diff options
author | Glenn L McGrath <bug1@ihug.co.nz> | 2002-12-02 21:18:10 +0000 |
---|---|---|
committer | Glenn L McGrath <bug1@ihug.co.nz> | 2002-12-02 21:18:10 +0000 |
commit | 09adaca37d6bd67745c1c81c598ba25006f990b4 (patch) | |
tree | 7393efda99ebc952755c2a92360c4f6c873d000a | |
parent | 06b1aeaf0ad1748a6e355df3e0e8052d613aa158 (diff) | |
download | busybox-w32-09adaca37d6bd67745c1c81c598ba25006f990b4.tar.gz busybox-w32-09adaca37d6bd67745c1c81c598ba25006f990b4.tar.bz2 busybox-w32-09adaca37d6bd67745c1c81c598ba25006f990b4.zip |
last_patch_69, 8 bit clean and other fixes from Vladimir N. Oleynik
-rw-r--r-- | editors/vi.c | 859 | ||||
-rw-r--r-- | libbb/procps.c | 2 |
2 files changed, 451 insertions, 410 deletions
diff --git a/editors/vi.c b/editors/vi.c index 835adb62e..8e9ecc925 100644 --- a/editors/vi.c +++ b/editors/vi.c | |||
@@ -19,7 +19,7 @@ | |||
19 | */ | 19 | */ |
20 | 20 | ||
21 | static const char vi_Version[] = | 21 | static const char vi_Version[] = |
22 | "$Id: vi.c,v 1.25 2002/11/28 11:27:23 aaronl Exp $"; | 22 | "$Id: vi.c,v 1.26 2002/12/02 21:18:08 bug1 Exp $"; |
23 | 23 | ||
24 | /* | 24 | /* |
25 | * To compile for standalone use: | 25 | * To compile for standalone use: |
@@ -87,6 +87,12 @@ static const char vi_Version[] = | |||
87 | #include "busybox.h" | 87 | #include "busybox.h" |
88 | #endif /* STANDALONE */ | 88 | #endif /* STANDALONE */ |
89 | 89 | ||
90 | #ifdef CONFIG_LOCALE_SUPPORT | ||
91 | #define Isprint(c) isprint((c)) | ||
92 | #else | ||
93 | #define Isprint(c) ( (c) >= ' ' && (c) != 127 && (c) != ((unsigned char)'\233') ) | ||
94 | #endif | ||
95 | |||
90 | #ifndef TRUE | 96 | #ifndef TRUE |
91 | #define TRUE ((int)1) | 97 | #define TRUE ((int)1) |
92 | #define FALSE ((int)0) | 98 | #define FALSE ((int)0) |
@@ -116,6 +122,22 @@ static const char vi_Version[] = | |||
116 | #define VI_K_FUN11 147 // Function Key F11 | 122 | #define VI_K_FUN11 147 // Function Key F11 |
117 | #define VI_K_FUN12 148 // Function Key F12 | 123 | #define VI_K_FUN12 148 // Function Key F12 |
118 | 124 | ||
125 | /* vt102 typical ESC sequence */ | ||
126 | /* terminal standout start/normal ESC sequence */ | ||
127 | static const char SOs[] = "\033[7m"; | ||
128 | static const char SOn[] = "\033[0m"; | ||
129 | /* terminal bell sequence */ | ||
130 | static const char bell[] = "\007"; | ||
131 | /* Clear-end-of-line and Clear-end-of-screen ESC sequence */ | ||
132 | static const char Ceol[] = "\033[0K"; | ||
133 | static const char Ceos [] = "\033[0J"; | ||
134 | /* Cursor motion arbitrary destination ESC sequence */ | ||
135 | static const char CMrc[] = "\033[%d;%dH"; | ||
136 | /* Cursor motion up and down ESC sequence */ | ||
137 | static const char CMup[] = "\033[A"; | ||
138 | static const char CMdown[] = "\n"; | ||
139 | |||
140 | |||
119 | static const int YANKONLY = FALSE; | 141 | static const int YANKONLY = FALSE; |
120 | static const int YANKDEL = TRUE; | 142 | static const int YANKDEL = TRUE; |
121 | static const int FORWARD = 1; // code depends on "1" for array index | 143 | static const int FORWARD = 1; // code depends on "1" for array index |
@@ -131,27 +153,29 @@ static const int S_END_ALNUM = 5; // used in skip_thing() for moving "dot" | |||
131 | 153 | ||
132 | typedef unsigned char Byte; | 154 | typedef unsigned char Byte; |
133 | 155 | ||
156 | static int vi_setops; | ||
157 | #define VI_AUTOINDENT 1 | ||
158 | #define VI_SHOWMATCH 2 | ||
159 | #define VI_IGNORECASE 4 | ||
160 | #define VI_ERR_METHOD 8 | ||
161 | #define autoindent (vi_setops & VI_AUTOINDENT) | ||
162 | #define showmatch (vi_setops & VI_SHOWMATCH ) | ||
163 | #define ignorecase (vi_setops & VI_IGNORECASE) | ||
164 | /* indicate error with beep or flash */ | ||
165 | #define err_method (vi_setops & VI_ERR_METHOD) | ||
166 | |||
134 | 167 | ||
135 | static int editing; // >0 while we are editing a file | 168 | static int editing; // >0 while we are editing a file |
136 | static int cmd_mode; // 0=command 1=insert | 169 | static int cmd_mode; // 0=command 1=insert |
137 | static int file_modified; // buffer contents changed | 170 | static int file_modified; // buffer contents changed |
138 | static int err_method; // indicate error with beep or flash | ||
139 | static int fn_start; // index of first cmd line file name | 171 | static int fn_start; // index of first cmd line file name |
140 | static int save_argc; // how many file names on cmd line | 172 | static int save_argc; // how many file names on cmd line |
141 | static int cmdcnt; // repetition count | 173 | static int cmdcnt; // repetition count |
142 | static fd_set rfds; // use select() for small sleeps | 174 | static fd_set rfds; // use select() for small sleeps |
143 | static struct timeval tv; // use select() for small sleeps | 175 | static struct timeval tv; // use select() for small sleeps |
144 | static char erase_char; // the users erase character | ||
145 | static int rows, columns; // the terminal screen is this size | 176 | static int rows, columns; // the terminal screen is this size |
146 | static int crow, ccol, offset; // cursor is on Crow x Ccol with Horz Ofset | 177 | static int crow, ccol, offset; // cursor is on Crow x Ccol with Horz Ofset |
147 | static char *SOs, *SOn; // terminal standout start/normal ESC sequence | ||
148 | static char *bell; // terminal bell sequence | ||
149 | static char *Ceol, *Ceos; // Clear-end-of-line and Clear-end-of-screen ESC sequence | ||
150 | static char *CMrc; // Cursor motion arbitrary destination ESC sequence | ||
151 | static char *CMup, *CMdown; // Cursor motion up and down ESC sequence | ||
152 | static Byte *status_buffer; // mesages to the user | 178 | static Byte *status_buffer; // mesages to the user |
153 | static Byte last_input_char; // last char read from user | ||
154 | static Byte last_forward_char; // last char searched for with 'f' | ||
155 | static Byte *cfn; // previous, current, and next file name | 179 | static Byte *cfn; // previous, current, and next file name |
156 | static Byte *text, *end, *textend; // pointers to the user data in memory | 180 | static Byte *text, *end, *textend; // pointers to the user data in memory |
157 | static Byte *screen; // pointer to the virtual screen buffer | 181 | static Byte *screen; // pointer to the virtual screen buffer |
@@ -160,6 +184,9 @@ static Byte *screenbegin; // index into text[], of top line on the screen | |||
160 | static Byte *dot; // where all the action takes place | 184 | static Byte *dot; // where all the action takes place |
161 | static int tabstop; | 185 | static int tabstop; |
162 | static struct termios term_orig, term_vi; // remember what the cooked mode was | 186 | static struct termios term_orig, term_vi; // remember what the cooked mode was |
187 | static Byte erase_char; // the users erase character | ||
188 | static Byte last_input_char; // last char read from user | ||
189 | static Byte last_forward_char; // last char searched for with 'f' | ||
163 | 190 | ||
164 | #ifdef CONFIG_FEATURE_VI_OPTIMIZE_CURSOR | 191 | #ifdef CONFIG_FEATURE_VI_OPTIMIZE_CURSOR |
165 | static int last_row; // where the cursor was last moved to | 192 | static int last_row; // where the cursor was last moved to |
@@ -167,6 +194,9 @@ static int last_row; // where the cursor was last moved to | |||
167 | #ifdef CONFIG_FEATURE_VI_USE_SIGNALS | 194 | #ifdef CONFIG_FEATURE_VI_USE_SIGNALS |
168 | static jmp_buf restart; // catch_sig() | 195 | static jmp_buf restart; // catch_sig() |
169 | #endif /* CONFIG_FEATURE_VI_USE_SIGNALS */ | 196 | #endif /* CONFIG_FEATURE_VI_USE_SIGNALS */ |
197 | #if defined(CONFIG_FEATURE_VI_USE_SIGNALS) || defined(CONFIG_FEATURE_VI_CRASHME) | ||
198 | static int my_pid; | ||
199 | #endif | ||
170 | #ifdef CONFIG_FEATURE_VI_WIN_RESIZE | 200 | #ifdef CONFIG_FEATURE_VI_WIN_RESIZE |
171 | static struct winsize winsize; // remember the window size | 201 | static struct winsize winsize; // remember the window size |
172 | #endif /* CONFIG_FEATURE_VI_WIN_RESIZE */ | 202 | #endif /* CONFIG_FEATURE_VI_WIN_RESIZE */ |
@@ -181,11 +211,6 @@ static Byte *modifying_cmds; // cmds that modify text[] | |||
181 | #ifdef CONFIG_FEATURE_VI_READONLY | 211 | #ifdef CONFIG_FEATURE_VI_READONLY |
182 | static int vi_readonly, readonly; | 212 | static int vi_readonly, readonly; |
183 | #endif /* CONFIG_FEATURE_VI_READONLY */ | 213 | #endif /* CONFIG_FEATURE_VI_READONLY */ |
184 | #ifdef CONFIG_FEATURE_VI_SETOPTS | ||
185 | static int autoindent; | ||
186 | static int showmatch; | ||
187 | static int ignorecase; | ||
188 | #endif /* CONFIG_FEATURE_VI_SETOPTS */ | ||
189 | #ifdef CONFIG_FEATURE_VI_YANKMARK | 214 | #ifdef CONFIG_FEATURE_VI_YANKMARK |
190 | static Byte *reg[28]; // named register a-z, "D", and "U" 0-25,26,27 | 215 | static Byte *reg[28]; // named register a-z, "D", and "U" 0-25,26,27 |
191 | static int YDreg, Ureg; // default delete register and orig line for "U" | 216 | static int YDreg, Ureg; // default delete register and orig line for "U" |
@@ -202,7 +227,6 @@ static void do_cmd(Byte); // execute a command | |||
202 | static void sync_cursor(Byte *, int *, int *); // synchronize the screen cursor to dot | 227 | static void sync_cursor(Byte *, int *, int *); // synchronize the screen cursor to dot |
203 | static Byte *begin_line(Byte *); // return pointer to cur line B-o-l | 228 | static Byte *begin_line(Byte *); // return pointer to cur line B-o-l |
204 | static Byte *end_line(Byte *); // return pointer to cur line E-o-l | 229 | static Byte *end_line(Byte *); // return pointer to cur line E-o-l |
205 | extern inline Byte *dollar_line(Byte *); // return pointer to just before NL | ||
206 | static Byte *prev_line(Byte *); // return pointer to prev line B-o-l | 230 | static Byte *prev_line(Byte *); // return pointer to prev line B-o-l |
207 | static Byte *next_line(Byte *); // return pointer to next line B-o-l | 231 | static Byte *next_line(Byte *); // return pointer to next line B-o-l |
208 | static Byte *end_screen(void); // get pointer to last char on screen | 232 | static Byte *end_screen(void); // get pointer to last char on screen |
@@ -232,13 +256,12 @@ static Byte *text_hole_delete(Byte *, Byte *); // at "p", delete a 'size' byte h | |||
232 | static Byte *text_hole_make(Byte *, int); // at "p", make a 'size' byte hole | 256 | static Byte *text_hole_make(Byte *, int); // at "p", make a 'size' byte hole |
233 | static Byte *yank_delete(Byte *, Byte *, int, int); // yank text[] into register then delete | 257 | static Byte *yank_delete(Byte *, Byte *, int, int); // yank text[] into register then delete |
234 | static void show_help(void); // display some help info | 258 | static void show_help(void); // display some help info |
235 | extern inline void print_literal(Byte *, Byte *); // copy s to buf, convert unprintable | ||
236 | static void rawmode(void); // set "raw" mode on tty | 259 | static void rawmode(void); // set "raw" mode on tty |
237 | static void cookmode(void); // return to "cooked" mode on tty | 260 | static void cookmode(void); // return to "cooked" mode on tty |
238 | static int mysleep(int); // sleep for 'h' 1/100 seconds | 261 | static int mysleep(int); // sleep for 'h' 1/100 seconds |
239 | static Byte readit(void); // read (maybe cursor) key from stdin | 262 | static Byte readit(void); // read (maybe cursor) key from stdin |
240 | static Byte get_one_char(void); // read 1 char from stdin | 263 | static Byte get_one_char(void); // read 1 char from stdin |
241 | static int file_size(Byte *); // what is the byte size of "fn" | 264 | static int file_size(const Byte *); // what is the byte size of "fn" |
242 | static int file_insert(Byte *, Byte *, int); | 265 | static int file_insert(Byte *, Byte *, int); |
243 | static int file_write(Byte *, Byte *, Byte *); | 266 | static int file_write(Byte *, Byte *, Byte *); |
244 | static void place_cursor(int, int, int); | 267 | static void place_cursor(int, int, int); |
@@ -248,17 +271,18 @@ static void clear_to_eos(void); | |||
248 | static void standout_start(void); // send "start reverse video" sequence | 271 | static void standout_start(void); // send "start reverse video" sequence |
249 | static void standout_end(void); // send "end reverse video" sequence | 272 | static void standout_end(void); // send "end reverse video" sequence |
250 | static void flash(int); // flash the terminal screen | 273 | static void flash(int); // flash the terminal screen |
251 | static void beep(void); // beep the terminal | ||
252 | static void indicate_error(char); // use flash or beep to indicate error | ||
253 | static void show_status_line(void); // put a message on the bottom line | 274 | static void show_status_line(void); // put a message on the bottom line |
254 | static void psb(char *, ...); // Print Status Buf | 275 | static void psb(const char *, ...); // Print Status Buf |
255 | static void psbs(char *, ...); // Print Status Buf in standout mode | 276 | static void psbs(const char *, ...); // Print Status Buf in standout mode |
256 | static void ni(Byte *); // display messages | 277 | static void ni(Byte *); // display messages |
257 | static void edit_status(void); // show file status on status line | 278 | static void edit_status(void); // show file status on status line |
258 | static void redraw(int); // force a full screen refresh | 279 | static void redraw(int); // force a full screen refresh |
259 | static void format_line(Byte*, Byte*, int); | 280 | static void format_line(Byte*, Byte*, int); |
260 | static void refresh(int); // update the terminal from screen[] | 281 | static void refresh(int); // update the terminal from screen[] |
261 | 282 | ||
283 | static void Indicate_Error(void); // use flash or beep to indicate error | ||
284 | #define indicate_error(c) Indicate_Error() | ||
285 | |||
262 | #ifdef CONFIG_FEATURE_VI_SEARCH | 286 | #ifdef CONFIG_FEATURE_VI_SEARCH |
263 | static Byte *char_search(Byte *, Byte *, int, int); // search for pattern starting at p | 287 | static Byte *char_search(Byte *, Byte *, int, int); // search for pattern starting at p |
264 | static int mycmp(Byte *, Byte *, int); // string cmp based in "ignorecase" | 288 | static int mycmp(Byte *, Byte *, int); // string cmp based in "ignorecase" |
@@ -269,12 +293,10 @@ static Byte *get_one_address(Byte *, int *); // get colon addr, if present | |||
269 | static Byte *get_address(Byte *, int *, int *); // get two colon addrs, if present | 293 | static Byte *get_address(Byte *, int *, int *); // get two colon addrs, if present |
270 | static void colon(Byte *); // execute the "colon" mode cmds | 294 | static void colon(Byte *); // execute the "colon" mode cmds |
271 | #endif /* CONFIG_FEATURE_VI_COLON */ | 295 | #endif /* CONFIG_FEATURE_VI_COLON */ |
272 | static Byte *get_input_line(Byte *); // get input line- use "status line" | ||
273 | #ifdef CONFIG_FEATURE_VI_USE_SIGNALS | 296 | #ifdef CONFIG_FEATURE_VI_USE_SIGNALS |
274 | static void winch_sig(int); // catch window size changes | 297 | static void winch_sig(int); // catch window size changes |
275 | static void suspend_sig(int); // catch ctrl-Z | 298 | static void suspend_sig(int); // catch ctrl-Z |
276 | static void alarm_sig(int); // catch alarm time-outs | 299 | static void catch_sig(int); // catch ctrl-C and alarm time-outs |
277 | static void catch_sig(int); // catch ctrl-C | ||
278 | static void core_sig(int); // catch a core dump signal | 300 | static void core_sig(int); // catch a core dump signal |
279 | #endif /* CONFIG_FEATURE_VI_USE_SIGNALS */ | 301 | #endif /* CONFIG_FEATURE_VI_USE_SIGNALS */ |
280 | #ifdef CONFIG_FEATURE_VI_DOT_CMD | 302 | #ifdef CONFIG_FEATURE_VI_DOT_CMD |
@@ -296,7 +318,6 @@ static Byte *string_insert(Byte *, Byte *); // insert the string at 'p' | |||
296 | static Byte *text_yank(Byte *, Byte *, int); // save copy of "p" into a register | 318 | static Byte *text_yank(Byte *, Byte *, int); // save copy of "p" into a register |
297 | static Byte what_reg(void); // what is letter of current YDreg | 319 | static Byte what_reg(void); // what is letter of current YDreg |
298 | static void check_context(Byte); // remember context for '' command | 320 | static void check_context(Byte); // remember context for '' command |
299 | extern inline Byte *swap_context(Byte *); // goto new context for '' command | ||
300 | #endif /* CONFIG_FEATURE_VI_YANKMARK */ | 321 | #endif /* CONFIG_FEATURE_VI_YANKMARK */ |
301 | #ifdef CONFIG_FEATURE_VI_CRASHME | 322 | #ifdef CONFIG_FEATURE_VI_CRASHME |
302 | static void crash_dummy(); | 323 | static void crash_dummy(); |
@@ -305,26 +326,28 @@ static int crashme = 0; | |||
305 | #endif /* CONFIG_FEATURE_VI_CRASHME */ | 326 | #endif /* CONFIG_FEATURE_VI_CRASHME */ |
306 | 327 | ||
307 | 328 | ||
329 | static void write1(const char *out) | ||
330 | { | ||
331 | fputs(out, stdout); | ||
332 | } | ||
333 | |||
308 | extern int vi_main(int argc, char **argv) | 334 | extern int vi_main(int argc, char **argv) |
309 | { | 335 | { |
310 | int c; | 336 | int c; |
337 | RESERVE_CONFIG_BUFFER(STATUS_BUFFER, 200); | ||
311 | 338 | ||
312 | #ifdef CONFIG_FEATURE_VI_YANKMARK | 339 | #ifdef CONFIG_FEATURE_VI_YANKMARK |
313 | int i; | 340 | int i; |
314 | #endif /* CONFIG_FEATURE_VI_YANKMARK */ | 341 | #endif /* CONFIG_FEATURE_VI_YANKMARK */ |
315 | 342 | #if defined(CONFIG_FEATURE_VI_USE_SIGNALS) || defined(CONFIG_FEATURE_VI_CRASHME) | |
316 | CMrc= "\033[%d;%dH"; // Terminal Crusor motion ESC sequence | 343 | my_pid = getpid(); |
317 | CMup= "\033[A"; // move cursor up one line, same col | 344 | #endif |
318 | CMdown="\n"; // move cursor down one line, same col | ||
319 | Ceol= "\033[0K"; // Clear from cursor to end of line | ||
320 | Ceos= "\033[0J"; // Clear from cursor to end of screen | ||
321 | SOs = "\033[7m"; // Terminal standout mode on | ||
322 | SOn = "\033[0m"; // Terminal standout mode off | ||
323 | bell= "\007"; // Terminal bell sequence | ||
324 | #ifdef CONFIG_FEATURE_VI_CRASHME | 345 | #ifdef CONFIG_FEATURE_VI_CRASHME |
325 | (void) srand((long) getpid()); | 346 | (void) srand((long) my_pid); |
326 | #endif /* CONFIG_FEATURE_VI_CRASHME */ | 347 | #endif /* CONFIG_FEATURE_VI_CRASHME */ |
327 | status_buffer = (Byte *) xmalloc(200); // hold messages to user | 348 | |
349 | status_buffer = STATUS_BUFFER; | ||
350 | |||
328 | #ifdef CONFIG_FEATURE_VI_READONLY | 351 | #ifdef CONFIG_FEATURE_VI_READONLY |
329 | vi_readonly = readonly = FALSE; | 352 | vi_readonly = readonly = FALSE; |
330 | if (strncmp(argv[0], "view", 4) == 0) { | 353 | if (strncmp(argv[0], "view", 4) == 0) { |
@@ -332,11 +355,7 @@ extern int vi_main(int argc, char **argv) | |||
332 | vi_readonly = TRUE; | 355 | vi_readonly = TRUE; |
333 | } | 356 | } |
334 | #endif /* CONFIG_FEATURE_VI_READONLY */ | 357 | #endif /* CONFIG_FEATURE_VI_READONLY */ |
335 | #ifdef CONFIG_FEATURE_VI_SETOPTS | 358 | vi_setops = VI_AUTOINDENT | VI_SHOWMATCH | VI_IGNORECASE | VI_ERR_METHOD; |
336 | autoindent = 1; | ||
337 | ignorecase = 1; | ||
338 | showmatch = 1; | ||
339 | #endif /* CONFIG_FEATURE_VI_SETOPTS */ | ||
340 | #ifdef CONFIG_FEATURE_VI_YANKMARK | 359 | #ifdef CONFIG_FEATURE_VI_YANKMARK |
341 | for (i = 0; i < 28; i++) { | 360 | for (i = 0; i < 28; i++) { |
342 | reg[i] = 0; | 361 | reg[i] = 0; |
@@ -395,11 +414,10 @@ extern int vi_main(int argc, char **argv) | |||
395 | 414 | ||
396 | static void edit_file(Byte * fn) | 415 | static void edit_file(Byte * fn) |
397 | { | 416 | { |
398 | char c; | 417 | Byte c; |
399 | int cnt, size, ch; | 418 | int cnt, size, ch; |
400 | 419 | ||
401 | #ifdef CONFIG_FEATURE_VI_USE_SIGNALS | 420 | #ifdef CONFIG_FEATURE_VI_USE_SIGNALS |
402 | char *msg; | ||
403 | int sig; | 421 | int sig; |
404 | #endif /* CONFIG_FEATURE_VI_USE_SIGNALS */ | 422 | #endif /* CONFIG_FEATURE_VI_USE_SIGNALS */ |
405 | #ifdef CONFIG_FEATURE_VI_YANKMARK | 423 | #ifdef CONFIG_FEATURE_VI_YANKMARK |
@@ -435,33 +453,20 @@ static void edit_file(Byte * fn) | |||
435 | mark[26] = mark[27] = text; // init "previous context" | 453 | mark[26] = mark[27] = text; // init "previous context" |
436 | #endif /* CONFIG_FEATURE_VI_YANKMARK */ | 454 | #endif /* CONFIG_FEATURE_VI_YANKMARK */ |
437 | 455 | ||
438 | err_method = 1; // flash | ||
439 | last_forward_char = last_input_char = '\0'; | 456 | last_forward_char = last_input_char = '\0'; |
440 | crow = 0; | 457 | crow = 0; |
441 | ccol = 0; | 458 | ccol = 0; |
442 | edit_status(); | 459 | edit_status(); |
443 | 460 | ||
444 | #ifdef CONFIG_FEATURE_VI_USE_SIGNALS | 461 | #ifdef CONFIG_FEATURE_VI_USE_SIGNALS |
445 | signal(SIGHUP, catch_sig); | 462 | catch_sig(0); |
446 | signal(SIGINT, catch_sig); | 463 | core_sig(0); |
447 | signal(SIGALRM, alarm_sig); | ||
448 | signal(SIGTERM, catch_sig); | ||
449 | signal(SIGQUIT, core_sig); | ||
450 | signal(SIGILL, core_sig); | ||
451 | signal(SIGTRAP, core_sig); | ||
452 | signal(SIGIOT, core_sig); | ||
453 | signal(SIGABRT, core_sig); | ||
454 | signal(SIGFPE, core_sig); | ||
455 | signal(SIGBUS, core_sig); | ||
456 | signal(SIGSEGV, core_sig); | ||
457 | #ifdef SIGSYS | ||
458 | signal(SIGSYS, core_sig); | ||
459 | #endif | ||
460 | signal(SIGWINCH, winch_sig); | 464 | signal(SIGWINCH, winch_sig); |
461 | signal(SIGTSTP, suspend_sig); | 465 | signal(SIGTSTP, suspend_sig); |
462 | sig = setjmp(restart); | 466 | sig = setjmp(restart); |
463 | if (sig != 0) { | 467 | if (sig != 0) { |
464 | msg = ""; | 468 | const char *msg = ""; |
469 | |||
465 | if (sig == SIGWINCH) | 470 | if (sig == SIGWINCH) |
466 | msg = "(window resize)"; | 471 | msg = "(window resize)"; |
467 | if (sig == SIGHUP) | 472 | if (sig == SIGHUP) |
@@ -496,6 +501,7 @@ static void edit_file(Byte * fn) | |||
496 | #endif /* CONFIG_FEATURE_VI_DOT_CMD */ | 501 | #endif /* CONFIG_FEATURE_VI_DOT_CMD */ |
497 | redraw(FALSE); // dont force every col re-draw | 502 | redraw(FALSE); // dont force every col re-draw |
498 | show_status_line(); | 503 | show_status_line(); |
504 | fflush(stdout); | ||
499 | 505 | ||
500 | //------This is the main Vi cmd handling loop ----------------------- | 506 | //------This is the main Vi cmd handling loop ----------------------- |
501 | while (editing > 0) { | 507 | while (editing > 0) { |
@@ -549,212 +555,6 @@ static void edit_file(Byte * fn) | |||
549 | cookmode(); | 555 | cookmode(); |
550 | } | 556 | } |
551 | 557 | ||
552 | static Byte readbuffer[BUFSIZ]; | ||
553 | |||
554 | #ifdef CONFIG_FEATURE_VI_CRASHME | ||
555 | static int totalcmds = 0; | ||
556 | static int Mp = 85; // Movement command Probability | ||
557 | static int Np = 90; // Non-movement command Probability | ||
558 | static int Dp = 96; // Delete command Probability | ||
559 | static int Ip = 97; // Insert command Probability | ||
560 | static int Yp = 98; // Yank command Probability | ||
561 | static int Pp = 99; // Put command Probability | ||
562 | static int M = 0, N = 0, I = 0, D = 0, Y = 0, P = 0, U = 0; | ||
563 | char chars[20] = "\t012345 abcdABCD-=.$"; | ||
564 | char *words[20] = { "this", "is", "a", "test", | ||
565 | "broadcast", "the", "emergency", "of", | ||
566 | "system", "quick", "brown", "fox", | ||
567 | "jumped", "over", "lazy", "dogs", | ||
568 | "back", "January", "Febuary", "March" | ||
569 | }; | ||
570 | char *lines[20] = { | ||
571 | "You should have received a copy of the GNU General Public License\n", | ||
572 | "char c, cm, *cmd, *cmd1;\n", | ||
573 | "generate a command by percentages\n", | ||
574 | "Numbers may be typed as a prefix to some commands.\n", | ||
575 | "Quit, discarding changes!\n", | ||
576 | "Forced write, if permission originally not valid.\n", | ||
577 | "In general, any ex or ed command (such as substitute or delete).\n", | ||
578 | "I have tickets available for the Blazers vs LA Clippers for Monday, Janurary 1 at 1:00pm.\n", | ||
579 | "Please get w/ me and I will go over it with you.\n", | ||
580 | "The following is a list of scheduled, committed changes.\n", | ||
581 | "1. Launch Norton Antivirus (Start, Programs, Norton Antivirus)\n", | ||
582 | "Reminder....Town Meeting in Central Perk cafe today at 3:00pm.\n", | ||
583 | "Any question about transactions please contact Sterling Huxley.\n", | ||
584 | "I will try to get back to you by Friday, December 31.\n", | ||
585 | "This Change will be implemented on Friday.\n", | ||
586 | "Let me know if you have problems accessing this;\n", | ||
587 | "Sterling Huxley recently added you to the access list.\n", | ||
588 | "Would you like to go to lunch?\n", | ||
589 | "The last command will be automatically run.\n", | ||
590 | "This is too much english for a computer geek.\n", | ||
591 | }; | ||
592 | char *multilines[20] = { | ||
593 | "You should have received a copy of the GNU General Public License\n", | ||
594 | "char c, cm, *cmd, *cmd1;\n", | ||
595 | "generate a command by percentages\n", | ||
596 | "Numbers may be typed as a prefix to some commands.\n", | ||
597 | "Quit, discarding changes!\n", | ||
598 | "Forced write, if permission originally not valid.\n", | ||
599 | "In general, any ex or ed command (such as substitute or delete).\n", | ||
600 | "I have tickets available for the Blazers vs LA Clippers for Monday, Janurary 1 at 1:00pm.\n", | ||
601 | "Please get w/ me and I will go over it with you.\n", | ||
602 | "The following is a list of scheduled, committed changes.\n", | ||
603 | "1. Launch Norton Antivirus (Start, Programs, Norton Antivirus)\n", | ||
604 | "Reminder....Town Meeting in Central Perk cafe today at 3:00pm.\n", | ||
605 | "Any question about transactions please contact Sterling Huxley.\n", | ||
606 | "I will try to get back to you by Friday, December 31.\n", | ||
607 | "This Change will be implemented on Friday.\n", | ||
608 | "Let me know if you have problems accessing this;\n", | ||
609 | "Sterling Huxley recently added you to the access list.\n", | ||
610 | "Would you like to go to lunch?\n", | ||
611 | "The last command will be automatically run.\n", | ||
612 | "This is too much english for a computer geek.\n", | ||
613 | }; | ||
614 | |||
615 | // create a random command to execute | ||
616 | static void crash_dummy() | ||
617 | { | ||
618 | static int sleeptime; // how long to pause between commands | ||
619 | char c, cm, *cmd, *cmd1; | ||
620 | int i, cnt, thing, rbi, startrbi, percent; | ||
621 | |||
622 | // "dot" movement commands | ||
623 | cmd1 = " \n\r\002\004\005\006\025\0310^$-+wWeEbBhjklHL"; | ||
624 | |||
625 | // is there already a command running? | ||
626 | if (strlen((char *) readbuffer) > 0) | ||
627 | goto cd1; | ||
628 | cd0: | ||
629 | startrbi = rbi = 0; | ||
630 | sleeptime = 0; // how long to pause between commands | ||
631 | memset(readbuffer, '\0', BUFSIZ - 1); // clear the read buffer | ||
632 | // generate a command by percentages | ||
633 | percent = (int) lrand48() % 100; // get a number from 0-99 | ||
634 | if (percent < Mp) { // Movement commands | ||
635 | // available commands | ||
636 | cmd = cmd1; | ||
637 | M++; | ||
638 | } else if (percent < Np) { // non-movement commands | ||
639 | cmd = "mz<>\'\""; // available commands | ||
640 | N++; | ||
641 | } else if (percent < Dp) { // Delete commands | ||
642 | cmd = "dx"; // available commands | ||
643 | D++; | ||
644 | } else if (percent < Ip) { // Inset commands | ||
645 | cmd = "iIaAsrJ"; // available commands | ||
646 | I++; | ||
647 | } else if (percent < Yp) { // Yank commands | ||
648 | cmd = "yY"; // available commands | ||
649 | Y++; | ||
650 | } else if (percent < Pp) { // Put commands | ||
651 | cmd = "pP"; // available commands | ||
652 | P++; | ||
653 | } else { | ||
654 | // We do not know how to handle this command, try again | ||
655 | U++; | ||
656 | goto cd0; | ||
657 | } | ||
658 | // randomly pick one of the available cmds from "cmd[]" | ||
659 | i = (int) lrand48() % strlen(cmd); | ||
660 | cm = cmd[i]; | ||
661 | if (strchr(":\024", cm)) | ||
662 | goto cd0; // dont allow colon or ctrl-T commands | ||
663 | readbuffer[rbi++] = cm; // put cmd into input buffer | ||
664 | |||
665 | // now we have the command- | ||
666 | // there are 1, 2, and multi char commands | ||
667 | // find out which and generate the rest of command as necessary | ||
668 | if (strchr("dmryz<>\'\"", cm)) { // 2-char commands | ||
669 | cmd1 = " \n\r0$^-+wWeEbBhjklHL"; | ||
670 | if (cm == 'm' || cm == '\'' || cm == '\"') { // pick a reg[] | ||
671 | cmd1 = "abcdefghijklmnopqrstuvwxyz"; | ||
672 | } | ||
673 | thing = (int) lrand48() % strlen(cmd1); // pick a movement command | ||
674 | c = cmd1[thing]; | ||
675 | readbuffer[rbi++] = c; // add movement to input buffer | ||
676 | } | ||
677 | if (strchr("iIaAsc", cm)) { // multi-char commands | ||
678 | if (cm == 'c') { | ||
679 | // change some thing | ||
680 | thing = (int) lrand48() % strlen(cmd1); // pick a movement command | ||
681 | c = cmd1[thing]; | ||
682 | readbuffer[rbi++] = c; // add movement to input buffer | ||
683 | } | ||
684 | thing = (int) lrand48() % 4; // what thing to insert | ||
685 | cnt = (int) lrand48() % 10; // how many to insert | ||
686 | for (i = 0; i < cnt; i++) { | ||
687 | if (thing == 0) { // insert chars | ||
688 | readbuffer[rbi++] = chars[((int) lrand48() % strlen(chars))]; | ||
689 | } else if (thing == 1) { // insert words | ||
690 | strcat((char *) readbuffer, words[(int) lrand48() % 20]); | ||
691 | strcat((char *) readbuffer, " "); | ||
692 | sleeptime = 0; // how fast to type | ||
693 | } else if (thing == 2) { // insert lines | ||
694 | strcat((char *) readbuffer, lines[(int) lrand48() % 20]); | ||
695 | sleeptime = 0; // how fast to type | ||
696 | } else { // insert multi-lines | ||
697 | strcat((char *) readbuffer, multilines[(int) lrand48() % 20]); | ||
698 | sleeptime = 0; // how fast to type | ||
699 | } | ||
700 | } | ||
701 | strcat((char *) readbuffer, "\033"); | ||
702 | } | ||
703 | cd1: | ||
704 | totalcmds++; | ||
705 | if (sleeptime > 0) | ||
706 | (void) mysleep(sleeptime); // sleep 1/100 sec | ||
707 | } | ||
708 | |||
709 | // test to see if there are any errors | ||
710 | static void crash_test() | ||
711 | { | ||
712 | static time_t oldtim; | ||
713 | time_t tim; | ||
714 | char d[2], buf[BUFSIZ], msg[BUFSIZ]; | ||
715 | |||
716 | msg[0] = '\0'; | ||
717 | if (end < text) { | ||
718 | strcat((char *) msg, "end<text "); | ||
719 | } | ||
720 | if (end > textend) { | ||
721 | strcat((char *) msg, "end>textend "); | ||
722 | } | ||
723 | if (dot < text) { | ||
724 | strcat((char *) msg, "dot<text "); | ||
725 | } | ||
726 | if (dot > end) { | ||
727 | strcat((char *) msg, "dot>end "); | ||
728 | } | ||
729 | if (screenbegin < text) { | ||
730 | strcat((char *) msg, "screenbegin<text "); | ||
731 | } | ||
732 | if (screenbegin > end - 1) { | ||
733 | strcat((char *) msg, "screenbegin>end-1 "); | ||
734 | } | ||
735 | |||
736 | if (strlen(msg) > 0) { | ||
737 | alarm(0); | ||
738 | sprintf(buf, "\n\n%d: \'%c\' %s\n\n\n%s[Hit return to continue]%s", | ||
739 | totalcmds, last_input_char, msg, SOs, SOn); | ||
740 | write(1, buf, strlen(buf)); | ||
741 | while (read(0, d, 1) > 0) { | ||
742 | if (d[0] == '\n' || d[0] == '\r') | ||
743 | break; | ||
744 | } | ||
745 | alarm(3); | ||
746 | } | ||
747 | tim = (time_t) time((time_t *) 0); | ||
748 | if (tim >= (oldtim + 3)) { | ||
749 | sprintf((char *) status_buffer, | ||
750 | "Tot=%d: M=%d N=%d I=%d D=%d Y=%d P=%d U=%d size=%d", | ||
751 | totalcmds, M, N, I, D, Y, P, U, end - text + 1); | ||
752 | oldtim = tim; | ||
753 | } | ||
754 | return; | ||
755 | } | ||
756 | #endif /* CONFIG_FEATURE_VI_CRASHME */ | ||
757 | |||
758 | //----- The Colon commands ------------------------------------- | 558 | //----- The Colon commands ------------------------------------- |
759 | #ifdef CONFIG_FEATURE_VI_COLON | 559 | #ifdef CONFIG_FEATURE_VI_COLON |
760 | static Byte *get_one_address(Byte * p, int *addr) // get colon addr, if present | 560 | static Byte *get_one_address(Byte * p, int *addr) // get colon addr, if present |
@@ -848,6 +648,23 @@ ga0: | |||
848 | return (p); | 648 | return (p); |
849 | } | 649 | } |
850 | 650 | ||
651 | #ifdef CONFIG_FEATURE_VI_SETOPTS | ||
652 | static void setops(const Byte *args, const char *opname, int flg_no, | ||
653 | const char *short_opname, int opt) | ||
654 | { | ||
655 | const char *a = (char *) args + flg_no; | ||
656 | int l = strlen(opname) - 1; /* opname have + ' ' */ | ||
657 | |||
658 | if (strncasecmp(a, opname, l) == 0 || | ||
659 | strncasecmp(a, short_opname, 2) == 0) { | ||
660 | if(flg_no) | ||
661 | vi_setops &= ~opt; | ||
662 | else | ||
663 | vi_setops |= opt; | ||
664 | } | ||
665 | } | ||
666 | #endif | ||
667 | |||
851 | static void colon(Byte * buf) | 668 | static void colon(Byte * buf) |
852 | { | 669 | { |
853 | Byte c, *orig_buf, *buf1, *q, *r; | 670 | Byte c, *orig_buf, *buf1, *q, *r; |
@@ -1065,19 +882,27 @@ static void colon(Byte * buf) | |||
1065 | } | 882 | } |
1066 | place_cursor(rows - 1, 0, FALSE); // go to Status line, bottom of screen | 883 | place_cursor(rows - 1, 0, FALSE); // go to Status line, bottom of screen |
1067 | clear_to_eol(); // clear the line | 884 | clear_to_eol(); // clear the line |
1068 | write(1, "\r\n", 2); | 885 | puts("\r"); |
1069 | for (; q <= r; q++) { | 886 | for (; q <= r; q++) { |
887 | int c_is_no_print; | ||
888 | |||
1070 | c = *q; | 889 | c = *q; |
1071 | if (c > '~') | 890 | c_is_no_print = c > 127 && !Isprint(c); |
891 | if (c_is_no_print) { | ||
892 | c = '.'; | ||
1072 | standout_start(); | 893 | standout_start(); |
894 | } | ||
1073 | if (c == '\n') { | 895 | if (c == '\n') { |
1074 | write(1, "$\r", 2); | 896 | write1("$\r"); |
1075 | } else if (*q < ' ') { | 897 | } else if (c < ' ' || c == 127) { |
1076 | write(1, "^", 1); | 898 | putchar('^'); |
899 | if(c == 127) | ||
900 | c = '?'; | ||
901 | else | ||
1077 | c += '@'; | 902 | c += '@'; |
1078 | } | 903 | } |
1079 | write(1, &c, 1); | 904 | putchar(c); |
1080 | if (c > '~') | 905 | if (c_is_no_print) |
1081 | standout_end(); | 906 | standout_end(); |
1082 | } | 907 | } |
1083 | #ifdef CONFIG_FEATURE_VI_SET | 908 | #ifdef CONFIG_FEATURE_VI_SET |
@@ -1185,23 +1010,11 @@ static void colon(Byte * buf) | |||
1185 | if (strncasecmp((char *) args, "no", 2) == 0) | 1010 | if (strncasecmp((char *) args, "no", 2) == 0) |
1186 | i = 2; // ":set noautoindent" | 1011 | i = 2; // ":set noautoindent" |
1187 | #ifdef CONFIG_FEATURE_VI_SETOPTS | 1012 | #ifdef CONFIG_FEATURE_VI_SETOPTS |
1188 | if (strncasecmp((char *) args + i, "autoindent", 10) == 0 || | 1013 | setops(args, "autoindent ", i, "ai", VI_AUTOINDENT); |
1189 | strncasecmp((char *) args + i, "ai", 2) == 0) { | 1014 | setops(args, "flash ", i, "fl", VI_ERR_METHOD); |
1190 | autoindent = (i == 2) ? 0 : 1; | 1015 | setops(args, "ignorecase ", i, "ic", VI_IGNORECASE); |
1191 | } | 1016 | setops(args, "showmatch ", i, "ic", VI_SHOWMATCH); |
1192 | if (strncasecmp((char *) args + i, "flash", 5) == 0 || | 1017 | if (strncasecmp((char *) args + i, "tabstop=%d ", 7) == 0) { |
1193 | strncasecmp((char *) args + i, "fl", 2) == 0) { | ||
1194 | err_method = (i == 2) ? 0 : 1; | ||
1195 | } | ||
1196 | if (strncasecmp((char *) args + i, "ignorecase", 10) == 0 || | ||
1197 | strncasecmp((char *) args + i, "ic", 2) == 0) { | ||
1198 | ignorecase = (i == 2) ? 0 : 1; | ||
1199 | } | ||
1200 | if (strncasecmp((char *) args + i, "showmatch", 9) == 0 || | ||
1201 | strncasecmp((char *) args + i, "sm", 2) == 0) { | ||
1202 | showmatch = (i == 2) ? 0 : 1; | ||
1203 | } | ||
1204 | if (strncasecmp((char *) args + i, "tabstop", 7) == 0) { | ||
1205 | sscanf(strchr((char *) args + i, '='), "=%d", &ch); | 1018 | sscanf(strchr((char *) args + i, '='), "=%d", &ch); |
1206 | if (ch > 0 && ch < columns - 1) | 1019 | if (ch > 0 && ch < columns - 1) |
1207 | tabstop = ch; | 1020 | tabstop = ch; |
@@ -1318,9 +1131,7 @@ static void colon(Byte * buf) | |||
1318 | #ifdef CONFIG_FEATURE_VI_SEARCH | 1131 | #ifdef CONFIG_FEATURE_VI_SEARCH |
1319 | colon_s_fail: | 1132 | colon_s_fail: |
1320 | psb(":s expression missing delimiters"); | 1133 | psb(":s expression missing delimiters"); |
1321 | return; | ||
1322 | #endif | 1134 | #endif |
1323 | |||
1324 | } | 1135 | } |
1325 | 1136 | ||
1326 | static void Hit_Return(void) | 1137 | static void Hit_Return(void) |
@@ -1328,7 +1139,7 @@ static void Hit_Return(void) | |||
1328 | char c; | 1139 | char c; |
1329 | 1140 | ||
1330 | standout_start(); // start reverse video | 1141 | standout_start(); // start reverse video |
1331 | write(1, "[Hit return to continue]", 24); | 1142 | write1("[Hit return to continue]"); |
1332 | standout_end(); // end reverse video | 1143 | standout_end(); // end reverse video |
1333 | while ((c = get_one_char()) != '\n' && c != '\r') /*do nothing */ | 1144 | while ((c = get_one_char()) != '\n' && c != '\r') /*do nothing */ |
1334 | ; | 1145 | ; |
@@ -1392,7 +1203,7 @@ static void sync_cursor(Byte * d, int *row, int *col) | |||
1392 | if (*tp == '\t') { | 1203 | if (*tp == '\t') { |
1393 | // 7 - (co % 8 ) | 1204 | // 7 - (co % 8 ) |
1394 | co += ((tabstop - 1) - (co % tabstop)); | 1205 | co += ((tabstop - 1) - (co % tabstop)); |
1395 | } else if (*tp < ' ') { | 1206 | } else if (*tp < ' ' || *tp == 127) { |
1396 | co++; // display as ^X, use 2 columns | 1207 | co++; // display as ^X, use 2 columns |
1397 | } | 1208 | } |
1398 | } while (tp++ < d && ++co); | 1209 | } while (tp++ < d && ++co); |
@@ -1442,7 +1253,7 @@ static Byte *end_line(Byte * p) // return pointer to NL of cur line line | |||
1442 | return (p); | 1253 | return (p); |
1443 | } | 1254 | } |
1444 | 1255 | ||
1445 | extern inline Byte *dollar_line(Byte * p) // return pointer to just before NL line | 1256 | static inline Byte *dollar_line(Byte * p) // return pointer to just before NL line |
1446 | { | 1257 | { |
1447 | while (p < end - 1 && *p != '\n') | 1258 | while (p < end - 1 && *p != '\n') |
1448 | p++; // go to cur line E-o-l | 1259 | p++; // go to cur line E-o-l |
@@ -1547,7 +1358,7 @@ static Byte *move_to_col(Byte * p, int l) | |||
1547 | if (*p == '\t') { | 1358 | if (*p == '\t') { |
1548 | // 7 - (co % 8 ) | 1359 | // 7 - (co % 8 ) |
1549 | co += ((tabstop - 1) - (co % tabstop)); | 1360 | co += ((tabstop - 1) - (co % tabstop)); |
1550 | } else if (*p < ' ') { | 1361 | } else if (*p < ' ' || *p == 127) { |
1551 | co++; // display as ^X, use 2 columns | 1362 | co++; // display as ^X, use 2 columns |
1552 | } | 1363 | } |
1553 | } while (++co <= l && p++ < end); | 1364 | } while (++co <= l && p++ < end); |
@@ -1787,7 +1598,7 @@ static Byte *char_insert(Byte * p, Byte c) // insert the char c at 'p' | |||
1787 | p = text_hole_delete(p, p); // shrink buffer 1 char | 1598 | p = text_hole_delete(p, p); // shrink buffer 1 char |
1788 | #ifdef CONFIG_FEATURE_VI_DOT_CMD | 1599 | #ifdef CONFIG_FEATURE_VI_DOT_CMD |
1789 | // also rmove char from last_modifying_cmd | 1600 | // also rmove char from last_modifying_cmd |
1790 | if (strlen((char *) last_modifying_cmd) > 0) { | 1601 | if (last_modifying_cmd != 0 && strlen((char *) last_modifying_cmd) > 0) { |
1791 | Byte *q; | 1602 | Byte *q; |
1792 | 1603 | ||
1793 | q = last_modifying_cmd; | 1604 | q = last_modifying_cmd; |
@@ -2130,7 +1941,7 @@ static void show_help(void) | |||
2130 | ); | 1941 | ); |
2131 | } | 1942 | } |
2132 | 1943 | ||
2133 | extern inline void print_literal(Byte * buf, Byte * s) // copy s to buf, convert unprintable | 1944 | static inline void print_literal(Byte * buf, Byte * s) // copy s to buf, convert unprintable |
2134 | { | 1945 | { |
2135 | Byte c, b[2]; | 1946 | Byte c, b[2]; |
2136 | 1947 | ||
@@ -2139,19 +1950,25 @@ extern inline void print_literal(Byte * buf, Byte * s) // copy s to buf, convert | |||
2139 | if (strlen((char *) s) <= 0) | 1950 | if (strlen((char *) s) <= 0) |
2140 | s = (Byte *) "(NULL)"; | 1951 | s = (Byte *) "(NULL)"; |
2141 | for (; *s > '\0'; s++) { | 1952 | for (; *s > '\0'; s++) { |
1953 | int c_is_no_print; | ||
1954 | |||
2142 | c = *s; | 1955 | c = *s; |
2143 | if (*s > '~') { | 1956 | c_is_no_print = c > 127 && !Isprint(c); |
2144 | strcat((char *) buf, SOs); | 1957 | if (c_is_no_print) { |
2145 | c = *s - 128; | 1958 | strcat((char *) buf, SOn); |
1959 | c = '.'; | ||
2146 | } | 1960 | } |
2147 | if (*s < ' ') { | 1961 | if (c < ' ' || c == 127) { |
2148 | strcat((char *) buf, "^"); | 1962 | strcat((char *) buf, "^"); |
1963 | if(c == 127) | ||
1964 | c = '?'; | ||
1965 | else | ||
2149 | c += '@'; | 1966 | c += '@'; |
2150 | } | 1967 | } |
2151 | b[0] = c; | 1968 | b[0] = c; |
2152 | strcat((char *) buf, (char *) b); | 1969 | strcat((char *) buf, (char *) b); |
2153 | if (*s > '~') | 1970 | if (c_is_no_print) |
2154 | strcat((char *) buf, SOn); | 1971 | strcat((char *) buf, SOs); |
2155 | if (*s == '\n') { | 1972 | if (*s == '\n') { |
2156 | strcat((char *) buf, "$"); | 1973 | strcat((char *) buf, "$"); |
2157 | } | 1974 | } |
@@ -2259,7 +2076,7 @@ static void check_context(Byte cmd) | |||
2259 | return; | 2076 | return; |
2260 | } | 2077 | } |
2261 | 2078 | ||
2262 | extern inline Byte *swap_context(Byte * p) // goto new context for '' command make this the current context | 2079 | static inline Byte *swap_context(Byte * p) // goto new context for '' command make this the current context |
2263 | { | 2080 | { |
2264 | Byte *tmp; | 2081 | Byte *tmp; |
2265 | 2082 | ||
@@ -2301,6 +2118,7 @@ static void rawmode(void) | |||
2301 | 2118 | ||
2302 | static void cookmode(void) | 2119 | static void cookmode(void) |
2303 | { | 2120 | { |
2121 | fflush(stdout); | ||
2304 | tcsetattr(0, TCSANOW, &term_orig); | 2122 | tcsetattr(0, TCSANOW, &term_orig); |
2305 | } | 2123 | } |
2306 | 2124 | ||
@@ -2348,7 +2166,7 @@ static void cont_sig(int sig) | |||
2348 | 2166 | ||
2349 | signal(SIGTSTP, suspend_sig); | 2167 | signal(SIGTSTP, suspend_sig); |
2350 | signal(SIGCONT, SIG_DFL); | 2168 | signal(SIGCONT, SIG_DFL); |
2351 | kill(getpid(), SIGCONT); | 2169 | kill(my_pid, SIGCONT); |
2352 | } | 2170 | } |
2353 | 2171 | ||
2354 | //----- Come here when we get a Suspend signal ------------------- | 2172 | //----- Come here when we get a Suspend signal ------------------- |
@@ -2360,7 +2178,7 @@ static void suspend_sig(int sig) | |||
2360 | 2178 | ||
2361 | signal(SIGCONT, cont_sig); | 2179 | signal(SIGCONT, cont_sig); |
2362 | signal(SIGTSTP, SIG_DFL); | 2180 | signal(SIGTSTP, SIG_DFL); |
2363 | kill(getpid(), SIGTSTP); | 2181 | kill(my_pid, SIGTSTP); |
2364 | } | 2182 | } |
2365 | 2183 | ||
2366 | //----- Come here when we get a signal --------------------------- | 2184 | //----- Come here when we get a signal --------------------------- |
@@ -2369,12 +2187,8 @@ static void catch_sig(int sig) | |||
2369 | signal(SIGHUP, catch_sig); | 2187 | signal(SIGHUP, catch_sig); |
2370 | signal(SIGINT, catch_sig); | 2188 | signal(SIGINT, catch_sig); |
2371 | signal(SIGTERM, catch_sig); | 2189 | signal(SIGTERM, catch_sig); |
2372 | longjmp(restart, sig); | ||
2373 | } | ||
2374 | |||
2375 | static void alarm_sig(int sig) | ||
2376 | { | ||
2377 | signal(SIGALRM, catch_sig); | 2190 | signal(SIGALRM, catch_sig); |
2191 | if(sig) | ||
2378 | longjmp(restart, sig); | 2192 | longjmp(restart, sig); |
2379 | } | 2193 | } |
2380 | 2194 | ||
@@ -2393,15 +2207,18 @@ static void core_sig(int sig) | |||
2393 | signal(SIGSYS, core_sig); | 2207 | signal(SIGSYS, core_sig); |
2394 | #endif | 2208 | #endif |
2395 | 2209 | ||
2210 | if(sig) { // signaled | ||
2396 | dot = bound_dot(dot); // make sure "dot" is valid | 2211 | dot = bound_dot(dot); // make sure "dot" is valid |
2397 | 2212 | ||
2398 | longjmp(restart, sig); | 2213 | longjmp(restart, sig); |
2214 | } | ||
2399 | } | 2215 | } |
2400 | #endif /* CONFIG_FEATURE_VI_USE_SIGNALS */ | 2216 | #endif /* CONFIG_FEATURE_VI_USE_SIGNALS */ |
2401 | 2217 | ||
2402 | static int mysleep(int hund) // sleep for 'h' 1/100 seconds | 2218 | static int mysleep(int hund) // sleep for 'h' 1/100 seconds |
2403 | { | 2219 | { |
2404 | // Don't hang- Wait 5/100 seconds- 1 Sec= 1000000 | 2220 | // Don't hang- Wait 5/100 seconds- 1 Sec= 1000000 |
2221 | fflush(stdout); | ||
2405 | FD_ZERO(&rfds); | 2222 | FD_ZERO(&rfds); |
2406 | FD_SET(0, &rfds); | 2223 | FD_SET(0, &rfds); |
2407 | tv.tv_sec = 0; | 2224 | tv.tv_sec = 0; |
@@ -2410,60 +2227,66 @@ static int mysleep(int hund) // sleep for 'h' 1/100 seconds | |||
2410 | return (FD_ISSET(0, &rfds)); | 2227 | return (FD_ISSET(0, &rfds)); |
2411 | } | 2228 | } |
2412 | 2229 | ||
2230 | static Byte readbuffer[BUFSIZ]; | ||
2231 | static int readed_for_parse; | ||
2232 | |||
2413 | //----- IO Routines -------------------------------------------- | 2233 | //----- IO Routines -------------------------------------------- |
2414 | static Byte readit(void) // read (maybe cursor) key from stdin | 2234 | static Byte readit(void) // read (maybe cursor) key from stdin |
2415 | { | 2235 | { |
2416 | Byte c; | 2236 | Byte c; |
2417 | int i, bufsiz, cnt, cmdindex; | 2237 | int n; |
2418 | struct esc_cmds { | 2238 | struct esc_cmds { |
2419 | Byte *seq; | 2239 | const char *seq; |
2420 | Byte val; | 2240 | Byte val; |
2421 | }; | 2241 | }; |
2422 | 2242 | ||
2423 | static struct esc_cmds esccmds[] = { | 2243 | static const struct esc_cmds esccmds[] = { |
2424 | {(Byte *) "OA", (Byte) VI_K_UP}, // cursor key Up | 2244 | {"OA", (Byte) VI_K_UP}, // cursor key Up |
2425 | {(Byte *) "OB", (Byte) VI_K_DOWN}, // cursor key Down | 2245 | {"OB", (Byte) VI_K_DOWN}, // cursor key Down |
2426 | {(Byte *) "OC", (Byte) VI_K_RIGHT}, // Cursor Key Right | 2246 | {"OC", (Byte) VI_K_RIGHT}, // Cursor Key Right |
2427 | {(Byte *) "OD", (Byte) VI_K_LEFT}, // cursor key Left | 2247 | {"OD", (Byte) VI_K_LEFT}, // cursor key Left |
2428 | {(Byte *) "OH", (Byte) VI_K_HOME}, // Cursor Key Home | 2248 | {"OH", (Byte) VI_K_HOME}, // Cursor Key Home |
2429 | {(Byte *) "OF", (Byte) VI_K_END}, // Cursor Key End | 2249 | {"OF", (Byte) VI_K_END}, // Cursor Key End |
2430 | {(Byte *) "[A", (Byte) VI_K_UP}, // cursor key Up | 2250 | {"[A", (Byte) VI_K_UP}, // cursor key Up |
2431 | {(Byte *) "[B", (Byte) VI_K_DOWN}, // cursor key Down | 2251 | {"[B", (Byte) VI_K_DOWN}, // cursor key Down |
2432 | {(Byte *) "[C", (Byte) VI_K_RIGHT}, // Cursor Key Right | 2252 | {"[C", (Byte) VI_K_RIGHT}, // Cursor Key Right |
2433 | {(Byte *) "[D", (Byte) VI_K_LEFT}, // cursor key Left | 2253 | {"[D", (Byte) VI_K_LEFT}, // cursor key Left |
2434 | {(Byte *) "[H", (Byte) VI_K_HOME}, // Cursor Key Home | 2254 | {"[H", (Byte) VI_K_HOME}, // Cursor Key Home |
2435 | {(Byte *) "[F", (Byte) VI_K_END}, // Cursor Key End | 2255 | {"[F", (Byte) VI_K_END}, // Cursor Key End |
2436 | {(Byte *) "[2~", (Byte) VI_K_INSERT}, // Cursor Key Insert | 2256 | {"[1~", (Byte) VI_K_HOME}, // Cursor Key Home |
2437 | {(Byte *) "[5~", (Byte) VI_K_PAGEUP}, // Cursor Key Page Up | 2257 | {"[2~", (Byte) VI_K_INSERT}, // Cursor Key Insert |
2438 | {(Byte *) "[6~", (Byte) VI_K_PAGEDOWN}, // Cursor Key Page Down | 2258 | {"[4~", (Byte) VI_K_END}, // Cursor Key End |
2439 | {(Byte *) "OP", (Byte) VI_K_FUN1}, // Function Key F1 | 2259 | {"[5~", (Byte) VI_K_PAGEUP}, // Cursor Key Page Up |
2440 | {(Byte *) "OQ", (Byte) VI_K_FUN2}, // Function Key F2 | 2260 | {"[6~", (Byte) VI_K_PAGEDOWN}, // Cursor Key Page Down |
2441 | {(Byte *) "OR", (Byte) VI_K_FUN3}, // Function Key F3 | 2261 | {"OP", (Byte) VI_K_FUN1}, // Function Key F1 |
2442 | {(Byte *) "OS", (Byte) VI_K_FUN4}, // Function Key F4 | 2262 | {"OQ", (Byte) VI_K_FUN2}, // Function Key F2 |
2443 | {(Byte *) "[15~", (Byte) VI_K_FUN5}, // Function Key F5 | 2263 | {"OR", (Byte) VI_K_FUN3}, // Function Key F3 |
2444 | {(Byte *) "[17~", (Byte) VI_K_FUN6}, // Function Key F6 | 2264 | {"OS", (Byte) VI_K_FUN4}, // Function Key F4 |
2445 | {(Byte *) "[18~", (Byte) VI_K_FUN7}, // Function Key F7 | 2265 | {"[15~", (Byte) VI_K_FUN5}, // Function Key F5 |
2446 | {(Byte *) "[19~", (Byte) VI_K_FUN8}, // Function Key F8 | 2266 | {"[17~", (Byte) VI_K_FUN6}, // Function Key F6 |
2447 | {(Byte *) "[20~", (Byte) VI_K_FUN9}, // Function Key F9 | 2267 | {"[18~", (Byte) VI_K_FUN7}, // Function Key F7 |
2448 | {(Byte *) "[21~", (Byte) VI_K_FUN10}, // Function Key F10 | 2268 | {"[19~", (Byte) VI_K_FUN8}, // Function Key F8 |
2449 | {(Byte *) "[23~", (Byte) VI_K_FUN11}, // Function Key F11 | 2269 | {"[20~", (Byte) VI_K_FUN9}, // Function Key F9 |
2450 | {(Byte *) "[24~", (Byte) VI_K_FUN12}, // Function Key F12 | 2270 | {"[21~", (Byte) VI_K_FUN10}, // Function Key F10 |
2451 | {(Byte *) "[11~", (Byte) VI_K_FUN1}, // Function Key F1 | 2271 | {"[23~", (Byte) VI_K_FUN11}, // Function Key F11 |
2452 | {(Byte *) "[12~", (Byte) VI_K_FUN2}, // Function Key F2 | 2272 | {"[24~", (Byte) VI_K_FUN12}, // Function Key F12 |
2453 | {(Byte *) "[13~", (Byte) VI_K_FUN3}, // Function Key F3 | 2273 | {"[11~", (Byte) VI_K_FUN1}, // Function Key F1 |
2454 | {(Byte *) "[14~", (Byte) VI_K_FUN4}, // Function Key F4 | 2274 | {"[12~", (Byte) VI_K_FUN2}, // Function Key F2 |
2275 | {"[13~", (Byte) VI_K_FUN3}, // Function Key F3 | ||
2276 | {"[14~", (Byte) VI_K_FUN4}, // Function Key F4 | ||
2455 | }; | 2277 | }; |
2456 | 2278 | ||
2457 | #define ESCCMDS_COUNT (sizeof(esccmds)/sizeof(struct esc_cmds)) | 2279 | #define ESCCMDS_COUNT (sizeof(esccmds)/sizeof(struct esc_cmds)) |
2458 | 2280 | ||
2459 | (void) alarm(0); // turn alarm OFF while we wait for input | 2281 | (void) alarm(0); // turn alarm OFF while we wait for input |
2282 | fflush(stdout); | ||
2283 | n = readed_for_parse; | ||
2460 | // get input from User- are there already input chars in Q? | 2284 | // get input from User- are there already input chars in Q? |
2461 | bufsiz = strlen((char *) readbuffer); | 2285 | if (n <= 0) { |
2462 | if (bufsiz <= 0) { | ||
2463 | ri0: | 2286 | ri0: |
2464 | // the Q is empty, wait for a typed char | 2287 | // the Q is empty, wait for a typed char |
2465 | bufsiz = read(0, readbuffer, BUFSIZ - 1); | 2288 | n = read(0, readbuffer, BUFSIZ - 1); |
2466 | if (bufsiz < 0) { | 2289 | if (n < 0) { |
2467 | if (errno == EINTR) | 2290 | if (errno == EINTR) |
2468 | goto ri0; // interrupted sys call | 2291 | goto ri0; // interrupted sys call |
2469 | if (errno == EBADF) | 2292 | if (errno == EBADF) |
@@ -2475,14 +2298,10 @@ static Byte readit(void) // read (maybe cursor) key from stdin | |||
2475 | if (errno == EIO) | 2298 | if (errno == EIO) |
2476 | editing = 0; | 2299 | editing = 0; |
2477 | errno = 0; | 2300 | errno = 0; |
2478 | bufsiz = 0; | ||
2479 | } | 2301 | } |
2480 | readbuffer[bufsiz] = '\0'; | 2302 | if(n <= 0) |
2481 | } | 2303 | return 0; // error |
2482 | // return char if it is not part of ESC sequence | 2304 | if (readbuffer[0] == 27) { |
2483 | if (readbuffer[0] != 27) | ||
2484 | goto ri1; | ||
2485 | |||
2486 | // This is an ESC char. Is this Esc sequence? | 2305 | // This is an ESC char. Is this Esc sequence? |
2487 | // Could be bare Esc key. See if there are any | 2306 | // Could be bare Esc key. See if there are any |
2488 | // more chars to read after the ESC. This would | 2307 | // more chars to read after the ESC. This would |
@@ -2493,34 +2312,44 @@ static Byte readit(void) // read (maybe cursor) key from stdin | |||
2493 | tv.tv_usec = 50000; // Wait 5/100 seconds- 1 Sec=1000000 | 2312 | tv.tv_usec = 50000; // Wait 5/100 seconds- 1 Sec=1000000 |
2494 | 2313 | ||
2495 | // keep reading while there are input chars and room in buffer | 2314 | // keep reading while there are input chars and room in buffer |
2496 | while (select(1, &rfds, NULL, NULL, &tv) > 0 && bufsiz <= (BUFSIZ - 5)) { | 2315 | while (select(1, &rfds, NULL, NULL, &tv) > 0 && n <= (BUFSIZ - 5)) { |
2497 | // read the rest of the ESC string | 2316 | // read the rest of the ESC string |
2498 | i = read(0, (void *) (readbuffer + bufsiz), BUFSIZ - bufsiz); | 2317 | int r = read(0, (void *) (readbuffer + n), BUFSIZ - n); |
2499 | if (i > 0) { | 2318 | if (r > 0) { |
2500 | bufsiz += i; | 2319 | n += r; |
2501 | readbuffer[bufsiz] = '\0'; // Terminate the string | 2320 | } |
2321 | } | ||
2502 | } | 2322 | } |
2323 | readed_for_parse = n; | ||
2503 | } | 2324 | } |
2325 | c = readbuffer[0]; | ||
2326 | if(c == 27 && n > 1) { | ||
2504 | // Maybe cursor or function key? | 2327 | // Maybe cursor or function key? |
2505 | for (cmdindex = 0; cmdindex < ESCCMDS_COUNT; cmdindex++) { | 2328 | const struct esc_cmds *eindex; |
2506 | cnt = strlen((char *) esccmds[cmdindex].seq); | 2329 | |
2507 | i = strncmp((char *) esccmds[cmdindex].seq, (char *) readbuffer, cnt); | 2330 | for (eindex = esccmds; eindex < &esccmds[ESCCMDS_COUNT]; eindex++) { |
2508 | if (i == 0) { | 2331 | int cnt = strlen(eindex->seq); |
2332 | |||
2333 | if(n <= cnt) | ||
2334 | continue; | ||
2335 | if(strncmp(eindex->seq, (char *) readbuffer + 1, cnt)) | ||
2336 | continue; | ||
2509 | // is a Cursor key- put derived value back into Q | 2337 | // is a Cursor key- put derived value back into Q |
2510 | readbuffer[0] = esccmds[cmdindex].val; | 2338 | c = eindex->val; |
2511 | // squeeze out the ESC sequence | 2339 | // for squeeze out the ESC sequence |
2512 | for (i = 1; i < cnt; i++) { | 2340 | n = cnt + 1; |
2513 | memmove(readbuffer + 1, readbuffer + 2, BUFSIZ - 2); | ||
2514 | readbuffer[BUFSIZ - 1] = '\0'; | ||
2515 | } | ||
2516 | break; | 2341 | break; |
2517 | } | 2342 | } |
2343 | if(eindex == &esccmds[ESCCMDS_COUNT]) { | ||
2344 | /* defined ESC sequence not found, set only one ESC */ | ||
2345 | n = 1; | ||
2518 | } | 2346 | } |
2519 | ri1: | 2347 | } else { |
2520 | c = readbuffer[0]; | 2348 | n = 1; |
2521 | // remove one char from Q | 2349 | } |
2522 | memmove(readbuffer, readbuffer + 1, BUFSIZ - 1); | 2350 | // remove key sequence from Q |
2523 | readbuffer[BUFSIZ - 1] = '\0'; | 2351 | readed_for_parse -= n; |
2352 | memmove(readbuffer, readbuffer + n, BUFSIZ - n); | ||
2524 | (void) alarm(3); // we are done waiting for input, turn alarm ON | 2353 | (void) alarm(3); // we are done waiting for input, turn alarm ON |
2525 | return (c); | 2354 | return (c); |
2526 | } | 2355 | } |
@@ -2561,7 +2390,6 @@ static Byte get_one_char() | |||
2561 | // add new char to q | 2390 | // add new char to q |
2562 | last_modifying_cmd[len] = c; | 2391 | last_modifying_cmd[len] = c; |
2563 | } | 2392 | } |
2564 | |||
2565 | } | 2393 | } |
2566 | } | 2394 | } |
2567 | #else /* CONFIG_FEATURE_VI_DOT_CMD */ | 2395 | #else /* CONFIG_FEATURE_VI_DOT_CMD */ |
@@ -2581,7 +2409,7 @@ static Byte *get_input_line(Byte * prompt) // get input line- use "status line" | |||
2581 | *status_buffer = '\0'; // clear the status buffer | 2409 | *status_buffer = '\0'; // clear the status buffer |
2582 | place_cursor(rows - 1, 0, FALSE); // go to Status line, bottom of screen | 2410 | place_cursor(rows - 1, 0, FALSE); // go to Status line, bottom of screen |
2583 | clear_to_eol(); // clear the line | 2411 | clear_to_eol(); // clear the line |
2584 | write(1, prompt, strlen((char *) prompt)); // write out the :, /, or ? prompt | 2412 | write1(prompt); // write out the :, /, or ? prompt |
2585 | 2413 | ||
2586 | for (i = strlen((char *) buf); i < BUFSIZ;) { | 2414 | for (i = strlen((char *) buf); i < BUFSIZ;) { |
2587 | c = get_one_char(); // read user input | 2415 | c = get_one_char(); // read user input |
@@ -2591,14 +2419,14 @@ static Byte *get_input_line(Byte * prompt) // get input line- use "status line" | |||
2591 | i--; // backup to prev char | 2419 | i--; // backup to prev char |
2592 | buf[i] = '\0'; // erase the char | 2420 | buf[i] = '\0'; // erase the char |
2593 | buf[i + 1] = '\0'; // null terminate buffer | 2421 | buf[i + 1] = '\0'; // null terminate buffer |
2594 | write(1, " ", 3); // erase char on screen | 2422 | write1("\b \b"); // erase char on screen |
2595 | if (i <= 0) { // user backs up before b-o-l, exit | 2423 | if (i <= 0) { // user backs up before b-o-l, exit |
2596 | break; | 2424 | break; |
2597 | } | 2425 | } |
2598 | } else { | 2426 | } else { |
2599 | buf[i] = c; // save char in buffer | 2427 | buf[i] = c; // save char in buffer |
2600 | buf[i + 1] = '\0'; // make sure buffer is null terminated | 2428 | buf[i + 1] = '\0'; // make sure buffer is null terminated |
2601 | write(1, buf + i, 1); // echo the char back to user | 2429 | putchar(c); // echo the char back to user |
2602 | i++; | 2430 | i++; |
2603 | } | 2431 | } |
2604 | } | 2432 | } |
@@ -2608,7 +2436,7 @@ static Byte *get_input_line(Byte * prompt) // get input line- use "status line" | |||
2608 | return (obufp); | 2436 | return (obufp); |
2609 | } | 2437 | } |
2610 | 2438 | ||
2611 | static int file_size(Byte * fn) // what is the byte size of "fn" | 2439 | static int file_size(const Byte * fn) // what is the byte size of "fn" |
2612 | { | 2440 | { |
2613 | struct stat st_buf; | 2441 | struct stat st_buf; |
2614 | int cnt, sr; | 2442 | int cnt, sr; |
@@ -2729,7 +2557,6 @@ static void place_cursor(int row, int col, int opti) | |||
2729 | { | 2557 | { |
2730 | char cm1[BUFSIZ]; | 2558 | char cm1[BUFSIZ]; |
2731 | char *cm; | 2559 | char *cm; |
2732 | int l; | ||
2733 | #ifdef CONFIG_FEATURE_VI_OPTIMIZE_CURSOR | 2560 | #ifdef CONFIG_FEATURE_VI_OPTIMIZE_CURSOR |
2734 | char cm2[BUFSIZ]; | 2561 | char cm2[BUFSIZ]; |
2735 | Byte *screenp; | 2562 | Byte *screenp; |
@@ -2784,32 +2611,31 @@ static void place_cursor(int row, int col, int opti) | |||
2784 | } */ | 2611 | } */ |
2785 | #endif /* CONFIG_FEATURE_VI_OPTIMIZE_CURSOR */ | 2612 | #endif /* CONFIG_FEATURE_VI_OPTIMIZE_CURSOR */ |
2786 | pc0: | 2613 | pc0: |
2787 | l= strlen(cm); | 2614 | write1(cm); // move the cursor |
2788 | if (l) write(1, cm, l); // move the cursor | ||
2789 | } | 2615 | } |
2790 | 2616 | ||
2791 | //----- Erase from cursor to end of line ----------------------- | 2617 | //----- Erase from cursor to end of line ----------------------- |
2792 | static void clear_to_eol() | 2618 | static void clear_to_eol() |
2793 | { | 2619 | { |
2794 | write(1, Ceol, strlen(Ceol)); // Erase from cursor to end of line | 2620 | write1(Ceol); // Erase from cursor to end of line |
2795 | } | 2621 | } |
2796 | 2622 | ||
2797 | //----- Erase from cursor to end of screen ----------------------- | 2623 | //----- Erase from cursor to end of screen ----------------------- |
2798 | static void clear_to_eos() | 2624 | static void clear_to_eos() |
2799 | { | 2625 | { |
2800 | write(1, Ceos, strlen(Ceos)); // Erase from cursor to end of screen | 2626 | write1(Ceos); // Erase from cursor to end of screen |
2801 | } | 2627 | } |
2802 | 2628 | ||
2803 | //----- Start standout mode ------------------------------------ | 2629 | //----- Start standout mode ------------------------------------ |
2804 | static void standout_start() // send "start reverse video" sequence | 2630 | static void standout_start() // send "start reverse video" sequence |
2805 | { | 2631 | { |
2806 | write(1, SOs, strlen(SOs)); // Start reverse video mode | 2632 | write1(SOs); // Start reverse video mode |
2807 | } | 2633 | } |
2808 | 2634 | ||
2809 | //----- End standout mode -------------------------------------- | 2635 | //----- End standout mode -------------------------------------- |
2810 | static void standout_end() // send "end reverse video" sequence | 2636 | static void standout_end() // send "end reverse video" sequence |
2811 | { | 2637 | { |
2812 | write(1, SOn, strlen(SOn)); // End reverse video mode | 2638 | write1(SOn); // End reverse video mode |
2813 | } | 2639 | } |
2814 | 2640 | ||
2815 | //----- Flash the screen -------------------------------------- | 2641 | //----- Flash the screen -------------------------------------- |
@@ -2822,19 +2648,14 @@ static void flash(int h) | |||
2822 | redraw(TRUE); | 2648 | redraw(TRUE); |
2823 | } | 2649 | } |
2824 | 2650 | ||
2825 | static void beep() | 2651 | static void Indicate_Error(void) |
2826 | { | ||
2827 | write(1, bell, strlen(bell)); // send out a bell character | ||
2828 | } | ||
2829 | |||
2830 | static void indicate_error(char c) | ||
2831 | { | 2652 | { |
2832 | #ifdef CONFIG_FEATURE_VI_CRASHME | 2653 | #ifdef CONFIG_FEATURE_VI_CRASHME |
2833 | if (crashme > 0) | 2654 | if (crashme > 0) |
2834 | return; // generate a random command | 2655 | return; // generate a random command |
2835 | #endif /* CONFIG_FEATURE_VI_CRASHME */ | 2656 | #endif /* CONFIG_FEATURE_VI_CRASHME */ |
2836 | if (err_method == 0) { | 2657 | if (!err_method) { |
2837 | beep(); | 2658 | write1(bell); // send out a bell character |
2838 | } else { | 2659 | } else { |
2839 | flash(10); | 2660 | flash(10); |
2840 | } | 2661 | } |
@@ -2859,7 +2680,7 @@ static void show_status_line(void) | |||
2859 | if (cnt > 0 && last_cksum != cksum) { | 2680 | if (cnt > 0 && last_cksum != cksum) { |
2860 | last_cksum= cksum; // remember if we have seen this line | 2681 | last_cksum= cksum; // remember if we have seen this line |
2861 | place_cursor(rows - 1, 0, FALSE); // put cursor on status line | 2682 | place_cursor(rows - 1, 0, FALSE); // put cursor on status line |
2862 | write(1, status_buffer, cnt); | 2683 | write1(status_buffer); |
2863 | clear_to_eol(); | 2684 | clear_to_eol(); |
2864 | place_cursor(crow, ccol, FALSE); // put cursor back in correct place | 2685 | place_cursor(crow, ccol, FALSE); // put cursor back in correct place |
2865 | } | 2686 | } |
@@ -2867,7 +2688,7 @@ static void show_status_line(void) | |||
2867 | 2688 | ||
2868 | //----- format the status buffer, the bottom line of screen ------ | 2689 | //----- format the status buffer, the bottom line of screen ------ |
2869 | // print status buffer, with STANDOUT mode | 2690 | // print status buffer, with STANDOUT mode |
2870 | static void psbs(char *format, ...) | 2691 | static void psbs(const char *format, ...) |
2871 | { | 2692 | { |
2872 | va_list args; | 2693 | va_list args; |
2873 | 2694 | ||
@@ -2882,7 +2703,7 @@ static void psbs(char *format, ...) | |||
2882 | } | 2703 | } |
2883 | 2704 | ||
2884 | // print status buffer | 2705 | // print status buffer |
2885 | static void psb(char *format, ...) | 2706 | static void psb(const char *format, ...) |
2886 | { | 2707 | { |
2887 | va_list args; | 2708 | va_list args; |
2888 | 2709 | ||
@@ -2954,7 +2775,10 @@ static void format_line(Byte *dest, Byte *src, int li) | |||
2954 | } | 2775 | } |
2955 | if (c == '\n') | 2776 | if (c == '\n') |
2956 | break; | 2777 | break; |
2957 | if (c < ' ' || c > '~') { | 2778 | if (c > 127 && !Isprint(c)) { |
2779 | c = '.'; | ||
2780 | } | ||
2781 | if (c < ' ' || c == 127) { | ||
2958 | if (c == '\t') { | 2782 | if (c == '\t') { |
2959 | c = ' '; | 2783 | c = ' '; |
2960 | // co % 8 != 7 | 2784 | // co % 8 != 7 |
@@ -2963,8 +2787,10 @@ static void format_line(Byte *dest, Byte *src, int li) | |||
2963 | } | 2787 | } |
2964 | } else { | 2788 | } else { |
2965 | dest[co++] = '^'; | 2789 | dest[co++] = '^'; |
2966 | c |= '@'; // make it visible | 2790 | if(c == 127) |
2967 | c &= 0x7f; // get rid of hi bit | 2791 | c = '?'; |
2792 | else | ||
2793 | c += '@'; // make it visible | ||
2968 | } | 2794 | } |
2969 | } | 2795 | } |
2970 | // the co++ is done here so that the column will | 2796 | // the co++ is done here so that the column will |
@@ -3067,7 +2893,15 @@ static void refresh(int full_screen) | |||
3067 | } | 2893 | } |
3068 | 2894 | ||
3069 | // write line out to terminal | 2895 | // write line out to terminal |
3070 | write(1, sp+cs, ce-cs+1); | 2896 | { |
2897 | int nic = ce-cs+1; | ||
2898 | char *out = sp+cs; | ||
2899 | |||
2900 | while(nic-- > 0) { | ||
2901 | putchar(*out); | ||
2902 | out++; | ||
2903 | } | ||
2904 | } | ||
3071 | #ifdef CONFIG_FEATURE_VI_OPTIMIZE_CURSOR | 2905 | #ifdef CONFIG_FEATURE_VI_OPTIMIZE_CURSOR |
3072 | last_row = li; | 2906 | last_row = li; |
3073 | #endif /* CONFIG_FEATURE_VI_OPTIMIZE_CURSOR */ | 2907 | #endif /* CONFIG_FEATURE_VI_OPTIMIZE_CURSOR */ |
@@ -3131,12 +2965,14 @@ static void do_cmd(Byte c) | |||
3131 | } | 2965 | } |
3132 | 2966 | ||
3133 | if (cmd_mode == 2) { | 2967 | if (cmd_mode == 2) { |
2968 | // flip-flop Insert/Replace mode | ||
2969 | if (c == VI_K_INSERT) goto dc_i; | ||
3134 | // we are 'R'eplacing the current *dot with new char | 2970 | // we are 'R'eplacing the current *dot with new char |
3135 | if (*dot == '\n') { | 2971 | if (*dot == '\n') { |
3136 | // don't Replace past E-o-l | 2972 | // don't Replace past E-o-l |
3137 | cmd_mode = 1; // convert to insert | 2973 | cmd_mode = 1; // convert to insert |
3138 | } else { | 2974 | } else { |
3139 | if (1 <= c && c <= 127) { // only ASCII chars | 2975 | if (1 <= c || Isprint(c)) { |
3140 | if (c != 27) | 2976 | if (c != 27) |
3141 | dot = yank_delete(dot, dot, 0, YANKDEL); // delete char | 2977 | dot = yank_delete(dot, dot, 0, YANKDEL); // delete char |
3142 | dot = char_insert(dot, c); // insert new char | 2978 | dot = char_insert(dot, c); // insert new char |
@@ -3148,8 +2984,8 @@ static void do_cmd(Byte c) | |||
3148 | // hitting "Insert" twice means "R" replace mode | 2984 | // hitting "Insert" twice means "R" replace mode |
3149 | if (c == VI_K_INSERT) goto dc5; | 2985 | if (c == VI_K_INSERT) goto dc5; |
3150 | // insert the char c at "dot" | 2986 | // insert the char c at "dot" |
3151 | if (1 <= c && c <= 127) { | 2987 | if (1 <= c || Isprint(c)) { |
3152 | dot = char_insert(dot, c); // only ASCII chars | 2988 | dot = char_insert(dot, c); |
3153 | } | 2989 | } |
3154 | goto dc1; | 2990 | goto dc1; |
3155 | } | 2991 | } |
@@ -3202,7 +3038,7 @@ key_cmd_mode: | |||
3202 | default: // unrecognised command | 3038 | default: // unrecognised command |
3203 | buf[0] = c; | 3039 | buf[0] = c; |
3204 | buf[1] = '\0'; | 3040 | buf[1] = '\0'; |
3205 | if (c <= ' ') { | 3041 | if (c < ' ') { |
3206 | buf[0] = '^'; | 3042 | buf[0] = '^'; |
3207 | buf[1] = c + '@'; | 3043 | buf[1] = c + '@'; |
3208 | buf[2] = '\0'; | 3044 | buf[2] = '\0'; |
@@ -3953,3 +3789,208 @@ key_cmd_mode: | |||
3953 | if (*dot == '\n' && cnt > 0 && cmd_mode == 0) | 3789 | if (*dot == '\n' && cnt > 0 && cmd_mode == 0) |
3954 | dot--; | 3790 | dot--; |
3955 | } | 3791 | } |
3792 | |||
3793 | #ifdef CONFIG_FEATURE_VI_CRASHME | ||
3794 | static int totalcmds = 0; | ||
3795 | static int Mp = 85; // Movement command Probability | ||
3796 | static int Np = 90; // Non-movement command Probability | ||
3797 | static int Dp = 96; // Delete command Probability | ||
3798 | static int Ip = 97; // Insert command Probability | ||
3799 | static int Yp = 98; // Yank command Probability | ||
3800 | static int Pp = 99; // Put command Probability | ||
3801 | static int M = 0, N = 0, I = 0, D = 0, Y = 0, P = 0, U = 0; | ||
3802 | char chars[20] = "\t012345 abcdABCD-=.$"; | ||
3803 | char *words[20] = { "this", "is", "a", "test", | ||
3804 | "broadcast", "the", "emergency", "of", | ||
3805 | "system", "quick", "brown", "fox", | ||
3806 | "jumped", "over", "lazy", "dogs", | ||
3807 | "back", "January", "Febuary", "March" | ||
3808 | }; | ||
3809 | char *lines[20] = { | ||
3810 | "You should have received a copy of the GNU General Public License\n", | ||
3811 | "char c, cm, *cmd, *cmd1;\n", | ||
3812 | "generate a command by percentages\n", | ||
3813 | "Numbers may be typed as a prefix to some commands.\n", | ||
3814 | "Quit, discarding changes!\n", | ||
3815 | "Forced write, if permission originally not valid.\n", | ||
3816 | "In general, any ex or ed command (such as substitute or delete).\n", | ||
3817 | "I have tickets available for the Blazers vs LA Clippers for Monday, Janurary 1 at 1:00pm.\n", | ||
3818 | "Please get w/ me and I will go over it with you.\n", | ||
3819 | "The following is a list of scheduled, committed changes.\n", | ||
3820 | "1. Launch Norton Antivirus (Start, Programs, Norton Antivirus)\n", | ||
3821 | "Reminder....Town Meeting in Central Perk cafe today at 3:00pm.\n", | ||
3822 | "Any question about transactions please contact Sterling Huxley.\n", | ||
3823 | "I will try to get back to you by Friday, December 31.\n", | ||
3824 | "This Change will be implemented on Friday.\n", | ||
3825 | "Let me know if you have problems accessing this;\n", | ||
3826 | "Sterling Huxley recently added you to the access list.\n", | ||
3827 | "Would you like to go to lunch?\n", | ||
3828 | "The last command will be automatically run.\n", | ||
3829 | "This is too much english for a computer geek.\n", | ||
3830 | }; | ||
3831 | char *multilines[20] = { | ||
3832 | "You should have received a copy of the GNU General Public License\n", | ||
3833 | "char c, cm, *cmd, *cmd1;\n", | ||
3834 | "generate a command by percentages\n", | ||
3835 | "Numbers may be typed as a prefix to some commands.\n", | ||
3836 | "Quit, discarding changes!\n", | ||
3837 | "Forced write, if permission originally not valid.\n", | ||
3838 | "In general, any ex or ed command (such as substitute or delete).\n", | ||
3839 | "I have tickets available for the Blazers vs LA Clippers for Monday, Janurary 1 at 1:00pm.\n", | ||
3840 | "Please get w/ me and I will go over it with you.\n", | ||
3841 | "The following is a list of scheduled, committed changes.\n", | ||
3842 | "1. Launch Norton Antivirus (Start, Programs, Norton Antivirus)\n", | ||
3843 | "Reminder....Town Meeting in Central Perk cafe today at 3:00pm.\n", | ||
3844 | "Any question about transactions please contact Sterling Huxley.\n", | ||
3845 | "I will try to get back to you by Friday, December 31.\n", | ||
3846 | "This Change will be implemented on Friday.\n", | ||
3847 | "Let me know if you have problems accessing this;\n", | ||
3848 | "Sterling Huxley recently added you to the access list.\n", | ||
3849 | "Would you like to go to lunch?\n", | ||
3850 | "The last command will be automatically run.\n", | ||
3851 | "This is too much english for a computer geek.\n", | ||
3852 | }; | ||
3853 | |||
3854 | // create a random command to execute | ||
3855 | static void crash_dummy() | ||
3856 | { | ||
3857 | static int sleeptime; // how long to pause between commands | ||
3858 | char c, cm, *cmd, *cmd1; | ||
3859 | int i, cnt, thing, rbi, startrbi, percent; | ||
3860 | |||
3861 | // "dot" movement commands | ||
3862 | cmd1 = " \n\r\002\004\005\006\025\0310^$-+wWeEbBhjklHL"; | ||
3863 | |||
3864 | // is there already a command running? | ||
3865 | if (readed_for_parse > 0) | ||
3866 | goto cd1; | ||
3867 | cd0: | ||
3868 | startrbi = rbi = 0; | ||
3869 | sleeptime = 0; // how long to pause between commands | ||
3870 | memset(readbuffer, '\0', BUFSIZ); // clear the read buffer | ||
3871 | // generate a command by percentages | ||
3872 | percent = (int) lrand48() % 100; // get a number from 0-99 | ||
3873 | if (percent < Mp) { // Movement commands | ||
3874 | // available commands | ||
3875 | cmd = cmd1; | ||
3876 | M++; | ||
3877 | } else if (percent < Np) { // non-movement commands | ||
3878 | cmd = "mz<>\'\""; // available commands | ||
3879 | N++; | ||
3880 | } else if (percent < Dp) { // Delete commands | ||
3881 | cmd = "dx"; // available commands | ||
3882 | D++; | ||
3883 | } else if (percent < Ip) { // Inset commands | ||
3884 | cmd = "iIaAsrJ"; // available commands | ||
3885 | I++; | ||
3886 | } else if (percent < Yp) { // Yank commands | ||
3887 | cmd = "yY"; // available commands | ||
3888 | Y++; | ||
3889 | } else if (percent < Pp) { // Put commands | ||
3890 | cmd = "pP"; // available commands | ||
3891 | P++; | ||
3892 | } else { | ||
3893 | // We do not know how to handle this command, try again | ||
3894 | U++; | ||
3895 | goto cd0; | ||
3896 | } | ||
3897 | // randomly pick one of the available cmds from "cmd[]" | ||
3898 | i = (int) lrand48() % strlen(cmd); | ||
3899 | cm = cmd[i]; | ||
3900 | if (strchr(":\024", cm)) | ||
3901 | goto cd0; // dont allow colon or ctrl-T commands | ||
3902 | readbuffer[rbi++] = cm; // put cmd into input buffer | ||
3903 | |||
3904 | // now we have the command- | ||
3905 | // there are 1, 2, and multi char commands | ||
3906 | // find out which and generate the rest of command as necessary | ||
3907 | if (strchr("dmryz<>\'\"", cm)) { // 2-char commands | ||
3908 | cmd1 = " \n\r0$^-+wWeEbBhjklHL"; | ||
3909 | if (cm == 'm' || cm == '\'' || cm == '\"') { // pick a reg[] | ||
3910 | cmd1 = "abcdefghijklmnopqrstuvwxyz"; | ||
3911 | } | ||
3912 | thing = (int) lrand48() % strlen(cmd1); // pick a movement command | ||
3913 | c = cmd1[thing]; | ||
3914 | readbuffer[rbi++] = c; // add movement to input buffer | ||
3915 | } | ||
3916 | if (strchr("iIaAsc", cm)) { // multi-char commands | ||
3917 | if (cm == 'c') { | ||
3918 | // change some thing | ||
3919 | thing = (int) lrand48() % strlen(cmd1); // pick a movement command | ||
3920 | c = cmd1[thing]; | ||
3921 | readbuffer[rbi++] = c; // add movement to input buffer | ||
3922 | } | ||
3923 | thing = (int) lrand48() % 4; // what thing to insert | ||
3924 | cnt = (int) lrand48() % 10; // how many to insert | ||
3925 | for (i = 0; i < cnt; i++) { | ||
3926 | if (thing == 0) { // insert chars | ||
3927 | readbuffer[rbi++] = chars[((int) lrand48() % strlen(chars))]; | ||
3928 | } else if (thing == 1) { // insert words | ||
3929 | strcat((char *) readbuffer, words[(int) lrand48() % 20]); | ||
3930 | strcat((char *) readbuffer, " "); | ||
3931 | sleeptime = 0; // how fast to type | ||
3932 | } else if (thing == 2) { // insert lines | ||
3933 | strcat((char *) readbuffer, lines[(int) lrand48() % 20]); | ||
3934 | sleeptime = 0; // how fast to type | ||
3935 | } else { // insert multi-lines | ||
3936 | strcat((char *) readbuffer, multilines[(int) lrand48() % 20]); | ||
3937 | sleeptime = 0; // how fast to type | ||
3938 | } | ||
3939 | } | ||
3940 | strcat((char *) readbuffer, "\033"); | ||
3941 | } | ||
3942 | readed_for_parse = strlen(readbuffer); | ||
3943 | cd1: | ||
3944 | totalcmds++; | ||
3945 | if (sleeptime > 0) | ||
3946 | (void) mysleep(sleeptime); // sleep 1/100 sec | ||
3947 | } | ||
3948 | |||
3949 | // test to see if there are any errors | ||
3950 | static void crash_test() | ||
3951 | { | ||
3952 | static time_t oldtim; | ||
3953 | time_t tim; | ||
3954 | char d[2], buf[BUFSIZ], msg[BUFSIZ]; | ||
3955 | |||
3956 | msg[0] = '\0'; | ||
3957 | if (end < text) { | ||
3958 | strcat((char *) msg, "end<text "); | ||
3959 | } | ||
3960 | if (end > textend) { | ||
3961 | strcat((char *) msg, "end>textend "); | ||
3962 | } | ||
3963 | if (dot < text) { | ||
3964 | strcat((char *) msg, "dot<text "); | ||
3965 | } | ||
3966 | if (dot > end) { | ||
3967 | strcat((char *) msg, "dot>end "); | ||
3968 | } | ||
3969 | if (screenbegin < text) { | ||
3970 | strcat((char *) msg, "screenbegin<text "); | ||
3971 | } | ||
3972 | if (screenbegin > end - 1) { | ||
3973 | strcat((char *) msg, "screenbegin>end-1 "); | ||
3974 | } | ||
3975 | |||
3976 | if (strlen(msg) > 0) { | ||
3977 | alarm(0); | ||
3978 | printf(buf, "\n\n%d: \'%c\' %s\n\n\n%s[Hit return to continue]%s", | ||
3979 | totalcmds, last_input_char, msg, SOs, SOn); | ||
3980 | fflush(stdout); | ||
3981 | while (read(0, d, 1) > 0) { | ||
3982 | if (d[0] == '\n' || d[0] == '\r') | ||
3983 | break; | ||
3984 | } | ||
3985 | alarm(3); | ||
3986 | } | ||
3987 | tim = (time_t) time((time_t *) 0); | ||
3988 | if (tim >= (oldtim + 3)) { | ||
3989 | sprintf((char *) status_buffer, | ||
3990 | "Tot=%d: M=%d N=%d I=%d D=%d Y=%d P=%d U=%d size=%d", | ||
3991 | totalcmds, M, N, I, D, Y, P, U, end - text + 1); | ||
3992 | oldtim = tim; | ||
3993 | } | ||
3994 | return; | ||
3995 | } | ||
3996 | #endif /* CONFIG_FEATURE_VI_CRASHME */ | ||
diff --git a/libbb/procps.c b/libbb/procps.c index e76e1ac36..2d2a9665f 100644 --- a/libbb/procps.c +++ b/libbb/procps.c | |||
@@ -115,7 +115,7 @@ extern procps_status_t * procps_scan(int save_user_arg0) | |||
115 | buf[--n] = 0; | 115 | buf[--n] = 0; |
116 | name = buf; | 116 | name = buf; |
117 | while(n) { | 117 | while(n) { |
118 | if(*name < ' ') | 118 | if(((unsigned char)*name) < ' ') |
119 | *name = ' '; | 119 | *name = ' '; |
120 | name++; | 120 | name++; |
121 | n--; | 121 | n--; |