Changeset 1765 in MondoRescue for branches/2.2.5/mindi-busybox/editors/vi.c


Ignore:
Timestamp:
Nov 4, 2007, 3:16:40 AM (17 years ago)
Author:
Bruno Cornec
Message:

Update to busybox 1.7.2

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/2.2.5/mindi-busybox/editors/vi.c

    r821 r1765  
    1414 *  add :help command
    1515 *  :map macros
    16  *  how about mode lines:   vi: set sw=8 ts=8:
    1716 *  if mark[] values were line numbers rather than pointers
    1817 *     it would be easier to change the mark when add/delete lines
     
    2322 */
    2423
    25 
    26 #include "busybox.h"
    27 #include <string.h>
    28 #include <strings.h>
    29 #include <unistd.h>
    30 #include <sys/ioctl.h>
    31 #include <time.h>
    32 #include <fcntl.h>
    33 #include <signal.h>
    34 #include <setjmp.h>
    35 #include <regex.h>
    36 #include <ctype.h>
    37 #include <errno.h>
    38 #define vi_Version BB_VER " " BB_BT
    39 
    40 #ifdef CONFIG_LOCALE_SUPPORT
     24#include "libbb.h"
     25
     26#define ENABLE_FEATURE_VI_CRASHME 0
     27
     28#if ENABLE_LOCALE_SUPPORT
    4129#define Isprint(c) isprint((c))
    4230#else
    43 #define Isprint(c) ( (c) >= ' ' && (c) != 127 && (c) != ((unsigned char)'\233') )
    44 #endif
    45 
    46 #define MAX_SCR_COLS        BUFSIZ
     31/* 0x9b is Meta-ESC */
     32#define Isprint(c) ((unsigned char)(c) >= ' ' && (c) != 0x7f && (unsigned char)(c) != 0x9b)
     33#endif
     34
     35enum {
     36    MAX_LINELEN = CONFIG_FEATURE_VI_MAX_LEN,
     37    MAX_SCR_COLS = CONFIG_FEATURE_VI_MAX_LEN,
     38};
    4739
    4840// Misc. non-Ascii keys that report an escape sequence
    49 #define VI_K_UP         128 // cursor key Up
    50 #define VI_K_DOWN       129 // cursor key Down
    51 #define VI_K_RIGHT      130 // Cursor Key Right
    52 #define VI_K_LEFT       131 // cursor key Left
    53 #define VI_K_HOME       132 // Cursor Key Home
    54 #define VI_K_END        133 // Cursor Key End
    55 #define VI_K_INSERT     134 // Cursor Key Insert
    56 #define VI_K_PAGEUP     135 // Cursor Key Page Up
    57 #define VI_K_PAGEDOWN       136 // Cursor Key Page Down
    58 #define VI_K_FUN1       137 // Function Key F1
    59 #define VI_K_FUN2       138 // Function Key F2
    60 #define VI_K_FUN3       139 // Function Key F3
    61 #define VI_K_FUN4       140 // Function Key F4
    62 #define VI_K_FUN5       141 // Function Key F5
    63 #define VI_K_FUN6       142 // Function Key F6
    64 #define VI_K_FUN7       143 // Function Key F7
    65 #define VI_K_FUN8       144 // Function Key F8
    66 #define VI_K_FUN9       145 // Function Key F9
    67 #define VI_K_FUN10      146 // Function Key F10
    68 #define VI_K_FUN11      147 // Function Key F11
    69 #define VI_K_FUN12      148 // Function Key F12
     41#define VI_K_UP         (char)128   // cursor key Up
     42#define VI_K_DOWN       (char)129   // cursor key Down
     43#define VI_K_RIGHT      (char)130   // Cursor Key Right
     44#define VI_K_LEFT       (char)131   // cursor key Left
     45#define VI_K_HOME       (char)132   // Cursor Key Home
     46#define VI_K_END        (char)133   // Cursor Key End
     47#define VI_K_INSERT     (char)134   // Cursor Key Insert
     48#define VI_K_PAGEUP     (char)135   // Cursor Key Page Up
     49#define VI_K_PAGEDOWN       (char)136   // Cursor Key Page Down
     50#define VI_K_FUN1       (char)137   // Function Key F1
     51#define VI_K_FUN2       (char)138   // Function Key F2
     52#define VI_K_FUN3       (char)139   // Function Key F3
     53#define VI_K_FUN4       (char)140   // Function Key F4
     54#define VI_K_FUN5       (char)141   // Function Key F5
     55#define VI_K_FUN6       (char)142   // Function Key F6
     56#define VI_K_FUN7       (char)143   // Function Key F7
     57#define VI_K_FUN8       (char)144   // Function Key F8
     58#define VI_K_FUN9       (char)145   // Function Key F9
     59#define VI_K_FUN10      (char)146   // Function Key F10
     60#define VI_K_FUN11      (char)147   // Function Key F11
     61#define VI_K_FUN12      (char)148   // Function Key F12
    7062
    7163/* vt102 typical ESC sequence */
    7264/* terminal standout start/normal ESC sequence */
    73 static const char SOs[] = "\033[7m";
    74 static const char SOn[] = "\033[0m";
     65static const char SOs[] ALIGN1 = "\033[7m";
     66static const char SOn[] ALIGN1 = "\033[0m";
    7567/* terminal bell sequence */
    76 static const char bell[] = "\007";
     68static const char bell[] ALIGN1 = "\007";
    7769/* Clear-end-of-line and Clear-end-of-screen ESC sequence */
    78 static const char Ceol[] = "\033[0K";
    79 static const char Ceos [] = "\033[0J";
     70static const char Ceol[] ALIGN1 = "\033[0K";
     71static const char Ceos[] ALIGN1 = "\033[0J";
    8072/* Cursor motion arbitrary destination ESC sequence */
    81 static const char CMrc[] = "\033[%d;%dH";
     73static const char CMrc[] ALIGN1 = "\033[%d;%dH";
    8274/* Cursor motion up and down ESC sequence */
    83 static const char CMup[] = "\033[A";
    84 static const char CMdown[] = "\n";
     75static const char CMup[] ALIGN1 = "\033[A";
     76static const char CMdown[] ALIGN1 = "\n";
    8577
    8678
     
    9789    S_OVER_WS = 3,      // used in skip_thing() for moving "dot"
    9890    S_END_PUNCT = 4,    // used in skip_thing() for moving "dot"
    99     S_END_ALNUM = 5     // used in skip_thing() for moving "dot"
     91    S_END_ALNUM = 5,    // used in skip_thing() for moving "dot"
    10092};
    10193
    102 typedef unsigned char Byte;
    103 
    104 static int vi_setops;
     94/* vi.c expects chars to be unsigned. */
     95/* busybox build system provides that, but it's better */
     96/* to audit and fix the source */
     97
     98static smallint vi_setops;
    10599#define VI_AUTOINDENT 1
    106100#define VI_SHOWMATCH  2
     
    114108
    115109
    116 static int editing;     // >0 while we are editing a file
    117 static int cmd_mode;        // 0=command  1=insert 2=replace
    118 static int file_modified;   // buffer contents changed
    119 static int last_file_modified = -1;
    120 static int fn_start;        // index of first cmd line file name
    121 static int save_argc;       // how many file names on cmd line
    122 static int cmdcnt;      // repetition count
    123 static fd_set rfds;     // use select() for small sleeps
    124 static struct timeval tv;   // use select() for small sleeps
    125 static int rows, columns;   // the terminal screen is this size
    126 static int crow, ccol, offset;  // cursor is on Crow x Ccol with Horz Ofset
    127 static Byte *status_buffer; // mesages to the user
     110static smallint editing;        // >0 while we are editing a file
     111                                // [code audit says "can be 0 or 1 only"]
     112static smallint cmd_mode;       // 0=command  1=insert 2=replace
     113static smallint file_modified;  // buffer contents changed
     114static smallint last_file_modified = -1;
     115static int fn_start;            // index of first cmd line file name
     116static int save_argc;           // how many file names on cmd line
     117static int cmdcnt;              // repetition count
     118static int rows, columns;       // the terminal screen is this size
     119static int crow, ccol, offset;  // cursor is on Crow x Ccol with Horz Ofset
     120static char *status_buffer;     // mesages to the user
    128121#define STATUS_BUFFER_LEN  200
    129122static int have_status_msg;     // is default edit status needed?
     123                                // [don't make smallint!]
    130124static int last_status_cksum;   // hash of current status line
    131 static Byte *cfn;       // previous, current, and next file name
    132 static Byte *text, *end, *textend;  // pointers to the user data in memory
    133 static Byte *screen;        // pointer to the virtual screen buffer
    134 static int screensize;      //            and its size
    135 static Byte *screenbegin;   // index into text[], of top line on the screen
    136 static Byte *dot;       // where all the action takes place
     125static char *current_filename;               // current file name
     126//static char *text, *end;        // pointers to the user data in memory
     127static char *screen;            // pointer to the virtual screen buffer
     128static int screensize;          //            and its size
     129static char *screenbegin;       // index into text[], of top line on the screen
     130//static char *dot;               // where all the action takes place
    137131static int tabstop;
    138 static struct termios term_orig, term_vi;   // remember what the cooked mode was
    139 static Byte erase_char;         // the users erase character
    140 static Byte last_input_char;    // last char read from user
    141 static Byte last_forward_char;  // last char searched for with 'f'
    142 
    143 #ifdef CONFIG_FEATURE_VI_OPTIMIZE_CURSOR
     132static char erase_char;         // the users erase character
     133static char last_input_char;    // last char read from user
     134static char last_forward_char;  // last char searched for with 'f'
     135
     136#if ENABLE_FEATURE_VI_READONLY
     137//static smallint vi_readonly, readonly;
     138static smallint readonly_mode = 0;
     139#define SET_READONLY_FILE(flags)        ((flags) |= 0x01)
     140#define SET_READONLY_MODE(flags)        ((flags) |= 0x02)
     141#define UNSET_READONLY_FILE(flags)      ((flags) &= 0xfe)
     142#else
     143#define readonly_mode 0
     144#define SET_READONLY_FILE(flags)
     145#define SET_READONLY_MODE(flags)
     146#define UNSET_READONLY_FILE(flags)
     147#endif
     148
     149#if ENABLE_FEATURE_VI_DOT_CMD
     150static smallint adding2q;       // are we currently adding user input to q
     151static char *last_modifying_cmd;    // last modifying cmd for "."
     152static char *ioq, *ioq_start;           // pointer to string for get_one_char to "read"
     153#endif
     154#if ENABLE_FEATURE_VI_OPTIMIZE_CURSOR
    144155static int last_row;        // where the cursor was last moved to
    145 #endif                          /* CONFIG_FEATURE_VI_OPTIMIZE_CURSOR */
    146 #ifdef CONFIG_FEATURE_VI_USE_SIGNALS
    147 static jmp_buf restart;     // catch_sig()
    148 #endif                          /* CONFIG_FEATURE_VI_USE_SIGNALS */
    149 #if defined(CONFIG_FEATURE_VI_USE_SIGNALS) || defined(CONFIG_FEATURE_VI_CRASHME)
     156#endif
     157#if ENABLE_FEATURE_VI_USE_SIGNALS || ENABLE_FEATURE_VI_CRASHME
    150158static int my_pid;
    151159#endif
    152 #ifdef CONFIG_FEATURE_VI_DOT_CMD
    153 static int adding2q;        // are we currently adding user input to q
    154 static Byte *last_modifying_cmd;    // last modifying cmd for "."
    155 static Byte *ioq, *ioq_start;   // pointer to string for get_one_char to "read"
    156 #endif                          /* CONFIG_FEATURE_VI_DOT_CMD */
    157 #if defined(CONFIG_FEATURE_VI_DOT_CMD) || defined(CONFIG_FEATURE_VI_YANKMARK)
    158 static Byte *modifying_cmds;    // cmds that modify text[]
    159 #endif                          /* CONFIG_FEATURE_VI_DOT_CMD || CONFIG_FEATURE_VI_YANKMARK */
    160 #ifdef CONFIG_FEATURE_VI_READONLY
    161 static int vi_readonly, readonly;
    162 #endif                          /* CONFIG_FEATURE_VI_READONLY */
    163 #ifdef CONFIG_FEATURE_VI_YANKMARK
    164 static Byte *reg[28];       // named register a-z, "D", and "U" 0-25,26,27
    165 static int YDreg, Ureg;     // default delete register and orig line for "U"
    166 static Byte *mark[28];      // user marks points somewhere in text[]-  a-z and previous context ''
    167 static Byte *context_start, *context_end;
    168 #endif                          /* CONFIG_FEATURE_VI_YANKMARK */
    169 #ifdef CONFIG_FEATURE_VI_SEARCH
    170 static Byte *last_search_pattern;   // last pattern from a '/' or '?' search
    171 #endif                          /* CONFIG_FEATURE_VI_SEARCH */
    172 
    173 
    174 static void edit_file(Byte *);  // edit one file
    175 static void do_cmd(Byte);   // execute a command
    176 static void sync_cursor(Byte *, int *, int *);  // synchronize the screen cursor to dot
    177 static Byte *begin_line(Byte *);    // return pointer to cur line B-o-l
    178 static Byte *end_line(Byte *);  // return pointer to cur line E-o-l
    179 static Byte *prev_line(Byte *); // return pointer to prev line B-o-l
    180 static Byte *next_line(Byte *); // return pointer to next line B-o-l
    181 static Byte *end_screen(void);  // get pointer to last char on screen
    182 static int count_lines(Byte *, Byte *); // count line from start to stop
    183 static Byte *find_line(int);    // find begining of line #li
    184 static Byte *move_to_col(Byte *, int);  // move "p" to column l
    185 static int isblnk(Byte);    // is the char a blank or tab
     160#if ENABLE_FEATURE_VI_DOT_CMD || ENABLE_FEATURE_VI_YANKMARK
     161static char *modifying_cmds;            // cmds that modify text[]
     162#endif
     163#if ENABLE_FEATURE_VI_SEARCH
     164static char *last_search_pattern;   // last pattern from a '/' or '?' search
     165#endif
     166
     167/* Moving biggest data to malloced space... */
     168struct globals {
     169    /* many references - keep near the top of globals */
     170    char *text, *end;       // pointers to the user data in memory
     171    int text_size;      // size of the allocated buffer
     172    char *dot;              // where all the action takes place
     173#if ENABLE_FEATURE_VI_YANKMARK
     174    char *reg[28];          // named register a-z, "D", and "U" 0-25,26,27
     175    int YDreg, Ureg;        // default delete register and orig line for "U"
     176    char *mark[28];         // user marks points somewhere in text[]-  a-z and previous context ''
     177    char *context_start, *context_end;
     178#endif
     179    /* a few references only */
     180#if ENABLE_FEATURE_VI_USE_SIGNALS
     181    jmp_buf restart;        // catch_sig()
     182#endif
     183    struct termios term_orig, term_vi;  // remember what the cooked mode was
     184#if ENABLE_FEATURE_VI_COLON
     185    char *initial_cmds[3];  // currently 2 entries, NULL terminated
     186#endif
     187};
     188#define G (*ptr_to_globals)
     189#define text           (G.text          )
     190#define text_size      (G.text_size     )
     191#define end            (G.end           )
     192#define dot            (G.dot           )
     193#define reg            (G.reg           )
     194#define YDreg          (G.YDreg         )
     195#define Ureg           (G.Ureg          )
     196#define mark           (G.mark          )
     197#define context_start  (G.context_start )
     198#define context_end    (G.context_end   )
     199#define restart        (G.restart       )
     200#define term_orig      (G.term_orig     )
     201#define term_vi        (G.term_vi       )
     202#define initial_cmds   (G.initial_cmds  )
     203
     204static int init_text_buffer(char *); // init from file or create new
     205static void edit_file(char *);  // edit one file
     206static void do_cmd(char);   // execute a command
     207static int next_tabstop(int);
     208static void sync_cursor(char *, int *, int *);  // synchronize the screen cursor to dot
     209static char *begin_line(char *);    // return pointer to cur line B-o-l
     210static char *end_line(char *);  // return pointer to cur line E-o-l
     211static char *prev_line(char *); // return pointer to prev line B-o-l
     212static char *next_line(char *); // return pointer to next line B-o-l
     213static char *end_screen(void);  // get pointer to last char on screen
     214static int count_lines(char *, char *); // count line from start to stop
     215static char *find_line(int);    // find begining of line #li
     216static char *move_to_col(char *, int);  // move "p" to column l
    186217static void dot_left(void); // move dot left- dont leave line
    187218static void dot_right(void);    // move dot right- dont leave line
     
    193224static void dot_skip_over_ws(void); // move dot pat WS
    194225static void dot_delete(void);   // delete the char at 'dot'
    195 static Byte *bound_dot(Byte *); // make sure  text[0] <= P < "end"
    196 static Byte *new_screen(int, int);  // malloc virtual screen memory
    197 static Byte *new_text(int); // malloc memory for text[] buffer
    198 static Byte *char_insert(Byte *, Byte); // insert the char c at 'p'
    199 static Byte *stupid_insert(Byte *, Byte);   // stupidly insert the char c at 'p'
    200 static Byte find_range(Byte **, Byte **, Byte); // return pointers for an object
    201 static int st_test(Byte *, int, int, Byte *);   // helper for skip_thing()
    202 static Byte *skip_thing(Byte *, int, int, int); // skip some object
    203 static Byte *find_pair(Byte *, Byte);   // find matching pair ()  []  {}
    204 static Byte *text_hole_delete(Byte *, Byte *);  // at "p", delete a 'size' byte hole
    205 static Byte *text_hole_make(Byte *, int);   // at "p", make a 'size' byte hole
    206 static Byte *yank_delete(Byte *, Byte *, int, int); // yank text[] into register then delete
     226static char *bound_dot(char *); // make sure  text[0] <= P < "end"
     227static char *new_screen(int, int);  // malloc virtual screen memory
     228static char *char_insert(char *, char); // insert the char c at 'p'
     229static char *stupid_insert(char *, char);   // stupidly insert the char c at 'p'
     230static char find_range(char **, char **, char); // return pointers for an object
     231static int st_test(char *, int, int, char *);   // helper for skip_thing()
     232static char *skip_thing(char *, int, int, int); // skip some object
     233static char *find_pair(char *, char);   // find matching pair ()  []  {}
     234static char *text_hole_delete(char *, char *);  // at "p", delete a 'size' byte hole
     235static char *text_hole_make(char *, int);   // at "p", make a 'size' byte hole
     236static char *yank_delete(char *, char *, int, int); // yank text[] into register then delete
    207237static void show_help(void);    // display some help info
    208238static void rawmode(void);  // set "raw" mode on tty
    209239static void cookmode(void); // return to "cooked" mode on tty
    210240static int mysleep(int);    // sleep for 'h' 1/100 seconds
    211 static Byte readit(void);   // read (maybe cursor) key from stdin
    212 static Byte get_one_char(void); // read 1 char from stdin
    213 static int file_size(const Byte *);   // what is the byte size of "fn"
    214 static int file_insert(Byte *, Byte *, int);
    215 static int file_write(Byte *, Byte *, Byte *);
     241static char readit(void);   // read (maybe cursor) key from stdin
     242static char get_one_char(void); // read 1 char from stdin
     243static int file_size(const char *);   // what is the byte size of "fn"
     244#if ENABLE_FEATURE_VI_READONLY
     245static int file_insert(const char *, char *, int);
     246#else
     247static int file_insert(const char *, char *);
     248#endif
     249static int file_write(char *, char *, char *);
    216250static void place_cursor(int, int, int);
    217251static void screen_erase(void);
     
    224258static void psb(const char *, ...);     // Print Status Buf
    225259static void psbs(const char *, ...);    // Print Status Buf in standout mode
    226 static void ni(Byte *);     // display messages
     260static void ni(const char *);       // display messages
    227261static int format_edit_status(void);    // format file status on status line
    228262static void redraw(int);    // force a full screen refresh
    229 static void format_line(Byte*, Byte*, int);
     263static void format_line(char*, char*, int);
    230264static void refresh(int);   // update the terminal from screen[]
    231265
     
    234268static void Hit_Return(void);
    235269
    236 #ifdef CONFIG_FEATURE_VI_SEARCH
    237 static Byte *char_search(Byte *, Byte *, int, int); // search for pattern starting at p
    238 static int mycmp(Byte *, Byte *, int);  // string cmp based in "ignorecase"
    239 #endif                          /* CONFIG_FEATURE_VI_SEARCH */
    240 #ifdef CONFIG_FEATURE_VI_COLON
    241 static Byte *get_one_address(Byte *, int *);    // get colon addr, if present
    242 static Byte *get_address(Byte *, int *, int *); // get two colon addrs, if present
    243 static void colon(Byte *);  // execute the "colon" mode cmds
    244 #endif                          /* CONFIG_FEATURE_VI_COLON */
    245 #ifdef CONFIG_FEATURE_VI_USE_SIGNALS
     270#if ENABLE_FEATURE_VI_SEARCH
     271static char *char_search(char *, const char *, int, int);   // search for pattern starting at p
     272static int mycmp(const char *, const char *, int);  // string cmp based in "ignorecase"
     273#endif
     274#if ENABLE_FEATURE_VI_COLON
     275static char *get_one_address(char *, int *);    // get colon addr, if present
     276static char *get_address(char *, int *, int *); // get two colon addrs, if present
     277static void colon(char *);  // execute the "colon" mode cmds
     278#endif
     279#if ENABLE_FEATURE_VI_USE_SIGNALS
    246280static void winch_sig(int); // catch window size changes
    247281static void suspend_sig(int);   // catch ctrl-Z
    248282static void catch_sig(int);     // catch ctrl-C and alarm time-outs
    249 #endif                          /* CONFIG_FEATURE_VI_USE_SIGNALS */
    250 #ifdef CONFIG_FEATURE_VI_DOT_CMD
    251 static void start_new_cmd_q(Byte);  // new queue for command
     283#endif
     284#if ENABLE_FEATURE_VI_DOT_CMD
     285static void start_new_cmd_q(char);  // new queue for command
    252286static void end_cmd_q(void);    // stop saving input chars
    253 #else                           /* CONFIG_FEATURE_VI_DOT_CMD */
    254 #define end_cmd_q()
    255 #endif                          /* CONFIG_FEATURE_VI_DOT_CMD */
    256 #ifdef CONFIG_FEATURE_VI_SETOPTS
    257 static void showmatching(Byte *);   // show the matching pair ()  []  {}
    258 #endif                          /* CONFIG_FEATURE_VI_SETOPTS */
    259 #if defined(CONFIG_FEATURE_VI_YANKMARK) || (defined(CONFIG_FEATURE_VI_COLON) && defined(CONFIG_FEATURE_VI_SEARCH)) || defined(CONFIG_FEATURE_VI_CRASHME)
    260 static Byte *string_insert(Byte *, Byte *); // insert the string at 'p'
    261 #endif                          /* CONFIG_FEATURE_VI_YANKMARK || CONFIG_FEATURE_VI_SEARCH || CONFIG_FEATURE_VI_CRASHME */
    262 #ifdef CONFIG_FEATURE_VI_YANKMARK
    263 static Byte *text_yank(Byte *, Byte *, int);    // save copy of "p" into a register
    264 static Byte what_reg(void);     // what is letter of current YDreg
    265 static void check_context(Byte);    // remember context for '' command
    266 #endif                          /* CONFIG_FEATURE_VI_YANKMARK */
    267 #ifdef CONFIG_FEATURE_VI_CRASHME
     287#else
     288#define end_cmd_q() ((void)0)
     289#endif
     290#if ENABLE_FEATURE_VI_SETOPTS
     291static void showmatching(char *);   // show the matching pair ()  []  {}
     292#endif
     293#if ENABLE_FEATURE_VI_YANKMARK || (ENABLE_FEATURE_VI_COLON && ENABLE_FEATURE_VI_SEARCH) || ENABLE_FEATURE_VI_CRASHME
     294static char *string_insert(char *, char *); // insert the string at 'p'
     295#endif
     296#if ENABLE_FEATURE_VI_YANKMARK
     297static char *text_yank(char *, char *, int);    // save copy of "p" into a register
     298static char what_reg(void);     // what is letter of current YDreg
     299static void check_context(char);    // remember context for '' command
     300#endif
     301#if ENABLE_FEATURE_VI_CRASHME
    268302static void crash_dummy();
    269303static void crash_test();
    270304static int crashme = 0;
    271 #endif                          /* CONFIG_FEATURE_VI_CRASHME */
     305#endif
    272306
    273307
     
    277311}
    278312
     313int vi_main(int argc, char **argv);
    279314int vi_main(int argc, char **argv)
    280315{
     
    282317    RESERVE_CONFIG_BUFFER(STATUS_BUFFER, STATUS_BUFFER_LEN);
    283318
    284 #ifdef CONFIG_FEATURE_VI_YANKMARK
    285     int i;
    286 #endif                          /* CONFIG_FEATURE_VI_YANKMARK */
    287 #if defined(CONFIG_FEATURE_VI_USE_SIGNALS) || defined(CONFIG_FEATURE_VI_CRASHME)
     319#if ENABLE_FEATURE_VI_USE_SIGNALS || ENABLE_FEATURE_VI_CRASHME
    288320    my_pid = getpid();
    289321#endif
    290 #ifdef CONFIG_FEATURE_VI_CRASHME
    291     (void) srand((long) my_pid);
    292 #endif                          /* CONFIG_FEATURE_VI_CRASHME */
    293 
    294     status_buffer = (Byte *)STATUS_BUFFER;
     322
     323    PTR_TO_GLOBALS = xzalloc(sizeof(G));
     324
     325#if ENABLE_FEATURE_VI_CRASHME
     326    srand((long) my_pid);
     327#endif
     328
     329    status_buffer = STATUS_BUFFER;
    295330    last_status_cksum = 0;
    296 
    297 #ifdef CONFIG_FEATURE_VI_READONLY
    298     vi_readonly = readonly = FALSE;
    299     if (strncmp(argv[0], "view", 4) == 0) {
    300         readonly = TRUE;
    301         vi_readonly = TRUE;
    302     }
    303 #endif                          /* CONFIG_FEATURE_VI_READONLY */
     331    text = NULL;
     332
     333#ifdef NO_SUCH_APPLET_YET
     334    /* If we aren't "vi", we are "view" */
     335    if (ENABLE_FEATURE_VI_READONLY && applet_name[2]) {
     336        SET_READONLY_MODE(readonly_mode);
     337    }
     338#endif
     339
    304340    vi_setops = VI_AUTOINDENT | VI_SHOWMATCH | VI_IGNORECASE | VI_ERR_METHOD;
    305 #ifdef CONFIG_FEATURE_VI_YANKMARK
    306     for (i = 0; i < 28; i++) {
    307         reg[i] = 0;
    308     }                   // init the yank regs
    309 #endif                          /* CONFIG_FEATURE_VI_YANKMARK */
    310 #if defined(CONFIG_FEATURE_VI_DOT_CMD) || defined(CONFIG_FEATURE_VI_YANKMARK)
    311     modifying_cmds = (Byte *) "aAcCdDiIJoOpPrRsxX<>~";  // cmds modifying text[]
    312 #endif                          /* CONFIG_FEATURE_VI_DOT_CMD */
    313 
    314     //  1-  process $HOME/.exrc file
     341#if ENABLE_FEATURE_VI_YANKMARK
     342    memset(reg, 0, sizeof(reg)); // init the yank regs
     343#endif
     344#if ENABLE_FEATURE_VI_DOT_CMD || ENABLE_FEATURE_VI_YANKMARK
     345    modifying_cmds = (char *) "aAcCdDiIJoOpPrRsxX<>~";  // cmds modifying text[]
     346#endif
     347
     348    //  1-  process $HOME/.exrc file (not inplemented yet)
    315349    //  2-  process EXINIT variable from environment
    316350    //  3-  process command line args
    317     while ((c = getopt(argc, argv, "hCR")) != -1) {
     351#if ENABLE_FEATURE_VI_COLON
     352    {
     353        char *p = getenv("EXINIT");
     354        if (p && *p)
     355            initial_cmds[0] = xstrdup(p);
     356    }
     357#endif
     358    while ((c = getopt(argc, argv, "hCR" USE_FEATURE_VI_COLON("c:"))) != -1) {
    318359        switch (c) {
    319 #ifdef CONFIG_FEATURE_VI_CRASHME
     360#if ENABLE_FEATURE_VI_CRASHME
    320361        case 'C':
    321362            crashme = 1;
    322363            break;
    323 #endif                          /* CONFIG_FEATURE_VI_CRASHME */
    324 #ifdef CONFIG_FEATURE_VI_READONLY
     364#endif
     365#if ENABLE_FEATURE_VI_READONLY
    325366        case 'R':       // Read-only flag
    326             readonly = TRUE;
    327             vi_readonly = TRUE;
     367            SET_READONLY_MODE(readonly_mode);
    328368            break;
    329 #endif                          /* CONFIG_FEATURE_VI_READONLY */
     369#endif
    330370            //case 'r': // recover flag-  ignore- we don't use tmp file
    331371            //case 'x': // encryption flag- ignore
    332372            //case 'c': // execute command first
     373#if ENABLE_FEATURE_VI_COLON
     374        case 'c':       // cmd line vi command
     375            if (*optarg)
     376                initial_cmds[initial_cmds[0] != 0] = xstrdup(optarg);
     377            break;
    333378            //case 'h': // help -- just use default
     379#endif
    334380        default:
    335381            show_help();
     
    345391    //----- This is the main file handling loop --------------
    346392    if (optind >= argc) {
    347         editing = 1;    // 0= exit,  1= one file,  2= multiple files
    348393        edit_file(0);
    349394    } else {
    350395        for (; optind < argc; optind++) {
    351             editing = 1;    // 0=exit, 1=one file, 2+ =many files
    352             free(cfn);
    353             cfn = (Byte *) bb_xstrdup(argv[optind]);
    354             edit_file(cfn);
     396            edit_file(argv[optind]);
    355397        }
    356398    }
    357399    //-----------------------------------------------------------
    358400
    359     return (0);
    360 }
    361 
    362 static void edit_file(Byte * fn)
    363 {
    364     Byte c;
    365     int cnt, size, ch;
    366 
    367 #ifdef CONFIG_FEATURE_VI_USE_SIGNALS
     401    return 0;
     402}
     403
     404/* read text from file or create an empty buf */
     405/* will also update current_filename */
     406static int init_text_buffer(char *fn)
     407{
     408    int rc;
     409    int size = file_size(fn);   // file size. -1 means does not exist.
     410
     411    /* allocate/reallocate text buffer */
     412    free(text);
     413    text_size = size * 2;
     414    if (text_size < 10240)
     415        text_size = 10240;  // have a minimum size for new files
     416    screenbegin = dot = end = text = xzalloc(text_size);
     417
     418    if (fn != current_filename) {
     419        free(current_filename);
     420        current_filename = xstrdup(fn);
     421    }
     422    if (size < 0) {
     423        // file dont exist. Start empty buf with dummy line
     424        char_insert(text, '\n');
     425        rc = 0;
     426    } else {
     427        rc = file_insert(fn, text
     428            USE_FEATURE_VI_READONLY(, 1));
     429    }
     430    file_modified = 0;
     431    last_file_modified = -1;
     432#if ENABLE_FEATURE_VI_YANKMARK
     433    /* init the marks. */
     434    memset(mark, 0, sizeof(mark));
     435#endif
     436    return rc;
     437}
     438
     439static void edit_file(char * fn)
     440{
     441    char c;
     442    int size;
     443
     444#if ENABLE_FEATURE_VI_USE_SIGNALS
    368445    int sig;
    369 #endif                          /* CONFIG_FEATURE_VI_USE_SIGNALS */
    370 #ifdef CONFIG_FEATURE_VI_YANKMARK
    371     static Byte *cur_line;
    372 #endif                          /* CONFIG_FEATURE_VI_YANKMARK */
    373 
     446#endif
     447#if ENABLE_FEATURE_VI_YANKMARK
     448    static char *cur_line;
     449#endif
     450
     451    editing = 1;    // 0= exit,  1= one file, 2= multiple files
    374452    rawmode();
    375453    rows = 24;
    376454    columns = 80;
    377     ch= -1;
     455    size = 0;
    378456    if (ENABLE_FEATURE_VI_WIN_RESIZE)
    379457        get_terminal_width_height(0, &columns, &rows);
    380458    new_screen(rows, columns);  // get memory for virtual screen
    381 
    382     cnt = file_size(fn);    // file size
    383     size = 2 * cnt;     // 200% of file size
    384     new_text(size);     // get a text[] buffer
    385     screenbegin = dot = end = text;
    386     if (fn != 0) {
    387         ch= file_insert(fn, text, cnt);
    388     }
    389     if (ch < 1) {
    390         (void) char_insert(text, '\n'); // start empty buf with dummy line
    391     }
    392     file_modified = 0;
    393     last_file_modified = -1;
    394 #ifdef CONFIG_FEATURE_VI_YANKMARK
     459    init_text_buffer(fn);
     460
     461#if ENABLE_FEATURE_VI_YANKMARK
    395462    YDreg = 26;         // default Yank/Delete reg
    396463    Ureg = 27;          // hold orig line for "U" cmd
    397     for (cnt = 0; cnt < 28; cnt++) {
    398         mark[cnt] = 0;
    399     }                   // init the marks
    400464    mark[26] = mark[27] = text; // init "previous context"
    401 #endif                          /* CONFIG_FEATURE_VI_YANKMARK */
     465#endif
    402466
    403467    last_forward_char = last_input_char = '\0';
     
    405469    ccol = 0;
    406470
    407 #ifdef CONFIG_FEATURE_VI_USE_SIGNALS
     471#if ENABLE_FEATURE_VI_USE_SIGNALS
    408472    catch_sig(0);
    409473    signal(SIGWINCH, winch_sig);
     
    413477        screenbegin = dot = text;
    414478    }
    415 #endif                          /* CONFIG_FEATURE_VI_USE_SIGNALS */
    416 
    417     editing = 1;
     479#endif
     480
    418481    cmd_mode = 0;       // 0=command  1=insert  2='R'eplace
    419482    cmdcnt = 0;
     
    421484    offset = 0;         // no horizontal offset
    422485    c = '\0';
    423 #ifdef CONFIG_FEATURE_VI_DOT_CMD
     486#if ENABLE_FEATURE_VI_DOT_CMD
    424487    free(last_modifying_cmd);
    425488    free(ioq_start);
    426     ioq = ioq_start = last_modifying_cmd = 0;
     489    ioq = ioq_start = last_modifying_cmd = NULL;
    427490    adding2q = 0;
    428 #endif                          /* CONFIG_FEATURE_VI_DOT_CMD */
     491#endif
    429492    redraw(FALSE);          // dont force every col re-draw
    430     show_status_line();
    431 
     493
     494#if ENABLE_FEATURE_VI_COLON
     495    {
     496        char *p, *q;
     497        int n = 0;
     498
     499        while ((p = initial_cmds[n])) {
     500            do {
     501                q = p;
     502                p = strchr(q,'\n');
     503                if (p)
     504                    while (*p == '\n')
     505                        *p++ = '\0';
     506                if (*q)
     507                    colon(q);
     508            } while (p);
     509            free(initial_cmds[n]);
     510            initial_cmds[n] = NULL;
     511            n++;
     512        }
     513    }
     514#endif
    432515    //------This is the main Vi cmd handling loop -----------------------
    433516    while (editing > 0) {
    434 #ifdef CONFIG_FEATURE_VI_CRASHME
     517#if ENABLE_FEATURE_VI_CRASHME
    435518        if (crashme > 0) {
    436519            if ((end - text) > 1) {
     
    438521            } else {
    439522                crashme = 0;
    440                 dot =
    441                     string_insert(text, (Byte *) "\n\n#####  Ran out of text to work on.  #####\n\n");  // insert the string
     523                dot = string_insert(text, "\n\n#####  Ran out of text to work on.  #####\n\n"); // insert the string
    442524                refresh(FALSE);
    443525            }
    444526        }
    445 #endif                          /* CONFIG_FEATURE_VI_CRASHME */
     527#endif
    446528        last_input_char = c = get_one_char();   // get a cmd from user
    447 #ifdef CONFIG_FEATURE_VI_YANKMARK
     529#if ENABLE_FEATURE_VI_YANKMARK
    448530        // save a copy of the current line- for the 'U" command
    449531        if (begin_line(dot) != cur_line) {
     
    451533            text_yank(begin_line(dot), end_line(dot), Ureg);
    452534        }
    453 #endif                          /* CONFIG_FEATURE_VI_YANKMARK */
    454 #ifdef CONFIG_FEATURE_VI_DOT_CMD
     535#endif
     536#if ENABLE_FEATURE_VI_DOT_CMD
    455537        // These are commands that change text[].
    456538        // Remember the input for the "." command
    457539        if (!adding2q && ioq_start == 0
    458             && strchr((char *) modifying_cmds, c) != NULL) {
     540         && strchr(modifying_cmds, c)
     541        ) {
    459542            start_new_cmd_q(c);
    460543        }
    461 #endif                          /* CONFIG_FEATURE_VI_DOT_CMD */
     544#endif
    462545        do_cmd(c);      // execute the user command
    463546        //
     
    470553            show_status_line();
    471554        }
    472 #ifdef CONFIG_FEATURE_VI_CRASHME
     555#if ENABLE_FEATURE_VI_CRASHME
    473556        if (crashme > 0)
    474557            crash_test();   // test editor variables
    475 #endif                          /* CONFIG_FEATURE_VI_CRASHME */
     558#endif
    476559    }
    477560    //-------------------------------------------------------------------
     
    483566
    484567//----- The Colon commands -------------------------------------
    485 #ifdef CONFIG_FEATURE_VI_COLON
    486 static Byte *get_one_address(Byte * p, int *addr)   // get colon addr, if present
     568#if ENABLE_FEATURE_VI_COLON
     569static char *get_one_address(char * p, int *addr)   // get colon addr, if present
    487570{
    488571    int st;
    489     Byte *q;
    490 
    491 #ifdef CONFIG_FEATURE_VI_YANKMARK
    492     Byte c;
    493 #endif                          /* CONFIG_FEATURE_VI_YANKMARK */
    494 #ifdef CONFIG_FEATURE_VI_SEARCH
    495     Byte *pat, buf[BUFSIZ];
    496 #endif                          /* CONFIG_FEATURE_VI_SEARCH */
     572    char *q;
     573
     574#if ENABLE_FEATURE_VI_YANKMARK
     575    char c;
     576#endif
     577#if ENABLE_FEATURE_VI_SEARCH
     578    char *pat, buf[MAX_LINELEN];
     579#endif
    497580
    498581    *addr = -1;         // assume no addr
     
    501584        q = begin_line(dot);
    502585        *addr = count_lines(text, q);
    503 #ifdef CONFIG_FEATURE_VI_YANKMARK
     586#if ENABLE_FEATURE_VI_YANKMARK
    504587    } else if (*p == '\'') {    // is this a mark addr
    505588        p++;
     
    509592            // we have a mark
    510593            c = c - 'a';
    511             q = mark[(int) c];
     594            q = mark[(unsigned char) c];
    512595            if (q != NULL) {    // is mark valid
    513596                *addr = count_lines(text, q);   // count lines
    514597            }
    515598        }
    516 #endif                          /* CONFIG_FEATURE_VI_YANKMARK */
    517 #ifdef CONFIG_FEATURE_VI_SEARCH
     599#endif
     600#if ENABLE_FEATURE_VI_SEARCH
    518601    } else if (*p == '/') { // a search pattern
    519602        q = buf;
     
    524607            *q = '\0';
    525608        }
    526         pat = (Byte *) bb_xstrdup((char *) buf);    // save copy of pattern
     609        pat = xstrdup(buf); // save copy of pattern
    527610        if (*p == '/')
    528611            p++;
     
    532615        }
    533616        free(pat);
    534 #endif                          /* CONFIG_FEATURE_VI_SEARCH */
     617#endif
    535618    } else if (*p == '$') { // the last line in file
    536619        p++;
     
    538621        *addr = count_lines(text, q);
    539622    } else if (isdigit(*p)) {   // specific line number
    540         sscanf((char *) p, "%d%n", addr, &st);
     623        sscanf(p, "%d%n", addr, &st);
    541624        p += st;
    542625    } else {            // I don't reconise this
     
    544627        *addr = -1;
    545628    }
    546     return (p);
    547 }
    548 
    549 static Byte *get_address(Byte *p, int *b, int *e)   // get two colon addrs, if present
     629    return p;
     630}
     631
     632static char *get_address(char *p, int *b, int *e)   // get two colon addrs, if present
    550633{
    551634    //----- get the address' i.e., 1,3   'a,'b  -----
    552635    // get FIRST addr, if present
    553     while (isblnk(*p))
     636    while (isblank(*p))
    554637        p++;                // skip over leading spaces
    555638    if (*p == '%') {            // alias for 1,$
     
    560643    }
    561644    p = get_one_address(p, b);
    562     while (isblnk(*p))
     645    while (isblank(*p))
    563646        p++;
    564647    if (*p == ',') {            // is there a address separator
    565648        p++;
    566         while (isblnk(*p))
     649        while (isblank(*p))
    567650            p++;
    568651        // get SECOND addr, if present
    569652        p = get_one_address(p, e);
    570653    }
    571 ga0:
    572     while (isblnk(*p))
     654 ga0:
     655    while (isblank(*p))
    573656        p++;                // skip over trailing spaces
    574     return (p);
    575 }
    576 
    577 #ifdef CONFIG_FEATURE_VI_SETOPTS
    578 static void setops(const Byte *args, const char *opname, int flg_no,
     657    return p;
     658}
     659
     660#if ENABLE_FEATURE_VI_SET && ENABLE_FEATURE_VI_SETOPTS
     661static void setops(const char *args, const char *opname, int flg_no,
    579662            const char *short_opname, int opt)
    580663{
    581     const char *a = (char *) args + flg_no;
     664    const char *a = args + flg_no;
    582665    int l = strlen(opname) - 1; /* opname have + ' ' */
    583666
    584     if (strncasecmp(a, opname, l) == 0 ||
    585             strncasecmp(a, short_opname, 2) == 0) {
    586         if(flg_no)
     667    if (strncasecmp(a, opname, l) == 0
     668     || strncasecmp(a, short_opname, 2) == 0
     669    ) {
     670        if (flg_no)
    587671            vi_setops &= ~opt;
    588          else
     672        else
    589673            vi_setops |= opt;
    590674    }
     
    592676#endif
    593677
    594 static void colon(Byte * buf)
    595 {
    596     Byte c, *orig_buf, *buf1, *q, *r;
    597     Byte *fn, cmd[BUFSIZ], args[BUFSIZ];
    598     int i, l, li, ch, st, b, e;
     678static void colon(char * buf)
     679{
     680    char c, *orig_buf, *buf1, *q, *r;
     681    char *fn, cmd[MAX_LINELEN], args[MAX_LINELEN];
     682    int i, l, li, ch, b, e;
    599683    int useforce = FALSE, forced = FALSE;
    600     struct stat st_buf;
    601684
    602685    // :3154    // if (-e line 3154) goto it  else stay put
     
    615698    //
    616699
    617     if (strlen((char *) buf) <= 0)
     700    if (!buf[0])
    618701        goto vc1;
    619702    if (*buf == ':')
    620703        buf++;          // move past the ':'
    621704
    622     li = st = ch = i = 0;
     705    li = ch = i = 0;
    623706    b = e = -1;
    624707    q = text;           // assume 1,$ for the range
    625708    r = end - 1;
    626709    li = count_lines(text, end - 1);
    627     fn = cfn;           // default to current file
    628     memset(cmd, '\0', BUFSIZ);  // clear cmd[]
    629     memset(args, '\0', BUFSIZ); // clear args[]
     710    fn = current_filename;          // default to current file
     711    memset(cmd, '\0', MAX_LINELEN); // clear cmd[]
     712    memset(args, '\0', MAX_LINELEN);    // clear args[]
    630713
    631714    // look for optional address(es)  :.  :1  :1,9   :'q,'a   :%
     
    643726    }
    644727    // get any ARGuments
    645     while (isblnk(*buf))
     728    while (isblank(*buf))
    646729        buf++;
    647     strcpy((char *) args, (char *) buf);
    648     buf1 = (Byte*)last_char_is((char *)cmd, '!');
     730    strcpy(args, buf);
     731    buf1 = last_char_is(cmd, '!');
    649732    if (buf1) {
    650733        useforce = TRUE;
     
    668751    }
    669752    // ------------ now look for the command ------------
    670     i = strlen((char *) cmd);
     753    i = strlen(cmd);
    671754    if (i == 0) {       // :123CR goto line #123
    672755        if (b >= 0) {
     
    674757            dot_skip_over_ws();
    675758        }
    676     } else if (strncmp((char *) cmd, "!", 1) == 0) {    // run a cmd
     759    }
     760#if ENABLE_FEATURE_ALLOW_EXEC
     761    else if (strncmp(cmd, "!", 1) == 0) {   // run a cmd
     762        int retcode;
    677763        // :!ls   run the <cmd>
    678         (void) alarm(0);        // wait for input- no alarms
     764        alarm(0);       // wait for input- no alarms
    679765        place_cursor(rows - 1, 0, FALSE);   // go to Status line
    680766        clear_to_eol();         // clear the line
    681767        cookmode();
    682         system((char*)(orig_buf+1));        // run the cmd
     768        retcode = system(orig_buf + 1); // run the cmd
     769        if (retcode)
     770            printf("\nshell returned %i\n\n", retcode);
    683771        rawmode();
    684772        Hit_Return();           // let user see results
    685         (void) alarm(3);        // done waiting for input
    686     } else if (strncmp((char *) cmd, "=", i) == 0) {    // where is the address
     773        alarm(3);       // done waiting for input
     774    }
     775#endif
     776    else if (strncmp(cmd, "=", i) == 0) {   // where is the address
    687777        if (b < 0) {    // no addr given- use defaults
    688778            b = e = count_lines(text, dot);
    689779        }
    690780        psb("%d", b);
    691     } else if (strncasecmp((char *) cmd, "delete", i) == 0) {   // delete lines
     781    } else if (strncasecmp(cmd, "delete", i) == 0) {    // delete lines
    692782        if (b < 0) {    // no addr given- use defaults
    693783            q = begin_line(dot);    // assume .,. for the range
     
    696786        dot = yank_delete(q, r, 1, YANKDEL);    // save, then delete lines
    697787        dot_skip_over_ws();
    698     } else if (strncasecmp((char *) cmd, "edit", i) == 0) { // Edit a file
    699         int sr;
    700         sr= 0;
     788    } else if (strncasecmp(cmd, "edit", i) == 0) {  // Edit a file
    701789        // don't edit, if the current file has been modified
    702790        if (file_modified && ! useforce) {
     
    704792            goto vc1;
    705793        }
    706         if (strlen((char*)args) > 0) {
     794        if (args[0]) {
    707795            // the user supplied a file name
    708             fn= args;
    709         } else if (cfn != 0 && strlen((char*)cfn) > 0) {
     796            fn = args;
     797        } else if (current_filename && current_filename[0]) {
    710798            // no user supplied name- use the current filename
    711             fn= cfn;
    712             goto vc5;
     799            // fn = current_filename;  was set by default
    713800        } else {
    714801            // no user file name, no current name- punt
     
    717804        }
    718805
    719         // see if file exists- if not, its just a new file request
    720         if ((sr=stat((char*)fn, &st_buf)) < 0) {
    721             // This is just a request for a new file creation.
    722             // The file_insert below will fail but we get
    723             // an empty buffer with a file name.  Then the "write"
    724             // command can do the create.
    725         } else {
    726             if ((st_buf.st_mode & (S_IFREG)) == 0) {
    727                 // This is not a regular file
    728                 psbs("\"%s\" is not a regular file", fn);
    729                 goto vc1;
    730             }
    731             if ((st_buf.st_mode & (S_IRUSR | S_IRGRP | S_IROTH)) == 0) {
    732                 // dont have any read permissions
    733                 psbs("\"%s\" is not readable", fn);
    734                 goto vc1;
    735             }
    736         }
    737 
    738         // There is a read-able regular file
    739         // make this the current file
    740         q = (Byte *) bb_xstrdup((char *) fn);   // save the cfn
    741         free(cfn);      // free the old name
    742         cfn = q;            // remember new cfn
    743 
    744       vc5:
    745         // delete all the contents of text[]
    746         new_text(2 * file_size(fn));
    747         screenbegin = dot = end = text;
    748 
    749         // insert new file
    750         ch = file_insert(fn, text, file_size(fn));
    751 
    752         if (ch < 1) {
    753             // start empty buf with dummy line
    754             (void) char_insert(text, '\n');
    755             ch= 1;
    756         }
    757         file_modified = 0;
    758         last_file_modified = -1;
    759 #ifdef CONFIG_FEATURE_VI_YANKMARK
     806        if (init_text_buffer(fn) < 0)
     807            goto vc1;
     808
     809#if ENABLE_FEATURE_VI_YANKMARK
    760810        if (Ureg >= 0 && Ureg < 28 && reg[Ureg] != 0) {
    761811            free(reg[Ureg]);    //   free orig line reg- for 'U'
     
    766816            reg[YDreg]= 0;
    767817        }
    768         for (li = 0; li < 28; li++) {
    769             mark[li] = 0;
    770         }               // init the marks
    771 #endif                          /* CONFIG_FEATURE_VI_YANKMARK */
     818#endif
    772819        // how many lines in text[]?
    773820        li = count_lines(text, end - 1);
    774821        psb("\"%s\"%s"
    775 #ifdef CONFIG_FEATURE_VI_READONLY
    776             "%s"
    777 #endif                          /* CONFIG_FEATURE_VI_READONLY */
    778             " %dL, %dC", cfn,
    779             (sr < 0 ? " [New file]" : ""),
    780 #ifdef CONFIG_FEATURE_VI_READONLY
    781             ((vi_readonly || readonly) ? " [Read only]" : ""),
    782 #endif                          /* CONFIG_FEATURE_VI_READONLY */
     822            USE_FEATURE_VI_READONLY("%s")
     823            " %dL, %dC", current_filename,
     824            (file_size(fn) < 0 ? " [New file]" : ""),
     825            USE_FEATURE_VI_READONLY(
     826                ((readonly_mode) ? " [Readonly]" : ""),
     827            )
    783828            li, ch);
    784     } else if (strncasecmp((char *) cmd, "file", i) == 0) { // what File is this
     829    } else if (strncasecmp(cmd, "file", i) == 0) {  // what File is this
    785830        if (b != -1 || e != -1) {
    786             ni((Byte *) "No address allowed on this command");
     831            ni("No address allowed on this command");
    787832            goto vc1;
    788833        }
    789         if (strlen((char *) args) > 0) {
     834        if (args[0]) {
    790835            // user wants a new filename
    791             free(cfn);
    792             cfn = (Byte *) bb_xstrdup((char *) args);
     836            free(current_filename);
     837            current_filename = xstrdup(args);
    793838        } else {
    794839            // user wants file status info
    795840            last_status_cksum = 0;  // force status update
    796841        }
    797     } else if (strncasecmp((char *) cmd, "features", i) == 0) { // what features are available
     842    } else if (strncasecmp(cmd, "features", i) == 0) {  // what features are available
    798843        // print out values of all features
    799844        place_cursor(rows - 1, 0, FALSE);   // go to Status line, bottom of screen
     
    803848        rawmode();
    804849        Hit_Return();
    805     } else if (strncasecmp((char *) cmd, "list", i) == 0) { // literal print line
     850    } else if (strncasecmp(cmd, "list", i) == 0) {  // literal print line
    806851        if (b < 0) {    // no addr given- use defaults
    807852            q = begin_line(dot);    // assume .,. for the range
     
    815860
    816861            c = *q;
    817             c_is_no_print = c > 127 && !Isprint(c);
     862            c_is_no_print = (c & 0x80) && !Isprint(c);
    818863            if (c_is_no_print) {
    819864                c = '.';
     
    824869            } else if (c < ' ' || c == 127) {
    825870                putchar('^');
    826                 if(c == 127)
     871                if (c == 127)
    827872                    c = '?';
    828                  else
    829                 c += '@';
     873                else
     874                    c += '@';
    830875            }
    831876            putchar(c);
     
    833878                standout_end();
    834879        }
    835 #ifdef CONFIG_FEATURE_VI_SET
    836       vc2:
    837 #endif                          /* CONFIG_FEATURE_VI_SET */
     880#if ENABLE_FEATURE_VI_SET
     881 vc2:
     882#endif
    838883        Hit_Return();
    839     } else if ((strncasecmp((char *) cmd, "quit", i) == 0) ||   // Quit
    840                (strncasecmp((char *) cmd, "next", i) == 0)) {   // edit next file
     884    } else if (strncasecmp(cmd, "quit", i) == 0 // Quit
     885            || strncasecmp(cmd, "next", i) == 0 // edit next file
     886    ) {
    841887        if (useforce) {
    842888            // force end of argv list
     
    863909        }
    864910        editing = 0;
    865     } else if (strncasecmp((char *) cmd, "read", i) == 0) { // read file into text[]
     911    } else if (strncasecmp(cmd, "read", i) == 0) {  // read file into text[]
    866912        fn = args;
    867         if (strlen((char *) fn) <= 0) {
     913        if (!fn[0]) {
    868914            psbs("No filename given");
    869915            goto vc1;
     
    875921        if (b != 0)
    876922            q = next_line(q);
    877 #ifdef CONFIG_FEATURE_VI_READONLY
    878         l= readonly;            // remember current files' status
    879 #endif
    880         ch = file_insert(fn, q, file_size(fn));
    881 #ifdef CONFIG_FEATURE_VI_READONLY
    882         readonly= l;
    883 #endif
     923        ch = file_insert(fn, q  USE_FEATURE_VI_READONLY(, 0));
    884924        if (ch < 0)
    885925            goto vc1;   // nothing was inserted
     
    887927        li = count_lines(q, q + ch - 1);
    888928        psb("\"%s\""
    889 #ifdef CONFIG_FEATURE_VI_READONLY
    890             "%s"
    891 #endif                          /* CONFIG_FEATURE_VI_READONLY */
     929            USE_FEATURE_VI_READONLY("%s")
    892930            " %dL, %dC", fn,
    893 #ifdef CONFIG_FEATURE_VI_READONLY
    894             ((vi_readonly || readonly) ? " [Read only]" : ""),
    895 #endif                          /* CONFIG_FEATURE_VI_READONLY */
     931            USE_FEATURE_VI_READONLY((readonly_mode ? " [Readonly]" : ""),)
    896932            li, ch);
    897933        if (ch > 0) {
     
    901937            file_modified++;
    902938        }
    903     } else if (strncasecmp((char *) cmd, "rewind", i) == 0) {   // rewind cmd line args
     939    } else if (strncasecmp(cmd, "rewind", i) == 0) {    // rewind cmd line args
    904940        if (file_modified && ! useforce) {
    905941            psbs("No write since last change (:rewind! overrides)");
     
    909945            editing = 0;
    910946        }
    911 #ifdef CONFIG_FEATURE_VI_SET
    912     } else if (strncasecmp((char *) cmd, "set", i) == 0) {  // set or clear features
     947#if ENABLE_FEATURE_VI_SET
     948    } else if (strncasecmp(cmd, "set", i) == 0) {   // set or clear features
     949#if ENABLE_FEATURE_VI_SETOPTS
     950        char *argp;
     951#endif
    913952        i = 0;          // offset into args
    914         if (strlen((char *) args) == 0) {
     953        // only blank is regarded as args delmiter. What about tab '\t' ?
     954        if (!args[0] || strcasecmp(args, "all") == 0) {
    915955            // print out values of all options
    916956            place_cursor(rows - 1, 0, FALSE);   // go to Status line, bottom of screen
    917957            clear_to_eol(); // clear the line
    918958            printf("----------------------------------------\r\n");
    919 #ifdef CONFIG_FEATURE_VI_SETOPTS
     959#if ENABLE_FEATURE_VI_SETOPTS
    920960            if (!autoindent)
    921961                printf("no");
     
    931971            printf("showmatch ");
    932972            printf("tabstop=%d ", tabstop);
    933 #endif                          /* CONFIG_FEATURE_VI_SETOPTS */
     973#endif
    934974            printf("\r\n");
    935975            goto vc2;
    936976        }
    937         if (strncasecmp((char *) args, "no", 2) == 0)
    938             i = 2;      // ":set noautoindent"
    939 #ifdef CONFIG_FEATURE_VI_SETOPTS
    940         setops(args, "autoindent ", i, "ai", VI_AUTOINDENT);
    941         setops(args, "flash ", i, "fl", VI_ERR_METHOD);
    942         setops(args, "ignorecase ", i, "ic", VI_IGNORECASE);
    943         setops(args, "showmatch ", i, "ic", VI_SHOWMATCH);
    944         if (strncasecmp((char *) args + i, "tabstop=%d ", 7) == 0) {
    945             sscanf(strchr((char *) args + i, '='), "=%d", &ch);
    946             if (ch > 0 && ch < columns - 1)
    947                 tabstop = ch;
    948         }
    949 #endif                          /* CONFIG_FEATURE_VI_SETOPTS */
    950 #endif                          /* CONFIG_FEATURE_VI_SET */
    951 #ifdef CONFIG_FEATURE_VI_SEARCH
    952     } else if (strncasecmp((char *) cmd, "s", 1) == 0) {    // substitute a pattern with a replacement pattern
    953         Byte *ls, *F, *R;
     977#if ENABLE_FEATURE_VI_SETOPTS
     978        argp = args;
     979        while (*argp) {
     980            if (strncasecmp(argp, "no", 2) == 0)
     981                i = 2;      // ":set noautoindent"
     982            setops(argp, "autoindent ", i, "ai", VI_AUTOINDENT);
     983            setops(argp, "flash ", i, "fl", VI_ERR_METHOD);
     984            setops(argp, "ignorecase ", i, "ic", VI_IGNORECASE);
     985            setops(argp, "showmatch ", i, "ic", VI_SHOWMATCH);
     986            /* tabstopXXXX */
     987            if (strncasecmp(argp + i, "tabstop=%d ", 7) == 0) {
     988                sscanf(strchr(argp + i, '='), "tabstop=%d" + 7, &ch);
     989                if (ch > 0 && ch < columns - 1)
     990                    tabstop = ch;
     991            }
     992            while (*argp && *argp != ' ')
     993                argp++; // skip to arg delimiter (i.e. blank)
     994            while (*argp && *argp == ' ')
     995                argp++; // skip all delimiting blanks
     996        }
     997#endif /* FEATURE_VI_SETOPTS */
     998#endif /* FEATURE_VI_SET */
     999#if ENABLE_FEATURE_VI_SEARCH
     1000    } else if (strncasecmp(cmd, "s", 1) == 0) { // substitute a pattern with a replacement pattern
     1001        char *ls, *F, *R;
    9541002        int gflag;
    9551003
     
    9601008        c = orig_buf[1];    // what is the delimiter
    9611009        F = orig_buf + 2;   // start of "find"
    962         R = (Byte *) strchr((char *) F, c); // middle delimiter
     1010        R = strchr(F, c);   // middle delimiter
    9631011        if (!R) goto colon_s_fail;
    9641012        *R++ = '\0';    // terminate "find"
    965         buf1 = (Byte *) strchr((char *) R, c);
     1013        buf1 = strchr(R, c);
    9661014        if (!buf1) goto colon_s_fail;
    9671015        *buf1++ = '\0'; // terminate "replace"
     
    9791027        for (i = b; i <= e; i++) {  // so, :20,23 s \0 find \0 replace \0
    9801028            ls = q;     // orig line start
    981           vc4:
     1029 vc4:
    9821030            buf1 = char_search(q, F, FORWARD, LIMITED); // search cur line only for "find"
    983             if (buf1 != NULL) {
    984                 // we found the "find" pattern- delete it
    985                 (void) text_hole_delete(buf1, buf1 + strlen((char *) F) - 1);
     1031            if (buf1) {
     1032                // we found the "find" pattern - delete it
     1033                text_hole_delete(buf1, buf1 + strlen(F) - 1);
    9861034                // inset the "replace" patern
    987                 (void) string_insert(buf1, R);  // insert the string
     1035                string_insert(buf1, R); // insert the string
    9881036                // check for "global"  :s/foo/bar/g
    9891037                if (gflag == 1) {
    990                     if ((buf1 + strlen((char *) R)) < end_line(ls)) {
    991                         q = buf1 + strlen((char *) R);
     1038                    if ((buf1 + strlen(R)) < end_line(ls)) {
     1039                        q = buf1 + strlen(R);
    9921040                        goto vc4;   // don't let q move past cur line
    9931041                    }
     
    9961044            q = next_line(ls);
    9971045        }
    998 #endif                          /* CONFIG_FEATURE_VI_SEARCH */
    999     } else if (strncasecmp((char *) cmd, "version", i) == 0) {  // show software version
    1000         psb("%s", vi_Version);
    1001     } else if (strncasecmp((char *) cmd, "write", i) == 0       // write text to file
    1002             || strncasecmp((char *) cmd, "wq", i) == 0
    1003             || strncasecmp((char *) cmd, "wn", i) == 0
    1004             || strncasecmp((char *) cmd, "x", i) == 0) {
     1046#endif /* FEATURE_VI_SEARCH */
     1047    } else if (strncasecmp(cmd, "version", i) == 0) {  // show software version
     1048        psb("%s", BB_VER " " BB_BT);
     1049    } else if (strncasecmp(cmd, "write", i) == 0  // write text to file
     1050            || strncasecmp(cmd, "wq", i) == 0
     1051            || strncasecmp(cmd, "wn", i) == 0
     1052            || strncasecmp(cmd, "x", i) == 0
     1053    ) {
    10051054        // is there a file name to write to?
    1006         if (strlen((char *) args) > 0) {
     1055        if (args[0]) {
    10071056            fn = args;
    10081057        }
    1009 #ifdef CONFIG_FEATURE_VI_READONLY
    1010         if ((vi_readonly || readonly) && ! useforce) {
     1058#if ENABLE_FEATURE_VI_READONLY
     1059        if (readonly_mode && !useforce) {
    10111060            psbs("\"%s\" File is read only", fn);
    10121061            goto vc3;
    10131062        }
    1014 #endif                          /* CONFIG_FEATURE_VI_READONLY */
     1063#endif
    10151064        // how many lines in text[]?
    10161065        li = count_lines(q, r);
     
    10321081        if (l < 0) {
    10331082            if (l == -1)
    1034                 psbs("Write error: %s", strerror(errno));
     1083                psbs("\"%s\" %s", fn, strerror(errno));
    10351084        } else {
    10361085            psb("\"%s\" %dL, %dC", fn, li, l);
     
    10451094            }
    10461095        }
    1047 #ifdef CONFIG_FEATURE_VI_READONLY
    1048       vc3:;
    1049 #endif                          /* CONFIG_FEATURE_VI_READONLY */
    1050 #ifdef CONFIG_FEATURE_VI_YANKMARK
    1051     } else if (strncasecmp((char *) cmd, "yank", i) == 0) { // yank lines
     1096#if ENABLE_FEATURE_VI_READONLY
     1097 vc3:;
     1098#endif
     1099#if ENABLE_FEATURE_VI_YANKMARK
     1100    } else if (strncasecmp(cmd, "yank", i) == 0) {  // yank lines
    10521101        if (b < 0) {    // no addr given- use defaults
    10531102            q = begin_line(dot);    // assume .,. for the range
     
    10571106        li = count_lines(q, r);
    10581107        psb("Yank %d lines (%d chars) into [%c]",
    1059             li, strlen((char *) reg[YDreg]), what_reg());
    1060 #endif                          /* CONFIG_FEATURE_VI_YANKMARK */
     1108                li, strlen(reg[YDreg]), what_reg());
     1109#endif
    10611110    } else {
    10621111        // cmd unknown
    1063         ni((Byte *) cmd);
    1064     }
    1065   vc1:
     1112        ni(cmd);
     1113    }
     1114 vc1:
    10661115    dot = bound_dot(dot);   // make sure "dot" is valid
    10671116    return;
    1068 #ifdef CONFIG_FEATURE_VI_SEARCH
    1069 colon_s_fail:
     1117#if ENABLE_FEATURE_VI_SEARCH
     1118 colon_s_fail:
    10701119    psb(":s expression missing delimiters");
    10711120#endif
    10721121}
    10731122
    1074 #endif                          /* CONFIG_FEATURE_VI_COLON */
     1123#endif /* FEATURE_VI_COLON */
    10751124
    10761125static void Hit_Return(void)
     
    10861135}
    10871136
     1137static int next_tabstop(int col)
     1138{
     1139    return col + ((tabstop - 1) - (col % tabstop));
     1140}
     1141
    10881142//----- Synchronize the cursor to Dot --------------------------
    1089 static void sync_cursor(Byte * d, int *row, int *col)
    1090 {
    1091     Byte *beg_cur;              // begin and end of "d" line
    1092     Byte *beg_scr, *end_scr;    // begin and end of screen
    1093     Byte *tp;
     1143static void sync_cursor(char * d, int *row, int *col)
     1144{
     1145    char *beg_cur;  // begin and end of "d" line
     1146    char *end_scr;  // begin and end of screen
     1147    char *tp;
    10941148    int cnt, ro, co;
    10951149
    10961150    beg_cur = begin_line(d);    // first char of cur line
    10971151
    1098     beg_scr = end_scr = screenbegin;    // first char of screen
    10991152    end_scr = end_screen(); // last char of screen
    11001153
     
    11031156        // how many lines do we have to move
    11041157        cnt = count_lines(beg_cur, screenbegin);
    1105       sc1:
     1158 sc1:
    11061159        screenbegin = beg_cur;
    11071160        if (cnt > (rows - 1) / 2) {
     
    11391192            break;
    11401193        if (*tp == '\t') {
    1141             //         7       - (co %    8  )
    1142             co += ((tabstop - 1) - (co % tabstop));
     1194            if (d == tp && cmd_mode) { /* handle tabs like real vi */
     1195                break;
     1196            } else {
     1197                co = next_tabstop(co);
     1198            }
    11431199        } else if (*tp < ' ' || *tp == 127) {
    11441200            co++;       // display as ^X, use 2 columns
     
    11771233
    11781234//----- Text Movement Routines ---------------------------------
    1179 static Byte *begin_line(Byte * p) // return pointer to first char cur line
     1235static char *begin_line(char * p) // return pointer to first char cur line
    11801236{
    11811237    while (p > text && p[-1] != '\n')
    11821238        p--;            // go to cur line B-o-l
    1183     return (p);
    1184 }
    1185 
    1186 static Byte *end_line(Byte * p) // return pointer to NL of cur line line
     1239    return p;
     1240}
     1241
     1242static char *end_line(char * p) // return pointer to NL of cur line line
    11871243{
    11881244    while (p < end - 1 && *p != '\n')
    11891245        p++;            // go to cur line E-o-l
    1190     return (p);
    1191 }
    1192 
    1193 static inline Byte *dollar_line(Byte * p) // return pointer to just before NL line
     1246    return p;
     1247}
     1248
     1249static inline char *dollar_line(char * p) // return pointer to just before NL line
    11941250{
    11951251    while (p < end - 1 && *p != '\n')
     
    11981254    if (*p == '\n' && (p - begin_line(p)) > 0)
    11991255        p--;
    1200     return (p);
    1201 }
    1202 
    1203 static Byte *prev_line(Byte * p) // return pointer first char prev line
     1256    return p;
     1257}
     1258
     1259static char *prev_line(char * p) // return pointer first char prev line
    12041260{
    12051261    p = begin_line(p);  // goto begining of cur line
     
    12071263        p--;            // step to prev line
    12081264    p = begin_line(p);  // goto begining of prev line
    1209     return (p);
    1210 }
    1211 
    1212 static Byte *next_line(Byte * p) // return pointer first char next line
     1265    return p;
     1266}
     1267
     1268static char *next_line(char * p) // return pointer first char next line
    12131269{
    12141270    p = end_line(p);
    12151271    if (*p == '\n' && p < end - 1)
    12161272        p++;            // step to next line
    1217     return (p);
     1273    return p;
    12181274}
    12191275
    12201276//----- Text Information Routines ------------------------------
    1221 static Byte *end_screen(void)
    1222 {
    1223     Byte *q;
     1277static char *end_screen(void)
     1278{
     1279    char *q;
    12241280    int cnt;
    12251281
     
    12291285        q = next_line(q);
    12301286    q = end_line(q);
    1231     return (q);
    1232 }
    1233 
    1234 static int count_lines(Byte * start, Byte * stop) // count line from start to stop
    1235 {
    1236     Byte *q;
     1287    return q;
     1288}
     1289
     1290static int count_lines(char * start, char * stop) // count line from start to stop
     1291{
     1292    char *q;
    12371293    int cnt;
    12381294
     
    12481304            cnt++;
    12491305    }
    1250     return (cnt);
    1251 }
    1252 
    1253 static Byte *find_line(int li)  // find begining of line #li
    1254 {
    1255     Byte *q;
     1306    return cnt;
     1307}
     1308
     1309static char *find_line(int li)  // find begining of line #li
     1310{
     1311    char *q;
    12561312
    12571313    for (q = text; li > 1; li--) {
    12581314        q = next_line(q);
    12591315    }
    1260     return (q);
     1316    return q;
    12611317}
    12621318
     
    12841340}
    12851341
    1286 static Byte *move_to_col(Byte * p, int l)
     1342static char *move_to_col(char * p, int l)
    12871343{
    12881344    int co;
     
    12941350            break;
    12951351        if (*p == '\t') {
    1296             //         7       - (co %    8  )
    1297             co += ((tabstop - 1) - (co % tabstop));
     1352            co = next_tabstop(co);
    12981353        } else if (*p < ' ' || *p == 127) {
    12991354            co++;       // display as ^X, use 2 columns
    13001355        }
    13011356    } while (++co <= l && p++ < end);
    1302     return (p);
     1357    return p;
    13031358}
    13041359
     
    13151370static void dot_scroll(int cnt, int dir)
    13161371{
    1317     Byte *q;
     1372    char *q;
    13181373
    13191374    for (; cnt > 0; cnt--) {
     
    13461401static void dot_delete(void)    // delete the char at 'dot'
    13471402{
    1348     (void) text_hole_delete(dot, dot);
    1349 }
    1350 
    1351 static Byte *bound_dot(Byte * p) // make sure  text[0] <= P < "end"
     1403    text_hole_delete(dot, dot);
     1404}
     1405
     1406static char *bound_dot(char * p) // make sure  text[0] <= P < "end"
    13521407{
    13531408    if (p >= end && end > text) {
     
    13591414        indicate_error('2');
    13601415    }
    1361     return (p);
     1416    return p;
    13621417}
    13631418
     
    13751430 */
    13761431
    1377 static Byte *new_screen(int ro, int co)
     1432static char *new_screen(int ro, int co)
    13781433{
    13791434    int li;
     
    13811436    free(screen);
    13821437    screensize = ro * co + 8;
    1383     screen = (Byte *) xmalloc(screensize);
     1438    screen = xmalloc(screensize);
    13841439    // initialize the new screen. assume this will be a empty file.
    13851440    screen_erase();
     
    13881443        screen[(li * co) + 0] = '~';
    13891444    }
    1390     return (screen);
    1391 }
    1392 
    1393 static Byte *new_text(int size)
    1394 {
    1395     if (size < 10240)
    1396         size = 10240;   // have a minimum size for new files
    1397     free(text);
    1398     text = (Byte *) xmalloc(size + 8);
    1399     memset(text, '\0', size);   // clear new text[]
    1400     //text += 4;        // leave some room for "oops"
    1401     textend = text + size - 1;
    1402     //textend -= 4;     // leave some root for "oops"
    1403     return (text);
    1404 }
    1405 
    1406 #ifdef CONFIG_FEATURE_VI_SEARCH
    1407 static int mycmp(Byte * s1, Byte * s2, int len)
     1445    return screen;
     1446}
     1447
     1448#if ENABLE_FEATURE_VI_SEARCH
     1449static int mycmp(const char * s1, const char * s2, int len)
    14081450{
    14091451    int i;
    14101452
    1411     i = strncmp((char *) s1, (char *) s2, len);
    1412 #ifdef CONFIG_FEATURE_VI_SETOPTS
    1413     if (ignorecase) {
    1414         i = strncasecmp((char *) s1, (char *) s2, len);
    1415     }
    1416 #endif                          /* CONFIG_FEATURE_VI_SETOPTS */
    1417     return (i);
    1418 }
    1419 
    1420 static Byte *char_search(Byte * p, Byte * pat, int dir, int range)  // search for pattern starting at p
     1453    i = strncmp(s1, s2, len);
     1454    if (ENABLE_FEATURE_VI_SETOPTS && ignorecase) {
     1455        i = strncasecmp(s1, s2, len);
     1456    }
     1457    return i;
     1458}
     1459
     1460// search for pattern starting at p
     1461static char *char_search(char * p, const char * pat, int dir, int range)
    14211462{
    14221463#ifndef REGEX_SEARCH
    1423     Byte *start, *stop;
     1464    char *start, *stop;
    14241465    int len;
    14251466
    1426     len = strlen((char *) pat);
     1467    len = strlen(pat);
    14271468    if (dir == FORWARD) {
    14281469        stop = end - 1; // assume range is p - end-1
     
    14311472        for (start = p; start < stop; start++) {
    14321473            if (mycmp(start, pat, len) == 0) {
    1433                 return (start);
     1474                return start;
    14341475            }
    14351476        }
     
    14401481        for (start = p - len; start >= stop; start--) {
    14411482            if (mycmp(start, pat, len) == 0) {
    1442                 return (start);
     1483                return start;
    14431484            }
    14441485        }
    14451486    }
    14461487    // pattern not found
    1447     return (NULL);
    1448 #else                           /*REGEX_SEARCH */
     1488    return NULL;
     1489#else /* REGEX_SEARCH */
    14491490    char *q;
    14501491    struct re_pattern_buffer preg;
     
    14731514    range = q - p;
    14741515
    1475     q = (char *) re_compile_pattern(pat, strlen((char *) pat), &preg);
     1516    q = re_compile_pattern(pat, strlen(pat), &preg);
    14761517    if (q != 0) {
    14771518        // The pattern was not compiled
     
    15001541        i = 0;          // return NULL if pattern not found
    15011542    }
    1502   cs1:
     1543 cs1:
    15031544    if (dir == FORWARD) {
    15041545        p = p + i;
     
    15061547        p = p - i;
    15071548    }
    1508     return (p);
    1509 #endif                          /*REGEX_SEARCH */
    1510 }
    1511 #endif                          /* CONFIG_FEATURE_VI_SEARCH */
    1512 
    1513 static Byte *char_insert(Byte * p, Byte c) // insert the char c at 'p'
     1549    return p;
     1550#endif /* REGEX_SEARCH */
     1551}
     1552#endif /* FEATURE_VI_SEARCH */
     1553
     1554static char *char_insert(char * p, char c) // insert the char c at 'p'
    15141555{
    15151556    if (c == 22) {      // Is this an ctrl-V?
     
    15261567        end_cmd_q();    // stop adding to q
    15271568        last_status_cksum = 0;  // force status update
    1528         if ((p[-1] != '\n') && (dot>text)) {
     1569        if ((p[-1] != '\n') && (dot > text)) {
    15291570            p--;
    15301571        }
     
    15371578    } else {
    15381579        // insert a char into text[]
    1539         Byte *sp;       // "save p"
     1580        char *sp;       // "save p"
    15401581
    15411582        if (c == 13)
     
    15431584        sp = p;         // remember addr of insert
    15441585        p = stupid_insert(p, c);    // insert the char
    1545 #ifdef CONFIG_FEATURE_VI_SETOPTS
     1586#if ENABLE_FEATURE_VI_SETOPTS
    15461587        if (showmatch && strchr(")]}", *sp) != NULL) {
    15471588            showmatching(sp);
    15481589        }
    15491590        if (autoindent && c == '\n') {  // auto indent the new line
    1550             Byte *q;
     1591            char *q;
    15511592
    15521593            q = prev_line(p);   // use prev line as templet
    1553             for (; isblnk(*q); q++) {
     1594            for (; isblank(*q); q++) {
    15541595                p = stupid_insert(p, *q);   // insert the char
    15551596            }
    15561597        }
    1557 #endif                          /* CONFIG_FEATURE_VI_SETOPTS */
    1558     }
    1559     return (p);
    1560 }
    1561 
    1562 static Byte *stupid_insert(Byte * p, Byte c) // stupidly insert the char c at 'p'
     1598#endif
     1599    }
     1600    return p;
     1601}
     1602
     1603static char *stupid_insert(char * p, char c) // stupidly insert the char c at 'p'
    15631604{
    15641605    p = text_hole_make(p, 1);
     
    15681609        p++;
    15691610    }
    1570     return (p);
    1571 }
    1572 
    1573 static Byte find_range(Byte ** start, Byte ** stop, Byte c)
    1574 {
    1575     Byte *save_dot, *p, *q;
     1611    return p;
     1612}
     1613
     1614static char find_range(char ** start, char ** stop, char c)
     1615{
     1616    char *save_dot, *p, *q;
    15761617    int cnt;
    15771618
     
    16251666    }
    16261667    dot = save_dot;
    1627     return (c);
    1628 }
    1629 
    1630 static int st_test(Byte * p, int type, int dir, Byte * tested)
    1631 {
    1632     Byte c, c0, ci;
     1668    return c;
     1669}
     1670
     1671static int st_test(char * p, int type, int dir, char * tested)
     1672{
     1673    char c, c0, ci;
    16331674    int test, inc;
    16341675
     
    16591700    }
    16601701    *tested = c;
    1661     return (test);
    1662 }
    1663 
    1664 static Byte *skip_thing(Byte * p, int linecnt, int dir, int type)
    1665 {
    1666     Byte c;
     1702    return test;
     1703}
     1704
     1705static char *skip_thing(char * p, int linecnt, int dir, int type)
     1706{
     1707    char c;
    16671708
    16681709    while (st_test(p, type, dir, &c)) {
     
    16761717        p += dir;       // move to next char
    16771718    }
    1678     return (p);
     1719    return p;
    16791720}
    16801721
    16811722// find matching char of pair  ()  []  {}
    1682 static Byte *find_pair(Byte * p, Byte c)
    1683 {
    1684     Byte match, *q;
     1723static char *find_pair(char * p, char c)
     1724{
     1725    char match, *q;
    16851726    int dir, level;
    16861727
     
    17221763    if (level != 0)
    17231764        q = NULL;       // indicate no match
    1724     return (q);
    1725 }
    1726 
    1727 #ifdef CONFIG_FEATURE_VI_SETOPTS
     1765    return q;
     1766}
     1767
     1768#if ENABLE_FEATURE_VI_SETOPTS
    17281769// show the matching char of a pair,  ()  []  {}
    1729 static void showmatching(Byte * p)
    1730 {
    1731     Byte *q, *save_dot;
     1770static void showmatching(char * p)
     1771{
     1772    char *q, *save_dot;
    17321773
    17331774    // we found half of a pair
     
    17401781        dot = q;        // go to new loc
    17411782        refresh(FALSE); // let the user see it
    1742         (void) mysleep(40); // give user some time
     1783        mysleep(40);    // give user some time
    17431784        dot = save_dot; // go back to old loc
    17441785        refresh(FALSE);
    17451786    }
    17461787}
    1747 #endif                          /* CONFIG_FEATURE_VI_SETOPTS */
     1788#endif /* FEATURE_VI_SETOPTS */
    17481789
    17491790//  open a hole in text[]
    1750 static Byte *text_hole_make(Byte * p, int size) // at "p", make a 'size' byte hole
    1751 {
    1752     Byte *src, *dest;
     1791static char *text_hole_make(char * p, int size) // at "p", make a 'size' byte hole
     1792{
     1793    char *src, *dest;
    17531794    int cnt;
    17541795
     
    17581799    dest = p + size;
    17591800    cnt = end - src;    // the rest of buffer
    1760     if (memmove(dest, src, cnt) != dest) {
     1801    if ( ((end + size) >= (text + text_size)) // TODO: realloc here
     1802            || memmove(dest, src, cnt) != dest) {
    17611803        psbs("can't create room for new characters");
     1804        p = NULL;
     1805        goto thm0;
    17621806    }
    17631807    memset(p, ' ', size);   // clear new hole
    1764     end = end + size;   // adjust the new END
     1808    end += size;        // adjust the new END
    17651809    file_modified++;    // has the file been modified
    1766   thm0:
    1767     return (p);
     1810 thm0:
     1811    return p;
    17681812}
    17691813
    17701814//  close a hole in text[]
    1771 static Byte *text_hole_delete(Byte * p, Byte * q) // delete "p" thru "q", inclusive
    1772 {
    1773     Byte *src, *dest;
     1815static char *text_hole_delete(char * p, char * q) // delete "p" thru "q", inclusive
     1816{
     1817    char *src, *dest;
    17741818    int cnt, hole_size;
    17751819
     
    17931837        psbs("can't delete the character");
    17941838    }
    1795   thd_atend:
     1839 thd_atend:
    17961840    end = end - hole_size;  // adjust the new END
    17971841    if (dest >= end)
     
    18001844        dest = end = text;  // keep pointers valid
    18011845    file_modified++;    // has the file been modified
    1802   thd0:
    1803     return (dest);
     1846 thd0:
     1847    return dest;
    18041848}
    18051849
     
    18071851// if dist <= 0, do not include, or go past, a NewLine
    18081852//
    1809 static Byte *yank_delete(Byte * start, Byte * stop, int dist, int yf)
    1810 {
    1811     Byte *p;
     1853static char *yank_delete(char * start, char * stop, int dist, int yf)
     1854{
     1855    char *p;
    18121856
    18131857    // make sure start <= stop
     
    18191863    }
    18201864    if (dist <= 0) {
    1821         // we can not cross NL boundaries
     1865        // we cannot cross NL boundaries
    18221866        p = start;
    18231867        if (*p == '\n')
    1824             return (p);
     1868            return p;
    18251869        // dont go past a NewLine
    18261870        for (; p + 1 <= stop; p++) {
     
    18321876    }
    18331877    p = start;
    1834 #ifdef CONFIG_FEATURE_VI_YANKMARK
     1878#if ENABLE_FEATURE_VI_YANKMARK
    18351879    text_yank(start, stop, YDreg);
    1836 #endif                          /* CONFIG_FEATURE_VI_YANKMARK */
     1880#endif
    18371881    if (yf == YANKDEL) {
    18381882        p = text_hole_delete(start, stop);
    18391883    }                   // delete lines
    1840     return (p);
     1884    return p;
    18411885}
    18421886
     
    18441888{
    18451889    puts("These features are available:"
    1846 #ifdef CONFIG_FEATURE_VI_SEARCH
     1890#if ENABLE_FEATURE_VI_SEARCH
    18471891    "\n\tPattern searches with / and ?"
    1848 #endif                          /* CONFIG_FEATURE_VI_SEARCH */
    1849 #ifdef CONFIG_FEATURE_VI_DOT_CMD
     1892#endif
     1893#if ENABLE_FEATURE_VI_DOT_CMD
    18501894    "\n\tLast command repeat with \'.\'"
    1851 #endif                          /* CONFIG_FEATURE_VI_DOT_CMD */
    1852 #ifdef CONFIG_FEATURE_VI_YANKMARK
     1895#endif
     1896#if ENABLE_FEATURE_VI_YANKMARK
    18531897    "\n\tLine marking with  'x"
    18541898    "\n\tNamed buffers with  \"x"
    1855 #endif                          /* CONFIG_FEATURE_VI_YANKMARK */
    1856 #ifdef CONFIG_FEATURE_VI_READONLY
     1899#endif
     1900#if ENABLE_FEATURE_VI_READONLY
    18571901    "\n\tReadonly if vi is called as \"view\""
    18581902    "\n\tReadonly with -R command line arg"
    1859 #endif                          /* CONFIG_FEATURE_VI_READONLY */
    1860 #ifdef CONFIG_FEATURE_VI_SET
     1903#endif
     1904#if ENABLE_FEATURE_VI_SET
    18611905    "\n\tSome colon mode commands with \':\'"
    1862 #endif                          /* CONFIG_FEATURE_VI_SET */
    1863 #ifdef CONFIG_FEATURE_VI_SETOPTS
     1906#endif
     1907#if ENABLE_FEATURE_VI_SETOPTS
    18641908    "\n\tSettable options with \":set\""
    1865 #endif                          /* CONFIG_FEATURE_VI_SETOPTS */
    1866 #ifdef CONFIG_FEATURE_VI_USE_SIGNALS
     1909#endif
     1910#if ENABLE_FEATURE_VI_USE_SIGNALS
    18671911    "\n\tSignal catching- ^C"
    18681912    "\n\tJob suspend and resume with ^Z"
    1869 #endif                          /* CONFIG_FEATURE_VI_USE_SIGNALS */
    1870 #ifdef CONFIG_FEATURE_VI_WIN_RESIZE
     1913#endif
     1914#if ENABLE_FEATURE_VI_WIN_RESIZE
    18711915    "\n\tAdapt to window re-sizes"
    1872 #endif                          /* CONFIG_FEATURE_VI_WIN_RESIZE */
     1916#endif
    18731917    );
    18741918}
    18751919
    1876 static inline void print_literal(Byte * buf, Byte * s) // copy s to buf, convert unprintable
    1877 {
    1878     Byte c, b[2];
     1920static inline void print_literal(char * buf, const char * s) // copy s to buf, convert unprintable
     1921{
     1922    unsigned char c;
     1923    char b[2];
    18791924
    18801925    b[1] = '\0';
    1881     strcpy((char *) buf, "");   // init buf
    1882     if (strlen((char *) s) <= 0)
    1883         s = (Byte *) "(NULL)";
    1884     for (; *s > '\0'; s++) {
     1926    buf[0] = '\0';
     1927    if (!s[0])
     1928        s = "(NULL)";
     1929    for (; *s; s++) {
    18851930        int c_is_no_print;
    18861931
    18871932        c = *s;
    1888         c_is_no_print = c > 127 && !Isprint(c);
     1933        c_is_no_print = (c & 0x80) && !Isprint(c);
    18891934        if (c_is_no_print) {
    1890             strcat((char *) buf, SOn);
     1935            strcat(buf, SOn);
    18911936            c = '.';
    18921937        }
    18931938        if (c < ' ' || c == 127) {
    1894             strcat((char *) buf, "^");
    1895             if(c == 127)
     1939            strcat(buf, "^");
     1940            if (c == 127)
    18961941                c = '?';
    1897              else
    1898             c += '@';
     1942            else
     1943                c += '@';
    18991944        }
    19001945        b[0] = c;
    1901         strcat((char *) buf, (char *) b);
     1946        strcat(buf, b);
    19021947        if (c_is_no_print)
    1903             strcat((char *) buf, SOs);
    1904         if (*s == '\n') {
    1905             strcat((char *) buf, "$");
    1906         }
    1907     }
    1908 }
    1909 
    1910 #ifdef CONFIG_FEATURE_VI_DOT_CMD
    1911 static void start_new_cmd_q(Byte c)
     1948            strcat(buf, SOs);
     1949        if (*s == '\n')
     1950            strcat(buf, "$");
     1951    }
     1952}
     1953
     1954#if ENABLE_FEATURE_VI_DOT_CMD
     1955static void start_new_cmd_q(char c)
    19121956{
    19131957    // release old cmd
    19141958    free(last_modifying_cmd);
    19151959    // get buffer for new cmd
    1916     last_modifying_cmd = (Byte *) xmalloc(BUFSIZ);
    1917     memset(last_modifying_cmd, '\0', BUFSIZ);   // clear new cmd queue
     1960    last_modifying_cmd = xzalloc(MAX_LINELEN);
    19181961    // if there is a current cmd count put it in the buffer first
    19191962    if (cmdcnt > 0)
    1920         sprintf((char *) last_modifying_cmd, "%d%c", cmdcnt, c);
     1963        sprintf(last_modifying_cmd, "%d%c", cmdcnt, c);
    19211964    else // just save char c onto queue
    19221965        last_modifying_cmd[0] = c;
     
    19261969static void end_cmd_q(void)
    19271970{
    1928 #ifdef CONFIG_FEATURE_VI_YANKMARK
     1971#if ENABLE_FEATURE_VI_YANKMARK
    19291972    YDreg = 26;         // go back to default Yank/Delete reg
    1930 #endif                          /* CONFIG_FEATURE_VI_YANKMARK */
     1973#endif
    19311974    adding2q = 0;
    1932     return;
    1933 }
    1934 #endif                          /* CONFIG_FEATURE_VI_DOT_CMD */
    1935 
    1936 #if defined(CONFIG_FEATURE_VI_YANKMARK) || (defined(CONFIG_FEATURE_VI_COLON) && defined(CONFIG_FEATURE_VI_SEARCH)) || defined(CONFIG_FEATURE_VI_CRASHME)
    1937 static Byte *string_insert(Byte * p, Byte * s) // insert the string at 'p'
     1975}
     1976#endif /* FEATURE_VI_DOT_CMD */
     1977
     1978#if ENABLE_FEATURE_VI_YANKMARK \
     1979 || (ENABLE_FEATURE_VI_COLON && ENABLE_FEATURE_VI_SEARCH) \
     1980 || ENABLE_FEATURE_VI_CRASHME
     1981static char *string_insert(char * p, char * s) // insert the string at 'p'
    19381982{
    19391983    int cnt, i;
    19401984
    1941     i = strlen((char *) s);
    1942     p = text_hole_make(p, i);
    1943     strncpy((char *) p, (char *) s, i);
    1944     for (cnt = 0; *s != '\0'; s++) {
    1945         if (*s == '\n')
    1946             cnt++;
    1947     }
    1948 #ifdef CONFIG_FEATURE_VI_YANKMARK
    1949     psb("Put %d lines (%d chars) from [%c]", cnt, i, what_reg());
    1950 #endif                          /* CONFIG_FEATURE_VI_YANKMARK */
    1951     return (p);
    1952 }
    1953 #endif                          /* CONFIG_FEATURE_VI_YANKMARK || CONFIG_FEATURE_VI_COLON || CONFIG_FEATURE_VI_CRASHME */
    1954 
    1955 #ifdef CONFIG_FEATURE_VI_YANKMARK
    1956 static Byte *text_yank(Byte * p, Byte * q, int dest)    // copy text into a register
    1957 {
    1958     Byte *t;
     1985    i = strlen(s);
     1986    if (text_hole_make(p, i)) {
     1987        strncpy(p, s, i);
     1988        for (cnt = 0; *s != '\0'; s++) {
     1989            if (*s == '\n')
     1990                cnt++;
     1991        }
     1992#if ENABLE_FEATURE_VI_YANKMARK
     1993        psb("Put %d lines (%d chars) from [%c]", cnt, i, what_reg());
     1994#endif
     1995    }
     1996    return p;
     1997}
     1998#endif
     1999
     2000#if ENABLE_FEATURE_VI_YANKMARK
     2001static char *text_yank(char * p, char * q, int dest)    // copy text into a register
     2002{
     2003    char *t;
    19592004    int cnt;
    19602005
     
    19672012    t = reg[dest];
    19682013    free(t);        //  if already a yank register, free it
    1969     t = (Byte *) xmalloc(cnt + 1);  // get a new register
     2014    t = xmalloc(cnt + 1);   // get a new register
    19702015    memset(t, '\0', cnt + 1);   // clear new text[]
    1971     strncpy((char *) t, (char *) p, cnt);   // copy text[] into bufer
     2016    strncpy(t, p, cnt); // copy text[] into bufer
    19722017    reg[dest] = t;
    1973     return (p);
    1974 }
    1975 
    1976 static Byte what_reg(void)
    1977 {
    1978     Byte c;
    1979     int i;
    1980 
    1981     i = 0;
     2018    return p;
     2019}
     2020
     2021static char what_reg(void)
     2022{
     2023    char c;
     2024
    19822025    c = 'D';            // default to D-reg
    19832026    if (0 <= YDreg && YDreg <= 25)
    1984         c = 'a' + (Byte) YDreg;
     2027        c = 'a' + (char) YDreg;
    19852028    if (YDreg == 26)
    19862029        c = 'D';
    19872030    if (YDreg == 27)
    19882031        c = 'U';
    1989     return (c);
    1990 }
    1991 
    1992 static void check_context(Byte cmd)
     2032    return c;
     2033}
     2034
     2035static void check_context(char cmd)
    19932036{
    19942037    // A context is defined to be "modifying text"
     
    19962039
    19972040    if (dot < context_start || dot > context_end) {
    1998         if (strchr((char *) modifying_cmds, cmd) != NULL) {
     2041        if (strchr(modifying_cmds, cmd) != NULL) {
    19992042            // we are trying to modify text[]- make this the current context
    20002043            mark[27] = mark[26];    // move cur to prev
     
    20052048        }
    20062049    }
    2007     return;
    2008 }
    2009 
    2010 static inline Byte *swap_context(Byte * p) // goto new context for '' command make this the current context
    2011 {
    2012     Byte *tmp;
     2050}
     2051
     2052static inline char *swap_context(char * p) // goto new context for '' command make this the current context
     2053{
     2054    char *tmp;
    20132055
    20142056    // the current context is in mark[26]
     
    20232065        context_end = next_line(next_line(next_line(p)));
    20242066    }
    2025     return (p);
    2026 }
    2027 #endif                          /* CONFIG_FEATURE_VI_YANKMARK */
    2028 
    2029 static int isblnk(Byte c) // is the char a blank or tab
    2030 {
    2031     return (c == ' ' || c == '\t');
    2032 }
     2067    return p;
     2068}
     2069#endif /* FEATURE_VI_YANKMARK */
    20332070
    20342071//----- Set terminal attributes --------------------------------
     
    20532090
    20542091//----- Come here when we get a window resize signal ---------
    2055 #ifdef CONFIG_FEATURE_VI_USE_SIGNALS
     2092#if ENABLE_FEATURE_VI_USE_SIGNALS
    20562093static void winch_sig(int sig ATTRIBUTE_UNUSED)
    20572094{
    20582095    signal(SIGWINCH, winch_sig);
    20592096    if (ENABLE_FEATURE_VI_WIN_RESIZE)
    2060        get_terminal_width_height(0, &columns, &rows);
     2097        get_terminal_width_height(0, &columns, &rows);
    20612098    new_screen(rows, columns);  // get memory for virtual screen
    20622099    redraw(TRUE);       // re-draw the screen
     
    20912128{
    20922129    signal(SIGINT, catch_sig);
    2093     if(sig)
     2130    if (sig)
    20942131        longjmp(restart, sig);
    20952132}
    2096 #endif                          /* CONFIG_FEATURE_VI_USE_SIGNALS */
     2133#endif /* FEATURE_VI_USE_SIGNALS */
    20972134
    20982135static int mysleep(int hund)    // sleep for 'h' 1/100 seconds
    20992136{
     2137    fd_set rfds;
     2138    struct timeval tv;
     2139
    21002140    // Don't hang- Wait 5/100 seconds-  1 Sec= 1000000
    21012141    fflush(stdout);
     
    21052145    tv.tv_usec = hund * 10000;
    21062146    select(1, &rfds, NULL, NULL, &tv);
    2107     return (FD_ISSET(0, &rfds));
     2147    return FD_ISSET(0, &rfds);
    21082148}
    21092149
     
    21132153
    21142154//----- IO Routines --------------------------------------------
    2115 static Byte readit(void)    // read (maybe cursor) key from stdin
    2116 {
    2117     Byte c;
     2155static char readit(void)    // read (maybe cursor) key from stdin
     2156{
     2157    char c;
    21182158    int n;
    21192159    struct esc_cmds {
    21202160        const char *seq;
    2121         Byte val;
     2161        char val;
    21222162    };
    21232163
    21242164    static const struct esc_cmds esccmds[] = {
    2125         {"OA", (Byte) VI_K_UP},       // cursor key Up
    2126         {"OB", (Byte) VI_K_DOWN},     // cursor key Down
    2127         {"OC", (Byte) VI_K_RIGHT},    // Cursor Key Right
    2128         {"OD", (Byte) VI_K_LEFT},     // cursor key Left
    2129         {"OH", (Byte) VI_K_HOME},     // Cursor Key Home
    2130         {"OF", (Byte) VI_K_END},      // Cursor Key End
    2131         {"[A", (Byte) VI_K_UP},       // cursor key Up
    2132         {"[B", (Byte) VI_K_DOWN},     // cursor key Down
    2133         {"[C", (Byte) VI_K_RIGHT},    // Cursor Key Right
    2134         {"[D", (Byte) VI_K_LEFT},     // cursor key Left
    2135         {"[H", (Byte) VI_K_HOME},     // Cursor Key Home
    2136         {"[F", (Byte) VI_K_END},      // Cursor Key End
    2137         {"[1~", (Byte) VI_K_HOME},     // Cursor Key Home
    2138         {"[2~", (Byte) VI_K_INSERT},  // Cursor Key Insert
    2139         {"[4~", (Byte) VI_K_END},      // Cursor Key End
    2140         {"[5~", (Byte) VI_K_PAGEUP},  // Cursor Key Page Up
    2141         {"[6~", (Byte) VI_K_PAGEDOWN},        // Cursor Key Page Down
    2142         {"OP", (Byte) VI_K_FUN1},     // Function Key F1
    2143         {"OQ", (Byte) VI_K_FUN2},     // Function Key F2
    2144         {"OR", (Byte) VI_K_FUN3},     // Function Key F3
    2145         {"OS", (Byte) VI_K_FUN4},     // Function Key F4
    2146         {"[15~", (Byte) VI_K_FUN5},   // Function Key F5
    2147         {"[17~", (Byte) VI_K_FUN6},   // Function Key F6
    2148         {"[18~", (Byte) VI_K_FUN7},   // Function Key F7
    2149         {"[19~", (Byte) VI_K_FUN8},   // Function Key F8
    2150         {"[20~", (Byte) VI_K_FUN9},   // Function Key F9
    2151         {"[21~", (Byte) VI_K_FUN10},  // Function Key F10
    2152         {"[23~", (Byte) VI_K_FUN11},  // Function Key F11
    2153         {"[24~", (Byte) VI_K_FUN12},  // Function Key F12
    2154         {"[11~", (Byte) VI_K_FUN1},   // Function Key F1
    2155         {"[12~", (Byte) VI_K_FUN2},   // Function Key F2
    2156         {"[13~", (Byte) VI_K_FUN3},   // Function Key F3
    2157         {"[14~", (Byte) VI_K_FUN4},   // Function Key F4
     2165        {"OA", VI_K_UP},       // cursor key Up
     2166        {"OB", VI_K_DOWN},     // cursor key Down
     2167        {"OC", VI_K_RIGHT},    // Cursor Key Right
     2168        {"OD", VI_K_LEFT},     // cursor key Left
     2169        {"OH", VI_K_HOME},     // Cursor Key Home
     2170        {"OF", VI_K_END},      // Cursor Key End
     2171        {"[A", VI_K_UP},       // cursor key Up
     2172        {"[B", VI_K_DOWN},     // cursor key Down
     2173        {"[C", VI_K_RIGHT},    // Cursor Key Right
     2174        {"[D", VI_K_LEFT},     // cursor key Left
     2175        {"[H", VI_K_HOME},     // Cursor Key Home
     2176        {"[F", VI_K_END},      // Cursor Key End
     2177        {"[1~", VI_K_HOME},    // Cursor Key Home
     2178        {"[2~", VI_K_INSERT},  // Cursor Key Insert
     2179        {"[4~", VI_K_END},     // Cursor Key End
     2180        {"[5~", VI_K_PAGEUP},  // Cursor Key Page Up
     2181        {"[6~", VI_K_PAGEDOWN},// Cursor Key Page Down
     2182        {"OP", VI_K_FUN1},     // Function Key F1
     2183        {"OQ", VI_K_FUN2},     // Function Key F2
     2184        {"OR", VI_K_FUN3},     // Function Key F3
     2185        {"OS", VI_K_FUN4},     // Function Key F4
     2186        {"[15~", VI_K_FUN5},   // Function Key F5
     2187        {"[17~", VI_K_FUN6},   // Function Key F6
     2188        {"[18~", VI_K_FUN7},   // Function Key F7
     2189        {"[19~", VI_K_FUN8},   // Function Key F8
     2190        {"[20~", VI_K_FUN9},   // Function Key F9
     2191        {"[21~", VI_K_FUN10},  // Function Key F10
     2192        {"[23~", VI_K_FUN11},  // Function Key F11
     2193        {"[24~", VI_K_FUN12},  // Function Key F12
     2194        {"[11~", VI_K_FUN1},   // Function Key F1
     2195        {"[12~", VI_K_FUN2},   // Function Key F2
     2196        {"[13~", VI_K_FUN3},   // Function Key F3
     2197        {"[14~", VI_K_FUN4},   // Function Key F4
    21582198    };
    2159 
    2160 #define ESCCMDS_COUNT (sizeof(esccmds)/sizeof(struct esc_cmds))
    2161 
    2162     (void) alarm(0);    // turn alarm OFF while we wait for input
     2199    enum { ESCCMDS_COUNT = ARRAY_SIZE(esccmds) };
     2200
     2201    alarm(0);   // turn alarm OFF while we wait for input
    21632202    fflush(stdout);
    21642203    n = readed_for_parse;
    21652204    // get input from User- are there already input chars in Q?
    21662205    if (n <= 0) {
    2167       ri0:
     2206 ri0:
    21682207        // the Q is empty, wait for a typed char
    2169         n = read(0, readbuffer, BUFSIZ - 1);
     2208        n = read(0, readbuffer, MAX_LINELEN - 1);
    21702209        if (n < 0) {
    21712210            if (errno == EINTR)
    21722211                goto ri0;   // interrupted sys call
    2173             if (errno == EBADF)
    2174                 editing = 0;
    2175             if (errno == EFAULT)
    2176                 editing = 0;
    2177             if (errno == EINVAL)
    2178                 editing = 0;
    2179             if (errno == EIO)
     2212            if (errno == EBADF || errno == EFAULT || errno == EINVAL
     2213                    || errno == EIO)
    21802214                editing = 0;
    21812215            errno = 0;
    21822216        }
    2183         if(n <= 0)
     2217        if (n <= 0)
    21842218            return 0;       // error
    21852219        if (readbuffer[0] == 27) {
    2186     // This is an ESC char. Is this Esc sequence?
    2187     // Could be bare Esc key. See if there are any
    2188     // more chars to read after the ESC. This would
    2189     // be a Function or Cursor Key sequence.
    2190     FD_ZERO(&rfds);
    2191     FD_SET(0, &rfds);
    2192     tv.tv_sec = 0;
    2193     tv.tv_usec = 50000; // Wait 5/100 seconds- 1 Sec=1000000
    2194 
    2195     // keep reading while there are input chars and room in buffer
    2196             while (select(1, &rfds, NULL, NULL, &tv) > 0 && n <= (BUFSIZ - 5)) {
    2197         // read the rest of the ESC string
    2198                 int r = read(0, (void *) (readbuffer + n), BUFSIZ - n);
     2220            fd_set rfds;
     2221            struct timeval tv;
     2222
     2223            // This is an ESC char. Is this Esc sequence?
     2224            // Could be bare Esc key. See if there are any
     2225            // more chars to read after the ESC. This would
     2226            // be a Function or Cursor Key sequence.
     2227            FD_ZERO(&rfds);
     2228            FD_SET(0, &rfds);
     2229            tv.tv_sec = 0;
     2230            tv.tv_usec = 50000; // Wait 5/100 seconds- 1 Sec=1000000
     2231
     2232            // keep reading while there are input chars and room in buffer
     2233            while (select(1, &rfds, NULL, NULL, &tv) > 0 && n <= (MAX_LINELEN - 5)) {
     2234                // read the rest of the ESC string
     2235                int r = read(0, (void *) (readbuffer + n), MAX_LINELEN - n);
    21992236                if (r > 0) {
    22002237                    n += r;
     
    22052242    }
    22062243    c = readbuffer[0];
    2207     if(c == 27 && n > 1) {
    2208     // Maybe cursor or function key?
     2244    if (c == 27 && n > 1) {
     2245        // Maybe cursor or function key?
    22092246        const struct esc_cmds *eindex;
    22102247
     
    22122249            int cnt = strlen(eindex->seq);
    22132250
    2214             if(n <= cnt)
     2251            if (n <= cnt)
    22152252                continue;
    2216             if(strncmp(eindex->seq, (char *) readbuffer + 1, cnt))
     2253            if (strncmp(eindex->seq, readbuffer + 1, cnt))
    22172254                continue;
    22182255            // is a Cursor key- put derived value back into Q
     
    22222259            break;
    22232260        }
    2224         if(eindex == &esccmds[ESCCMDS_COUNT]) {
     2261        if (eindex == &esccmds[ESCCMDS_COUNT]) {
    22252262            /* defined ESC sequence not found, set only one ESC */
    22262263            n = 1;
     
    22312268    // remove key sequence from Q
    22322269    readed_for_parse -= n;
    2233     memmove(readbuffer, readbuffer + n, BUFSIZ - n);
    2234     (void) alarm(3);    // we are done waiting for input, turn alarm ON
    2235     return (c);
     2270    memmove(readbuffer, readbuffer + n, MAX_LINELEN - n);
     2271    alarm(3);   // we are done waiting for input, turn alarm ON
     2272    return c;
    22362273}
    22372274
    22382275//----- IO Routines --------------------------------------------
    2239 static Byte get_one_char(void)
    2240 {
    2241     static Byte c;
    2242 
    2243 #ifdef CONFIG_FEATURE_VI_DOT_CMD
     2276static char get_one_char(void)
     2277{
     2278    static char c;
     2279
     2280#if ENABLE_FEATURE_VI_DOT_CMD
    22442281    // ! adding2q  && ioq == 0  read()
    22452282    // ! adding2q  && ioq != 0  *ioq
     
    22652302        c = readit();   // get the users input
    22662303        if (last_modifying_cmd != 0) {
    2267             int len = strlen((char *) last_modifying_cmd);
    2268             if (len + 1 >= BUFSIZ) {
     2304            int len = strlen(last_modifying_cmd);
     2305            if (len >= MAX_LINELEN - 1) {
    22692306                psbs("last_modifying_cmd overrun");
    22702307            } else {
     
    22742311        }
    22752312    }
    2276 #else                           /* CONFIG_FEATURE_VI_DOT_CMD */
     2313#else
    22772314    c = readit();       // get the users input
    2278 #endif                          /* CONFIG_FEATURE_VI_DOT_CMD */
    2279     return (c);         // return the char, where ever it came from
    2280 }
    2281 
    2282 static Byte *get_input_line(Byte * prompt) // get input line- use "status line"
    2283 {
    2284     Byte buf[BUFSIZ];
    2285     Byte c;
     2315#endif /* FEATURE_VI_DOT_CMD */
     2316    return c;           // return the char, where ever it came from
     2317}
     2318
     2319static char *get_input_line(const char * prompt) // get input line- use "status line"
     2320{
     2321    static char *obufp;
     2322
     2323    char buf[MAX_LINELEN];
     2324    char c;
    22862325    int i;
    2287     static Byte *obufp = NULL;
    2288 
    2289     strcpy((char *) buf, (char *) prompt);
     2326
     2327    strcpy(buf, prompt);
    22902328    last_status_cksum = 0;  // force status update
    22912329    place_cursor(rows - 1, 0, FALSE);   // go to Status line, bottom of screen
    22922330    clear_to_eol();     // clear the line
    2293     write1((char *) prompt);      // write out the :, /, or ? prompt
    2294 
    2295     for (i = strlen((char *) buf); i < BUFSIZ;) {
     2331    write1(prompt);      // write out the :, /, or ? prompt
     2332
     2333    i = strlen(buf);
     2334    while (i < MAX_LINELEN) {
    22962335        c = get_one_char(); // read user input
    22972336        if (c == '\n' || c == '\r' || c == 27)
     
    23152354    refresh(FALSE);
    23162355    free(obufp);
    2317     obufp = (Byte *) bb_xstrdup((char *) buf);
    2318     return (obufp);
    2319 }
    2320 
    2321 static int file_size(const Byte * fn) // what is the byte size of "fn"
     2356    obufp = xstrdup(buf);
     2357    return obufp;
     2358}
     2359
     2360static int file_size(const char *fn) // what is the byte size of "fn"
    23222361{
    23232362    struct stat st_buf;
    2324     int cnt, sr;
    2325 
    2326     if (fn == 0 || strlen((char *)fn) <= 0)
    2327         return (-1);
     2363    int cnt;
     2364
    23282365    cnt = -1;
    2329     sr = stat((char *) fn, &st_buf);    // see if file exists
    2330     if (sr >= 0) {
     2366    if (fn && fn[0] && stat(fn, &st_buf) == 0)  // see if file exists
    23312367        cnt = (int) st_buf.st_size;
    2332     }
    2333     return (cnt);
    2334 }
    2335 
    2336 static int file_insert(Byte * fn, Byte * p, int size)
    2337 {
    2338     int fd, cnt;
    2339 
    2340     cnt = -1;
    2341 #ifdef CONFIG_FEATURE_VI_READONLY
    2342     readonly = FALSE;
    2343 #endif                          /* CONFIG_FEATURE_VI_READONLY */
    2344     if (fn == 0 || strlen((char*) fn) <= 0) {
    2345         psbs("No filename given");
     2368    return cnt;
     2369}
     2370
     2371static int file_insert(const char * fn, char *p
     2372        USE_FEATURE_VI_READONLY(, int update_ro_status))
     2373{
     2374    int cnt = -1;
     2375    int fd, size;
     2376    struct stat statbuf;
     2377
     2378    /* Validate file */
     2379    if (stat(fn, &statbuf) < 0) {
     2380        psbs("\"%s\" %s", fn, strerror(errno));
    23462381        goto fi0;
    23472382    }
    2348     if (size == 0) {
    2349         // OK- this is just a no-op
    2350         cnt = 0;
     2383    if ((statbuf.st_mode & S_IFREG) == 0) {
     2384        // This is not a regular file
     2385        psbs("\"%s\" Not a regular file", fn);
    23512386        goto fi0;
    23522387    }
    2353     if (size < 0) {
    2354         psbs("Trying to insert a negative number (%d) of characters", size);
     2388    /* // this check is done by open()
     2389    if ((statbuf.st_mode & (S_IRUSR | S_IRGRP | S_IROTH)) == 0) {
     2390        // dont have any read permissions
     2391        psbs("\"%s\" Not readable", fn);
    23552392        goto fi0;
    23562393    }
     2394    */
    23572395    if (p < text || p > end) {
    23582396        psbs("Trying to insert file outside of memory");
     
    23602398    }
    23612399
    2362     // see if we can open the file
    2363 #ifdef CONFIG_FEATURE_VI_READONLY
    2364     if (vi_readonly) goto fi1;      // do not try write-mode
    2365 #endif
    2366     fd = open((char *) fn, O_RDWR);         // assume read & write
     2400    // read file to buffer
     2401    fd = open(fn, O_RDONLY);
    23672402    if (fd < 0) {
    2368         // could not open for writing- maybe file is read only
    2369 #ifdef CONFIG_FEATURE_VI_READONLY
    2370   fi1:
    2371 #endif
    2372         fd = open((char *) fn, O_RDONLY);   // try read-only
    2373         if (fd < 0) {
    2374             psbs("\"%s\" %s", fn, "could not open file");
    2375             goto fi0;
    2376         }
    2377 #ifdef CONFIG_FEATURE_VI_READONLY
    2378         // got the file- read-only
    2379         readonly = TRUE;
    2380 #endif                          /* CONFIG_FEATURE_VI_READONLY */
    2381     }
     2403        psbs("\"%s\" %s", fn, strerror(errno));
     2404        goto fi0;
     2405    }
     2406    size = statbuf.st_size;
    23822407    p = text_hole_make(p, size);
     2408    if (p == NULL)
     2409        goto fi0;
    23832410    cnt = read(fd, p, size);
    2384     close(fd);
    23852411    if (cnt < 0) {
    2386         cnt = -1;
     2412        psbs("\"%s\" %s", fn, strerror(errno));
    23872413        p = text_hole_delete(p, p + size - 1);  // un-do buffer insert
    2388         psbs("could not read file \"%s\"", fn);
    23892414    } else if (cnt < size) {
    23902415        // There was a partial read, shrink unused space text[]
    23912416        p = text_hole_delete(p + cnt, p + (size - cnt) - 1);    // un-do buffer insert
    2392         psbs("could not read all of file \"%s\"", fn);
     2417        psbs("cannot read all of file \"%s\"", fn);
    23932418    }
    23942419    if (cnt >= size)
    23952420        file_modified++;
    2396   fi0:
    2397     return (cnt);
    2398 }
    2399 
    2400 static int file_write(Byte * fn, Byte * first, Byte * last)
     2421    close(fd);
     2422 fi0:
     2423#if ENABLE_FEATURE_VI_READONLY
     2424    if (update_ro_status
     2425     && ((access(fn, W_OK) < 0) ||
     2426        /* root will always have access()
     2427         * so we check fileperms too */
     2428        !(statbuf.st_mode & (S_IWUSR | S_IWGRP | S_IWOTH))
     2429        )
     2430    ) {
     2431        SET_READONLY_FILE(readonly_mode);
     2432    }
     2433#endif
     2434    return cnt;
     2435}
     2436
     2437
     2438static int file_write(char * fn, char * first, char * last)
    24012439{
    24022440    int fd, cnt, charcnt;
     
    24042442    if (fn == 0) {
    24052443        psbs("No current filename");
    2406         return (-2);
     2444        return -2;
    24072445    }
    24082446    charcnt = 0;
    24092447    // FIXIT- use the correct umask()
    2410     fd = open((char *) fn, (O_WRONLY | O_CREAT | O_TRUNC), 0664);
     2448    fd = open(fn, (O_WRONLY | O_CREAT | O_TRUNC), 0664);
    24112449    if (fd < 0)
    2412         return (-1);
     2450        return -1;
    24132451    cnt = last - first + 1;
    24142452    charcnt = write(fd, first, cnt);
    24152453    if (charcnt == cnt) {
    24162454        // good write
    2417         //file_modified= FALSE; // the file has not been modified
     2455        //file_modified = FALSE; // the file has not been modified
    24182456    } else {
    24192457        charcnt = 0;
    24202458    }
    24212459    close(fd);
    2422     return (charcnt);
     2460    return charcnt;
    24232461}
    24242462
     
    24382476static void place_cursor(int row, int col, int opti)
    24392477{
    2440     char cm1[BUFSIZ];
     2478    char cm1[MAX_LINELEN];
    24412479    char *cm;
    2442 #ifdef CONFIG_FEATURE_VI_OPTIMIZE_CURSOR
    2443     char cm2[BUFSIZ];
    2444     Byte *screenp;
    2445     // char cm3[BUFSIZ];
    2446     int Rrow= last_row;
    2447 #endif                          /* CONFIG_FEATURE_VI_OPTIMIZE_CURSOR */
    2448 
    2449     memset(cm1, '\0', BUFSIZ - 1);  // clear the buffer
     2480#if ENABLE_FEATURE_VI_OPTIMIZE_CURSOR
     2481    char cm2[MAX_LINELEN];
     2482    char *screenp;
     2483    // char cm3[MAX_LINELEN];
     2484    int Rrow = last_row;
     2485#endif
     2486
     2487    memset(cm1, '\0', MAX_LINELEN);  // clear the buffer
    24502488
    24512489    if (row < 0) row = 0;
     
    24552493
    24562494    //----- 1.  Try the standard terminal ESC sequence
    2457     sprintf((char *) cm1, CMrc, row + 1, col + 1);
    2458     cm= cm1;
    2459     if (! opti) goto pc0;
    2460 
    2461 #ifdef CONFIG_FEATURE_VI_OPTIMIZE_CURSOR
     2495    sprintf(cm1, CMrc, row + 1, col + 1);
     2496    cm = cm1;
     2497    if (!opti)
     2498        goto pc0;
     2499
     2500#if ENABLE_FEATURE_VI_OPTIMIZE_CURSOR
    24622501    //----- find the minimum # of chars to move cursor -------------
    24632502    //----- 2.  Try moving with discreet chars (Newline, [back]space, ...)
    2464     memset(cm2, '\0', BUFSIZ - 1);  // clear the buffer
     2503    memset(cm2, '\0', MAX_LINELEN);  // clear the buffer
    24652504
    24662505    // move to the correct row
     
    24802519    // just send out orignal source char to get to correct place
    24812520    screenp = &screen[row * columns];   // start of screen line
    2482     strncat(cm2, (char* )screenp, col);
     2521    strncat(cm2, screenp, col);
    24832522
    24842523    //----- 3.  Try some other way of moving cursor
     
    24862525
    24872526    // pick the shortest cursor motion to send out
    2488     cm= cm1;
     2527    cm = cm1;
    24892528    if (strlen(cm2) < strlen(cm)) {
    2490         cm= cm2;
     2529        cm = cm2;
    24912530    }  /* else if (strlen(cm3) < strlen(cm)) {
    24922531        cm= cm3;
    24932532    } */
    2494 #endif                          /* CONFIG_FEATURE_VI_OPTIMIZE_CURSOR */
    2495   pc0:
     2533#endif /* FEATURE_VI_OPTIMIZE_CURSOR */
     2534 pc0:
    24962535    write1(cm);                 // move the cursor
    24972536}
     
    25262565    standout_start();   // send "start reverse video" sequence
    25272566    redraw(TRUE);
    2528     (void) mysleep(h);
     2567    mysleep(h);
    25292568    standout_end();     // send "end reverse video" sequence
    25302569    redraw(TRUE);
     
    25332572static void Indicate_Error(void)
    25342573{
    2535 #ifdef CONFIG_FEATURE_VI_CRASHME
     2574#if ENABLE_FEATURE_VI_CRASHME
    25362575    if (crashme > 0)
    25372576        return;         // generate a random command
    2538 #endif                          /* CONFIG_FEATURE_VI_CRASHME */
     2577#endif
    25392578    if (!err_method) {
    25402579        write1(bell);   // send out a bell character
     
    25512590}
    25522591
    2553 static int bufsum(unsigned char *buf, int count)
     2592static int bufsum(char *buf, int count)
    25542593{
    25552594    int sum = 0;
    2556     unsigned char *e = buf + count;
     2595    char *e = buf + count;
     2596
    25572597    while (buf < e)
    2558         sum += *buf++;
     2598        sum += (unsigned char) *buf++;
    25592599    return sum;
    25602600}
     
    25742614        last_status_cksum= cksum;       // remember if we have seen this line
    25752615        place_cursor(rows - 1, 0, FALSE);   // put cursor on status line
    2576         write1((char*)status_buffer);
     2616        write1(status_buffer);
    25772617        clear_to_eol();
    25782618        if (have_status_msg) {
    2579             if (((int)strlen((char*)status_buffer) - (have_status_msg - 1)) >
     2619            if (((int)strlen(status_buffer) - (have_status_msg - 1)) >
    25802620                    (columns - 1) ) {
    25812621                have_status_msg = 0;
     
    25962636
    25972637    va_start(args, format);
    2598     strcpy((char *) status_buffer, SOs);    // Terminal standout mode on
    2599     vsprintf((char *) status_buffer + strlen((char *) status_buffer), format, args);
    2600     strcat((char *) status_buffer, SOn);    // Terminal standout mode off
     2638    strcpy(status_buffer, SOs); // Terminal standout mode on
     2639    vsprintf(status_buffer + strlen(status_buffer), format, args);
     2640    strcat(status_buffer, SOn); // Terminal standout mode off
    26012641    va_end(args);
    26022642
    26032643    have_status_msg = 1 + sizeof(SOs) + sizeof(SOn) - 2;
    2604 
    2605     return;
    26062644}
    26072645
     
    26122650
    26132651    va_start(args, format);
    2614     vsprintf((char *) status_buffer, format, args);
     2652    vsprintf(status_buffer, format, args);
    26152653    va_end(args);
    26162654
    26172655    have_status_msg = 1;
    2618 
    2619     return;
    2620 }
    2621 
    2622 static void ni(Byte * s) // display messages
    2623 {
    2624     Byte buf[BUFSIZ];
     2656}
     2657
     2658static void ni(const char * s) // display messages
     2659{
     2660    char buf[MAX_LINELEN];
    26252661
    26262662    print_literal(buf, s);
     
    26302666static int format_edit_status(void) // show file status on status line
    26312667{
     2668    static int tot;
     2669    static const char cmd_mode_indicator[] ALIGN1 = "-IR-";
    26322670    int cur, percent, ret, trunc_at;
    2633     static int tot;
    26342671
    26352672    // file_modified is now a counter rather than a flag.  this
     
    26632700        columns : STATUS_BUFFER_LEN-1;
    26642701
    2665     ret = snprintf((char *) status_buffer, trunc_at+1,
    2666 #ifdef CONFIG_FEATURE_VI_READONLY
     2702    ret = snprintf(status_buffer, trunc_at+1,
     2703#if ENABLE_FEATURE_VI_READONLY
    26672704        "%c %s%s%s %d/%d %d%%",
    26682705#else
    26692706        "%c %s%s %d/%d %d%%",
    26702707#endif
    2671         (cmd_mode ? (cmd_mode == 2 ? 'R':'I'):'-'),
    2672         (cfn != 0 ? (char *) cfn : "No file"),
    2673 #ifdef CONFIG_FEATURE_VI_READONLY
    2674         ((vi_readonly || readonly) ? " [Read-only]" : ""),
    2675 #endif
    2676         (file_modified ? " [modified]" : ""),
     2708        cmd_mode_indicator[cmd_mode & 3],
     2709        (current_filename != NULL ? current_filename : "No file"),
     2710#if ENABLE_FEATURE_VI_READONLY
     2711        (readonly_mode ? " [Readonly]" : ""),
     2712#endif
     2713        (file_modified ? " [Modified]" : ""),
    26772714        cur, tot, percent);
    26782715
     
    26952732
    26962733//----- Format a text[] line into a buffer ---------------------
    2697 static void format_line(Byte *dest, Byte *src, int li)
     2734static void format_line(char *dest, char *src, int li)
    26982735{
    26992736    int co;
    2700     Byte c;
    2701 
    2702     for (co= 0; co < MAX_SCR_COLS; co++) {
    2703         c= ' ';     // assume blank
     2737    char c;
     2738
     2739    for (co = 0; co < MAX_SCR_COLS; co++) {
     2740        c = ' ';        // assume blank
    27042741        if (li > 0 && co == 0) {
    27052742            c = '~';        // not first line, assume Tilde
     
    27112748        if (c == '\n')
    27122749            break;
    2713         if (c > 127 && !Isprint(c)) {
     2750        if ((c & 0x80) && !Isprint(c)) {
    27142751            c = '.';
    27152752        }
    2716         if (c < ' ' || c == 127) {
     2753        if ((unsigned char)(c) < ' ' || c == 0x7f) {
    27172754            if (c == '\t') {
    27182755                c = ' ';
     
    27232760            } else {
    27242761                dest[co++] = '^';
    2725                 if(c == 127)
     2762                if (c == 0x7f)
    27262763                    c = '?';
    2727                  else
     2764                else
    27282765                    c += '@';       // make it visible
    27292766            }
     
    27452782{
    27462783    static int old_offset;
     2784
    27472785    int li, changed;
    2748     Byte buf[MAX_SCR_COLS];
    2749     Byte *tp, *sp;      // pointer into text[] and screen[]
    2750 #ifdef CONFIG_FEATURE_VI_OPTIMIZE_CURSOR
    2751     int last_li= -2;                // last line that changed- for optimizing cursor movement
    2752 #endif                          /* CONFIG_FEATURE_VI_OPTIMIZE_CURSOR */
     2786    char buf[MAX_SCR_COLS];
     2787    char *tp, *sp;      // pointer into text[] and screen[]
     2788#if ENABLE_FEATURE_VI_OPTIMIZE_CURSOR
     2789    int last_li = -2; // last line that changed- for optimizing cursor movement
     2790#endif
    27532791
    27542792    if (ENABLE_FEATURE_VI_WIN_RESIZE)
     
    27662804
    27672805        // skip to the end of the current text[] line
    2768         while (tp < end && *tp++ != '\n') /*no-op*/ ;
     2806        while (tp < end && *tp++ != '\n') /*no-op*/;
    27692807
    27702808        // see if there are any changes between vitual screen and buf
     
    27792817        // compare newly formatted buffer with virtual screen
    27802818        // look forward for first difference between buf and screen
    2781         for ( ; cs <= ce; cs++) {
     2819        for (; cs <= ce; cs++) {
    27822820            if (buf[cs + offset] != sp[cs]) {
    27832821                changed = TRUE; // mark for redraw
     
    27972835        // if horz offset has changed, force a redraw
    27982836        if (offset != old_offset) {
    2799   re0:
     2837 re0:
    28002838            changed = TRUE;
    28012839        }
     
    28162854                place_cursor(li, cs, FALSE);
    28172855            } else {
    2818 #ifdef CONFIG_FEATURE_VI_OPTIMIZE_CURSOR
     2856#if ENABLE_FEATURE_VI_OPTIMIZE_CURSOR
    28192857                // if this just the next line
    28202858                //  try to optimize cursor movement
     
    28222860                place_cursor(li, cs, li == (last_li+1) ? TRUE : FALSE);
    28232861                last_li= li;
    2824 #else                           /* CONFIG_FEATURE_VI_OPTIMIZE_CURSOR */
     2862#else
    28252863                place_cursor(li, cs, FALSE);    // use standard ESC sequence
    2826 #endif                          /* CONFIG_FEATURE_VI_OPTIMIZE_CURSOR */
     2864#endif /* FEATURE_VI_OPTIMIZE_CURSOR */
    28272865            }
    28282866
    28292867            // write line out to terminal
    28302868            {
    2831                 int nic = ce-cs+1;
    2832                 char *out = (char*)sp+cs;
    2833 
    2834                 while(nic-- > 0) {
     2869                int nic = ce - cs + 1;
     2870                char *out = sp + cs;
     2871
     2872                while (nic-- > 0) {
    28352873                    putchar(*out);
    28362874                    out++;
    28372875                }
    28382876            }
    2839 #ifdef CONFIG_FEATURE_VI_OPTIMIZE_CURSOR
     2877#if ENABLE_FEATURE_VI_OPTIMIZE_CURSOR
    28402878            last_row = li;
    2841 #endif                          /* CONFIG_FEATURE_VI_OPTIMIZE_CURSOR */
    2842         }
    2843     }
    2844 
    2845 #ifdef CONFIG_FEATURE_VI_OPTIMIZE_CURSOR
     2879#endif
     2880        }
     2881    }
     2882
     2883#if ENABLE_FEATURE_VI_OPTIMIZE_CURSOR
    28462884    place_cursor(crow, ccol, (crow == last_row) ? TRUE : FALSE);
    28472885    last_row = crow;
    28482886#else
    28492887    place_cursor(crow, ccol, FALSE);
    2850 #endif                          /* CONFIG_FEATURE_VI_OPTIMIZE_CURSOR */
     2888#endif
    28512889
    28522890    if (offset != old_offset)
     
    28762914
    28772915//----- Execute a Vi Command -----------------------------------
    2878 static void do_cmd(Byte c)
    2879 {
    2880     Byte c1, *p, *q, *msg, buf[9], *save_dot;
     2916static void do_cmd(char c)
     2917{
     2918    const char *msg;
     2919    char c1, *p, *q, buf[9], *save_dot;
    28812920    int cnt, i, j, dir, yf;
    28822921
    28832922    c1 = c;             // quiet the compiler
    28842923    cnt = yf = dir = 0; // quiet the compiler
    2885     p = q = save_dot = msg = buf;   // quiet the compiler
     2924    msg = p = q = save_dot = buf;   // quiet the compiler
    28862925    memset(buf, '\0', 9);   // clear buf
    28872926
     
    29032942    if (cmd_mode == 2) {
    29042943        //  flip-flop Insert/Replace mode
    2905         if (c == VI_K_INSERT) goto dc_i;
     2944        if (c == VI_K_INSERT)
     2945            goto dc_i;
    29062946        // we are 'R'eplacing the current *dot with new char
    29072947        if (*dot == '\n') {
     
    29272967    }
    29282968
    2929 key_cmd_mode:
     2969 key_cmd_mode:
    29302970    switch (c) {
    29312971        //case 0x01:    // soh
     
    29372977        //case 0x11:    // dc1
    29382978        //case 0x13:    // dc3
    2939 #ifdef CONFIG_FEATURE_VI_CRASHME
     2979#if ENABLE_FEATURE_VI_CRASHME
    29402980    case 0x14:          // dc4  ctrl-T
    29412981        crashme = (crashme == 0) ? 1 : 0;
    29422982        break;
    2943 #endif                          /* CONFIG_FEATURE_VI_CRASHME */
     2983#endif
    29442984        //case 0x16:    // syn
    29452985        //case 0x17:    // etb
     
    29803020            buf[2] = '\0';
    29813021        }
    2982         ni((Byte *) buf);
     3022        ni(buf);
    29833023        end_cmd_q();    // stop adding to q
    29843024    case 0x00:          // nul- ignore
     
    29883028        dot_scroll(rows - 2, -1);
    29893029        break;
    2990 #ifdef CONFIG_FEATURE_VI_USE_SIGNALS
     3030#if ENABLE_FEATURE_VI_USE_SIGNALS
    29913031    case 0x03:          // ctrl-C   interrupt
    29923032        longjmp(restart, 1);
     
    29953035        suspend_sig(SIGTSTP);
    29963036        break;
    2997 #endif                          /* CONFIG_FEATURE_VI_USE_SIGNALS */
     3037#endif
    29983038    case 4:         // ctrl-D  scroll down half screen
    29993039        dot_scroll((rows - 2) / 2, 1);
     
    30123052    case VI_K_LEFT: // cursor key Left
    30133053    case 8:     // ctrl-H- move left    (This may be ERASE char)
    3014     case 127:   // DEL- move left   (This may be ERASE char)
     3054    case 0x7f:  // DEL- move left   (This may be ERASE char)
    30153055        if (cmdcnt-- > 1) {
    30163056            do_cmd(c);
     
    30313071        place_cursor(0, 0, FALSE);  // put cursor in correct place
    30323072        clear_to_eos(); // tel terminal to erase display
    3033         (void) mysleep(10);
     3073        mysleep(10);
    30343074        screen_erase(); // erase the internal screen buffer
    30353075        last_status_cksum = 0;  // force status update
     
    30653105        dot_right();
    30663106        break;
    3067 #ifdef CONFIG_FEATURE_VI_YANKMARK
     3107#if ENABLE_FEATURE_VI_YANKMARK
    30683108    case '"':           // "- name a register to use for Delete/Yank
    30693109        c1 = get_one_char();
     
    30813121            c1 = c1 - 'a';
    30823122            // get the b-o-l
    3083             q = mark[(int) c1];
     3123            q = mark[(unsigned char) c1];
    30843124            if (text <= q && q < end) {
    30853125                dot = q;
     
    31183158        }
    31193159        // are we putting whole lines or strings
    3120         if (strchr((char *) p, '\n') != NULL) {
     3160        if (strchr(p, '\n') != NULL) {
    31213161            if (c == 'P') {
    31223162                dot_begin();    // putting lines- Put above
     
    31473187        }
    31483188        break;
    3149 #endif                          /* CONFIG_FEATURE_VI_YANKMARK */
     3189#endif /* FEATURE_VI_YANKMARK */
    31503190    case '$':           // $- goto end of line
    31513191    case VI_K_END:      // Cursor Key End
     
    31813221            do_cmd(';');
    31823222        }               // repeat cnt
    3183         if (last_forward_char == 0) break;
     3223        if (last_forward_char == 0)
     3224            break;
    31843225        q = dot + 1;
    31853226        while (q < end - 1 && *q != '\n' && *q != last_forward_char) {
     
    31963237        dot_skip_over_ws();
    31973238        break;
    3198 #ifdef CONFIG_FEATURE_VI_DOT_CMD
     3239#if ENABLE_FEATURE_VI_DOT_CMD
    31993240    case '.':           // .- repeat the last modifying command
    32003241        // Stuff the last_modifying_cmd back into stdin
    32013242        // and let it be re-executed.
    32023243        if (last_modifying_cmd != 0) {
    3203             ioq = ioq_start = (Byte *) bb_xstrdup((char *) last_modifying_cmd);
    3204         }
    3205         break;
    3206 #endif                          /* CONFIG_FEATURE_VI_DOT_CMD */
    3207 #ifdef CONFIG_FEATURE_VI_SEARCH
     3244            ioq = ioq_start = xstrdup(last_modifying_cmd);
     3245        }
     3246        break;
     3247#endif
     3248#if ENABLE_FEATURE_VI_SEARCH
    32083249    case '?':           // /- search for a pattern
    32093250    case '/':           // /- search for a pattern
     
    32113252        buf[1] = '\0';
    32123253        q = get_input_line(buf);    // get input line- use "status line"
    3213         if (strlen((char *) q) == 1)
    3214             goto dc3;   // if no pat re-use old pat
    3215         if (strlen((char *) q) > 1) {   // new pat- save it and find
     3254        if (q[0] && !q[1])
     3255            goto dc3; // if no pat re-use old pat
     3256        if (q[0]) {       // strlen(q) > 1: new pat- save it and find
    32163257            // there is a new pat
    32173258            free(last_search_pattern);
    3218             last_search_pattern = (Byte *) bb_xstrdup((char *) q);
     3259            last_search_pattern = xstrdup(q);
    32193260            goto dc3;   // now find the pattern
    32203261        }
     
    32393280            do_cmd(c);
    32403281        }               // repeat cnt
    3241       dc3:
     3282 dc3:
    32423283        if (last_search_pattern == 0) {
    3243             msg = (Byte *) "No previous regular expression";
     3284            msg = "No previous regular expression";
    32443285            goto dc2;
    32453286        }
     
    32523293            p = dot - 1;
    32533294        }
    3254       dc4:
     3295 dc4:
    32553296        q = char_search(p, last_search_pattern + 1, dir, FULL);
    32563297        if (q != NULL) {
    32573298            dot = q;    // good search, update "dot"
    3258             msg = (Byte *) "";
     3299            msg = "";
    32593300            goto dc2;
    32603301        }
     
    32673308        if (q != NULL) {    // found something
    32683309            dot = q;    // found new pattern- goto it
    3269             msg = (Byte *) "search hit BOTTOM, continuing at TOP";
     3310            msg = "search hit BOTTOM, continuing at TOP";
    32703311            if (dir == BACK) {
    3271                 msg = (Byte *) "search hit TOP, continuing at BOTTOM";
     3312                msg = "search hit TOP, continuing at BOTTOM";
    32723313            }
    32733314        } else {
    3274             msg = (Byte *) "Pattern not found";
    3275         }
    3276       dc2:
    3277         if (*msg) psbs("%s", msg);
     3315            msg = "Pattern not found";
     3316        }
     3317 dc2:
     3318        if (*msg)
     3319            psbs("%s", msg);
    32783320        break;
    32793321    case '{':           // {- move backward paragraph
    3280         q = char_search(dot, (Byte *) "\n\n", BACK, FULL);
     3322        q = char_search(dot, "\n\n", BACK, FULL);
    32813323        if (q != NULL) {    // found blank line
    32823324            dot = next_line(q); // move to next blank line
     
    32843326        break;
    32853327    case '}':           // }- move forward paragraph
    3286         q = char_search(dot, (Byte *) "\n\n", FORWARD, FULL);
     3328        q = char_search(dot, "\n\n", FORWARD, FULL);
    32873329        if (q != NULL) {    // found blank line
    32883330            dot = next_line(q); // move to next blank line
    32893331        }
    32903332        break;
    3291 #endif                          /* CONFIG_FEATURE_VI_SEARCH */
     3333#endif /* FEATURE_VI_SEARCH */
    32923334    case '0':           // 0- goto begining of line
    32933335    case '1':           // 1-
     
    33073349        break;
    33083350    case ':':           // :- the colon mode commands
    3309         p = get_input_line((Byte *) ":");   // get input line- use "status line"
    3310 #ifdef CONFIG_FEATURE_VI_COLON
     3351        p = get_input_line(":");    // get input line- use "status line"
     3352#if ENABLE_FEATURE_VI_COLON
    33113353        colon(p);       // execute the command
    3312 #else                           /* CONFIG_FEATURE_VI_COLON */
     3354#else
    33133355        if (*p == ':')
    33143356            p++;                // move past the ':'
    3315         cnt = strlen((char *) p);
     3357        cnt = strlen(p);
    33163358        if (cnt <= 0)
    33173359            break;
    3318         if (strncasecmp((char *) p, "quit", cnt) == 0 ||
    3319             strncasecmp((char *) p, "q!", cnt) == 0) {  // delete lines
     3360        if (strncasecmp(p, "quit", cnt) == 0
     3361         || strncasecmp(p, "q!", cnt) == 0   // delete lines
     3362        ) {
    33203363            if (file_modified && p[1] != '!') {
    33213364                psbs("No write since last change (:quit! overrides)");
     
    33233366                editing = 0;
    33243367            }
    3325         } else if (strncasecmp((char *) p, "write", cnt) == 0
    3326                 || strncasecmp((char *) p, "wq", cnt) == 0
    3327                 || strncasecmp((char *) p, "wn", cnt) == 0
    3328                 || strncasecmp((char *) p, "x", cnt) == 0) {
    3329             cnt = file_write(cfn, text, end - 1);
     3368        } else if (strncasecmp(p, "write", cnt) == 0
     3369                || strncasecmp(p, "wq", cnt) == 0
     3370                || strncasecmp(p, "wn", cnt) == 0
     3371                || strncasecmp(p, "x", cnt) == 0
     3372        ) {
     3373            cnt = file_write(current_filename, text, end - 1);
    33303374            if (cnt < 0) {
    33313375                if (cnt == -1)
     
    33343378                file_modified = 0;
    33353379                last_file_modified = -1;
    3336                 psb("\"%s\" %dL, %dC", cfn, count_lines(text, end - 1), cnt);
    3337                 if (p[0] == 'x' || p[1] == 'q' || p[1] == 'n' ||
    3338                     p[0] == 'X' || p[1] == 'Q' || p[1] == 'N') {
     3380                psb("\"%s\" %dL, %dC", current_filename, count_lines(text, end - 1), cnt);
     3381                if (p[0] == 'x' || p[1] == 'q' || p[1] == 'n'
     3382                 || p[0] == 'X' || p[1] == 'Q' || p[1] == 'N'
     3383                ) {
    33393384                    editing = 0;
    33403385                }
    33413386            }
    3342         } else if (strncasecmp((char *) p, "file", cnt) == 0 ) {
     3387        } else if (strncasecmp(p, "file", cnt) == 0) {
    33433388            last_status_cksum = 0;  // force status update
    3344         } else if (sscanf((char *) p, "%d", &j) > 0) {
     3389        } else if (sscanf(p, "%d", &j) > 0) {
    33453390            dot = find_line(j);     // go to line # j
    33463391            dot_skip_over_ws();
    33473392        } else {        // unrecognised cmd
    3348             ni((Byte *) p);
    3349         }
    3350 #endif                          /* CONFIG_FEATURE_VI_COLON */
     3393            ni(p);
     3394        }
     3395#endif /* !FEATURE_VI_COLON */
    33513396        break;
    33523397    case '<':           // <- Left  shift something
     
    33553400        c1 = get_one_char();    // get the type of thing to delete
    33563401        find_range(&p, &q, c1);
    3357         (void) yank_delete(p, q, 1, YANKONLY);  // save copy before change
     3402        yank_delete(p, q, 1, YANKONLY); // save copy before change
    33583403        p = begin_line(p);
    33593404        q = end_line(q);
     
    33643409                if (*p == '\t') {
    33653410                    // shrink buffer 1 char
    3366                     (void) text_hole_delete(p, p);
     3411                    text_hole_delete(p, p);
    33673412                } else if (*p == ' ') {
    33683413                    // we should be calculating columns, not just SPACE
    33693414                    for (j = 0; *p == ' ' && j < tabstop; j++) {
    3370                         (void) text_hole_delete(p, p);
     3415                        text_hole_delete(p, p);
    33713416                    }
    33723417                }
    33733418            } else if (c == '>') {
    33743419                // shift right -- add tab or 8 spaces
    3375                 (void) char_insert(p, '\t');
     3420                char_insert(p, '\t');
    33763421            }
    33773422        }
     
    34123457        if (c == 'C')
    34133458            goto dc_i;  // start inserting
    3414 #ifdef CONFIG_FEATURE_VI_DOT_CMD
     3459#if ENABLE_FEATURE_VI_DOT_CMD
    34153460        if (c == 'D')
    34163461            end_cmd_q();    // stop adding to q
    3417 #endif                          /* CONFIG_FEATURE_VI_DOT_CMD */
     3462#endif
    34183463        break;
    34193464    case 'G':       // G- goto to a line number (default= E-O-F)
     
    34403485    case 'i':           // i- insert before current char
    34413486    case VI_K_INSERT:   // Cursor Key Insert
    3442       dc_i:
     3487 dc_i:
    34433488        cmd_mode = 1;   // start insrting
    34443489        break;
     
    34513496            *dot++ = ' ';   // replace NL with space
    34523497            file_modified++;
    3453             while (isblnk(*dot)) {  // delete leading WS
     3498            while (isblank(*dot)) { // delete leading WS
    34543499                dot_delete();
    34553500            }
     
    34893534        break;
    34903535    case 'R':           // R- continuous Replace char
    3491       dc5:
     3536 dc5:
    34923537        cmd_mode = 2;
    34933538        break;
     
    35183563        }
    35193564        if (file_modified) {
    3520 #ifdef CONFIG_FEATURE_VI_READONLY
    3521             if (vi_readonly || readonly) {
    3522                 psbs("\"%s\" File is read only", cfn);
    3523                 break;
    3524             }
    3525 #endif      /* CONFIG_FEATURE_VI_READONLY */
    3526             cnt = file_write(cfn, text, end - 1);
     3565            if (ENABLE_FEATURE_VI_READONLY && readonly_mode) {
     3566                psbs("\"%s\" File is read only", current_filename);
     3567                break;
     3568            }
     3569            cnt = file_write(current_filename, text, end - 1);
    35273570            if (cnt < 0) {
    35283571                if (cnt == -1)
     
    35613604    case 'c':           // c- change something
    35623605    case 'd':           // d- delete something
    3563 #ifdef CONFIG_FEATURE_VI_YANKMARK
     3606#if ENABLE_FEATURE_VI_YANKMARK
    35643607    case 'y':           // y- yank   something
    35653608    case 'Y':           // Y- Yank a line
    3566 #endif                          /* CONFIG_FEATURE_VI_YANKMARK */
     3609#endif
    35673610        yf = YANKDEL;   // assume either "c" or "d"
    3568 #ifdef CONFIG_FEATURE_VI_YANKMARK
     3611#if ENABLE_FEATURE_VI_YANKMARK
    35693612        if (c == 'y' || c == 'Y')
    35703613            yf = YANKONLY;
    3571 #endif                          /* CONFIG_FEATURE_VI_YANKMARK */
     3614#endif
    35723615        c1 = 'y';
    35733616        if (c != 'Y')
     
    35793622            if (c == 'c') {
    35803623                // don't include trailing WS as part of word
    3581                 while (isblnk(*q)) {
     3624                while (isblank(*q)) {
    35823625                    if (q <= text || q[-1] == '\n')
    35833626                        break;
     
    36103653            // if CHANGING, not deleting, start inserting after the delete
    36113654            if (c == 'c') {
    3612                 strcpy((char *) buf, "Change");
     3655                strcpy(buf, "Change");
    36133656                goto dc_i;  // start inserting
    36143657            }
    36153658            if (c == 'd') {
    3616                 strcpy((char *) buf, "Delete");
    3617             }
    3618 #ifdef CONFIG_FEATURE_VI_YANKMARK
     3659                strcpy(buf, "Delete");
     3660            }
     3661#if ENABLE_FEATURE_VI_YANKMARK
    36193662            if (c == 'y' || c == 'Y') {
    3620                 strcpy((char *) buf, "Yank");
     3663                strcpy(buf, "Yank");
    36213664            }
    36223665            p = reg[YDreg];
    3623             q = p + strlen((char *) p);
     3666            q = p + strlen(p);
    36243667            for (cnt = 0; p <= q; p++) {
    36253668                if (*p == '\n')
     
    36273670            }
    36283671            psb("%s %d lines (%d chars) using [%c]",
    3629                 buf, cnt, strlen((char *) reg[YDreg]), what_reg());
    3630 #endif                          /* CONFIG_FEATURE_VI_YANKMARK */
     3672                buf, cnt, strlen(reg[YDreg]), what_reg());
     3673#endif
    36313674            end_cmd_q();    // stop adding to q
    36323675        }
     
    37173760    }
    37183761
    3719   dc1:
     3762 dc1:
    37203763    // if text[] just became empty, add back an empty line
    37213764    if (end == text) {
    3722         (void) char_insert(text, '\n'); // start empty buf with dummy line
     3765        char_insert(text, '\n');    // start empty buf with dummy line
    37233766        dot = text;
    37243767    }
     
    37273770        dot = bound_dot(dot);   // make sure "dot" is valid
    37283771    }
    3729 #ifdef CONFIG_FEATURE_VI_YANKMARK
     3772#if ENABLE_FEATURE_VI_YANKMARK
    37303773    check_context(c);   // update the current context
    3731 #endif                          /* CONFIG_FEATURE_VI_YANKMARK */
     3774#endif
    37323775
    37333776    if (!isdigit(c))
     
    37393782}
    37403783
    3741 #ifdef CONFIG_FEATURE_VI_CRASHME
     3784#if ENABLE_FEATURE_VI_CRASHME
    37423785static int totalcmds = 0;
    37433786static int Mp = 85;             // Movement command Probability
     
    37483791static int Pp = 99;             // Put command Probability
    37493792static int M = 0, N = 0, I = 0, D = 0, Y = 0, P = 0, U = 0;
    3750 char chars[20] = "\t012345 abcdABCD-=.$";
    3751 char *words[20] = { "this", "is", "a", "test",
     3793const char chars[20] = "\t012345 abcdABCD-=.$";
     3794const char *const words[20] = {
     3795    "this", "is", "a", "test",
    37523796    "broadcast", "the", "emergency", "of",
    37533797    "system", "quick", "brown", "fox",
     
    37553799    "back", "January", "Febuary", "March"
    37563800};
    3757 char *lines[20] = {
     3801const char *const lines[20] = {
    37583802    "You should have received a copy of the GNU General Public License\n",
    37593803    "char c, cm, *cmd, *cmd1;\n",
     
    38133857    if (readed_for_parse > 0)
    38143858        goto cd1;
    3815   cd0:
     3859 cd0:
    38163860    startrbi = rbi = 0;
    38173861    sleeptime = 0;          // how long to pause between commands
    3818     memset(readbuffer, '\0', BUFSIZ);   // clear the read buffer
     3862    memset(readbuffer, '\0', MAX_LINELEN);   // clear the read buffer
    38193863    // generate a command by percentages
    38203864    percent = (int) lrand48() % 100;        // get a number from 0-99
     
    38753919                readbuffer[rbi++] = chars[((int) lrand48() % strlen(chars))];
    38763920            } else if (thing == 1) {        // insert words
    3877                 strcat((char *) readbuffer, words[(int) lrand48() % 20]);
    3878                 strcat((char *) readbuffer, " ");
     3921                strcat(readbuffer, words[(int) lrand48() % 20]);
     3922                strcat(readbuffer, " ");
    38793923                sleeptime = 0;  // how fast to type
    38803924            } else if (thing == 2) {        // insert lines
    3881                 strcat((char *) readbuffer, lines[(int) lrand48() % 20]);
     3925                strcat(readbuffer, lines[(int) lrand48() % 20]);
    38823926                sleeptime = 0;  // how fast to type
    38833927            } else {        // insert multi-lines
    3884                 strcat((char *) readbuffer, multilines[(int) lrand48() % 20]);
     3928                strcat(readbuffer, multilines[(int) lrand48() % 20]);
    38853929                sleeptime = 0;  // how fast to type
    38863930            }
    38873931        }
    3888         strcat((char *) readbuffer, "\033");
     3932        strcat(readbuffer, "\033");
    38893933    }
    38903934    readed_for_parse = strlen(readbuffer);
    3891   cd1:
     3935 cd1:
    38923936    totalcmds++;
    38933937    if (sleeptime > 0)
    3894         (void) mysleep(sleeptime);      // sleep 1/100 sec
     3938        mysleep(sleeptime);      // sleep 1/100 sec
    38953939}
    38963940
     
    38993943{
    39003944    static time_t oldtim;
     3945
    39013946    time_t tim;
    3902     char d[2], msg[BUFSIZ];
     3947    char d[2], msg[MAX_LINELEN];
    39033948
    39043949    msg[0] = '\0';
    39053950    if (end < text) {
    3906         strcat((char *) msg, "end<text ");
     3951        strcat(msg, "end<text ");
    39073952    }
    39083953    if (end > textend) {
    3909         strcat((char *) msg, "end>textend ");
     3954        strcat(msg, "end>textend ");
    39103955    }
    39113956    if (dot < text) {
    3912         strcat((char *) msg, "dot<text ");
     3957        strcat(msg, "dot<text ");
    39133958    }
    39143959    if (dot > end) {
    3915         strcat((char *) msg, "dot>end ");
     3960        strcat(msg, "dot>end ");
    39163961    }
    39173962    if (screenbegin < text) {
    3918         strcat((char *) msg, "screenbegin<text ");
     3963        strcat(msg, "screenbegin<text ");
    39193964    }
    39203965    if (screenbegin > end - 1) {
    3921         strcat((char *) msg, "screenbegin>end-1 ");
    3922     }
    3923 
    3924     if (strlen(msg) > 0) {
     3966        strcat(msg, "screenbegin>end-1 ");
     3967    }
     3968
     3969    if (msg[0]) {
    39253970        alarm(0);
    39263971        printf("\n\n%d: \'%c\' %s\n\n\n%s[Hit return to continue]%s",
     
    39353980    tim = (time_t) time((time_t *) 0);
    39363981    if (tim >= (oldtim + 3)) {
    3937         sprintf((char *) status_buffer,
     3982        sprintf(status_buffer,
    39383983                "Tot=%d: M=%d N=%d I=%d D=%d Y=%d P=%d U=%d size=%d",
    39393984                totalcmds, M, N, I, D, Y, P, U, end - text + 1);
    39403985        oldtim = tim;
    39413986    }
    3942     return;
    3943 }
    3944 #endif                            /* CONFIG_FEATURE_VI_CRASHME */
     3987}
     3988#endif
Note: See TracChangeset for help on using the changeset viewer.