diff options
author | Denis Vlasenko <vda.linux@googlemail.com> | 2008-06-20 20:20:54 +0000 |
---|---|---|
committer | Denis Vlasenko <vda.linux@googlemail.com> | 2008-06-20 20:20:54 +0000 |
commit | b175946ba4426c4bb529f9b98f75105e21208c83 (patch) | |
tree | ab1c3187de9928a868396fc6973f9e1b55d57f17 /editors/vi.c | |
parent | b67004b2ae9ff6d5b31e3907465e35b8a7596dbe (diff) | |
download | busybox-w32-b175946ba4426c4bb529f9b98f75105e21208c83.tar.gz busybox-w32-b175946ba4426c4bb529f9b98f75105e21208c83.tar.bz2 busybox-w32-b175946ba4426c4bb529f9b98f75105e21208c83.zip |
vi: fix the bug where vi never grows the edit buffer.
vi: do G trick on it
function old new delta
place_cursor 264 276 +12
next_tabstop 22 34 +12
mycmp 44 52 +8
status_line 34 40 +6
yank_delete 89 92 +3
what_reg 34 37 +3
suspend_sig 63 66 +3
find_range 493 496 +3
redraw 104 106 +2
cont_sig 63 65 +2
Indicate_Error 59 61 +2
status_line_bold 71 72 +1
file_insert 327 328 +1
vi_setops 1 - -1
...
cmdcnt 4 - -4
chars_to_parse 4 - -4
ccol 4 - -4
dot_scroll 88 79 -9
stupid_insert 28 18 -10
winch_sig 102 91 -11
char_insert 353 336 -17
readit 354 336 -18
get_one_char 128 110 -18
init_text_buffer 171 152 -19
text_hole_delete 132 112 -20
edit_file 940 918 -22
get_input_line 198 168 -30
show_status_line 449 408 -41
colon 3112 3067 -45
vi_main 312 250 -62
refresh 1077 974 -103
do_cmd 4818 4483 -335
------------------------------------------------------------------------------
(add/remove: 0/38 grow/shrink: 13/20 up/down: 58/-889) Total: -831 bytes
text data bss dec hex filename
809566 612 7044 817222 c7846 busybox_old
808794 611 6924 816329 c74c9 busybox_unstripped
text data bss dec hex filename
18888 1 122 19011 4a43 busybox.t8/editors/vi.o
18116 0 0 18116 46c4 busybox.t9/editors/vi.o
Diffstat (limited to 'editors/vi.c')
-rw-r--r-- | editors/vi.c | 275 |
1 files changed, 154 insertions, 121 deletions
diff --git a/editors/vi.c b/editors/vi.c index 1770d98c5..17ce88b93 100644 --- a/editors/vi.c +++ b/editors/vi.c | |||
@@ -112,11 +112,19 @@ enum { | |||
112 | S_END_ALNUM = 5, // used in skip_thing() for moving "dot" | 112 | S_END_ALNUM = 5, // used in skip_thing() for moving "dot" |
113 | }; | 113 | }; |
114 | 114 | ||
115 | |||
115 | /* vi.c expects chars to be unsigned. */ | 116 | /* vi.c expects chars to be unsigned. */ |
116 | /* busybox build system provides that, but it's better */ | 117 | /* busybox build system provides that, but it's better */ |
117 | /* to audit and fix the source */ | 118 | /* to audit and fix the source */ |
118 | 119 | ||
119 | static smallint vi_setops; | 120 | struct globals { |
121 | /* many references - keep near the top of globals */ | ||
122 | char *text, *end; // pointers to the user data in memory | ||
123 | char *dot; // where all the action takes place | ||
124 | int text_size; // size of the allocated buffer | ||
125 | |||
126 | /* the rest */ | ||
127 | smallint vi_setops; | ||
120 | #define VI_AUTOINDENT 1 | 128 | #define VI_AUTOINDENT 1 |
121 | #define VI_SHOWMATCH 2 | 129 | #define VI_SHOWMATCH 2 |
122 | #define VI_IGNORECASE 4 | 130 | #define VI_IGNORECASE 4 |
@@ -127,83 +135,76 @@ static smallint vi_setops; | |||
127 | /* indicate error with beep or flash */ | 135 | /* indicate error with beep or flash */ |
128 | #define err_method (vi_setops & VI_ERR_METHOD) | 136 | #define err_method (vi_setops & VI_ERR_METHOD) |
129 | 137 | ||
130 | |||
131 | static smallint editing; // >0 while we are editing a file | ||
132 | // [code audit says "can be 0 or 1 only"] | ||
133 | static smallint cmd_mode; // 0=command 1=insert 2=replace | ||
134 | static smallint file_modified; // buffer contents changed | ||
135 | static smallint last_file_modified = -1; | ||
136 | static int fn_start; // index of first cmd line file name | ||
137 | static int save_argc; // how many file names on cmd line | ||
138 | static int cmdcnt; // repetition count | ||
139 | static unsigned rows, columns; // the terminal screen is this size | ||
140 | static int crow, ccol; // cursor is on Crow x Ccol | ||
141 | static int offset; // chars scrolled off the screen to the left | ||
142 | static char *status_buffer; // mesages to the user | ||
143 | #define STATUS_BUFFER_LEN 200 | ||
144 | static int have_status_msg; // is default edit status needed? | ||
145 | // [don't make smallint!] | ||
146 | static int last_status_cksum; // hash of current status line | ||
147 | static char *current_filename; // current file name | ||
148 | //static char *text, *end; // pointers to the user data in memory | ||
149 | static char *screen; // pointer to the virtual screen buffer | ||
150 | static int screensize; // and its size | ||
151 | static char *screenbegin; // index into text[], of top line on the screen | ||
152 | //static char *dot; // where all the action takes place | ||
153 | static int tabstop; | ||
154 | static char erase_char; // the users erase character | ||
155 | static char last_input_char; // last char read from user | ||
156 | static char last_forward_char; // last char searched for with 'f' | ||
157 | |||
158 | #if ENABLE_FEATURE_VI_READONLY | 138 | #if ENABLE_FEATURE_VI_READONLY |
159 | //static smallint vi_readonly, readonly; | 139 | smallint readonly_mode; |
160 | static smallint readonly_mode = 0; | ||
161 | #define SET_READONLY_FILE(flags) ((flags) |= 0x01) | 140 | #define SET_READONLY_FILE(flags) ((flags) |= 0x01) |
162 | #define SET_READONLY_MODE(flags) ((flags) |= 0x02) | 141 | #define SET_READONLY_MODE(flags) ((flags) |= 0x02) |
163 | #define UNSET_READONLY_FILE(flags) ((flags) &= 0xfe) | 142 | #define UNSET_READONLY_FILE(flags) ((flags) &= 0xfe) |
164 | #else | 143 | #else |
165 | #define readonly_mode 0 | 144 | #define SET_READONLY_FILE(flags) ((void)0) |
166 | #define SET_READONLY_FILE(flags) | 145 | #define SET_READONLY_MODE(flags) ((void)0) |
167 | #define SET_READONLY_MODE(flags) | 146 | #define UNSET_READONLY_FILE(flags) ((void)0) |
168 | #define UNSET_READONLY_FILE(flags) | 147 | #endif |
169 | #endif | 148 | |
149 | smallint editing; // >0 while we are editing a file | ||
150 | // [code audit says "can be 0 or 1 only"] | ||
151 | smallint cmd_mode; // 0=command 1=insert 2=replace | ||
152 | int file_modified; // buffer contents changed (counter, not flag!) | ||
153 | int last_file_modified; // = -1; | ||
154 | int fn_start; // index of first cmd line file name | ||
155 | int save_argc; // how many file names on cmd line | ||
156 | int cmdcnt; // repetition count | ||
157 | unsigned rows, columns; // the terminal screen is this size | ||
158 | int crow, ccol; // cursor is on Crow x Ccol | ||
159 | int offset; // chars scrolled off the screen to the left | ||
160 | int have_status_msg; // is default edit status needed? | ||
161 | // [don't make smallint!] | ||
162 | int last_status_cksum; // hash of current status line | ||
163 | char *current_filename; | ||
164 | char *screenbegin; // index into text[], of top line on the screen | ||
165 | char *screen; // pointer to the virtual screen buffer | ||
166 | int screensize; // and its size | ||
167 | int tabstop; | ||
168 | char erase_char; // the users erase character | ||
169 | char last_input_char; // last char read from user | ||
170 | char last_forward_char; // last char searched for with 'f' | ||
170 | 171 | ||
171 | #if ENABLE_FEATURE_VI_DOT_CMD | 172 | #if ENABLE_FEATURE_VI_DOT_CMD |
172 | static smallint adding2q; // are we currently adding user input to q | 173 | smallint adding2q; // are we currently adding user input to q |
173 | static char *last_modifying_cmd; // [MAX_INPUT_LEN] last modifying cmd for "." | 174 | int lmc_len; // length of last_modifying_cmd |
174 | static smallint lmc_len; // length of last_modifying_cmd | 175 | char *ioq, *ioq_start; // pointer to string for get_one_char to "read" |
175 | static char *ioq, *ioq_start; // pointer to string for get_one_char to "read" | ||
176 | #endif | 176 | #endif |
177 | #if ENABLE_FEATURE_VI_OPTIMIZE_CURSOR | 177 | #if ENABLE_FEATURE_VI_OPTIMIZE_CURSOR |
178 | static int last_row; // where the cursor was last moved to | 178 | int last_row; // where the cursor was last moved to |
179 | #endif | 179 | #endif |
180 | #if ENABLE_FEATURE_VI_USE_SIGNALS || ENABLE_FEATURE_VI_CRASHME | 180 | #if ENABLE_FEATURE_VI_USE_SIGNALS || ENABLE_FEATURE_VI_CRASHME |
181 | static int my_pid; | 181 | int my_pid; |
182 | #endif | 182 | #endif |
183 | #if ENABLE_FEATURE_VI_DOT_CMD || ENABLE_FEATURE_VI_YANKMARK | 183 | #if ENABLE_FEATURE_VI_DOT_CMD || ENABLE_FEATURE_VI_YANKMARK |
184 | static char *modifying_cmds; // cmds that modify text[] | 184 | char *modifying_cmds; // cmds that modify text[] |
185 | #endif | 185 | #endif |
186 | #if ENABLE_FEATURE_VI_SEARCH | 186 | #if ENABLE_FEATURE_VI_SEARCH |
187 | static char *last_search_pattern; // last pattern from a '/' or '?' search | 187 | char *last_search_pattern; // last pattern from a '/' or '?' search |
188 | #endif | ||
189 | int chars_to_parse; | ||
190 | /* former statics */ | ||
191 | #if ENABLE_FEATURE_VI_YANKMARK | ||
192 | char *edit_file__cur_line; | ||
188 | #endif | 193 | #endif |
194 | int refresh__old_offset; | ||
195 | int format_edit_status__tot; | ||
189 | 196 | ||
190 | /* Moving biggest data to malloced space... */ | 197 | /* a few references only */ |
191 | struct globals { | ||
192 | /* many references - keep near the top of globals */ | ||
193 | char *text, *end; // pointers to the user data in memory | ||
194 | char *dot; // where all the action takes place | ||
195 | int text_size; // size of the allocated buffer | ||
196 | #if ENABLE_FEATURE_VI_YANKMARK | 198 | #if ENABLE_FEATURE_VI_YANKMARK |
197 | int YDreg, Ureg; // default delete register and orig line for "U" | 199 | int YDreg, Ureg; // default delete register and orig line for "U" |
198 | char *reg[28]; // named register a-z, "D", and "U" 0-25,26,27 | 200 | char *reg[28]; // named register a-z, "D", and "U" 0-25,26,27 |
199 | char *mark[28]; // user marks points somewhere in text[]- a-z and previous context '' | 201 | char *mark[28]; // user marks points somewhere in text[]- a-z and previous context '' |
200 | char *context_start, *context_end; | 202 | char *context_start, *context_end; |
201 | #endif | 203 | #endif |
202 | /* a few references only */ | ||
203 | #if ENABLE_FEATURE_VI_USE_SIGNALS | 204 | #if ENABLE_FEATURE_VI_USE_SIGNALS |
204 | sigjmp_buf restart; // catch_sig() | 205 | sigjmp_buf restart; // catch_sig() |
205 | #endif | 206 | #endif |
206 | struct termios term_orig, term_vi; // remember what the cooked mode was | 207 | struct termios term_orig, term_vi; // remember what the cooked mode was |
207 | #if ENABLE_FEATURE_VI_COLON | 208 | #if ENABLE_FEATURE_VI_COLON |
208 | char *initial_cmds[3]; // currently 2 entries, NULL terminated | 209 | char *initial_cmds[3]; // currently 2 entries, NULL terminated |
209 | #endif | 210 | #endif |
@@ -214,6 +215,12 @@ struct globals { | |||
214 | #else | 215 | #else |
215 | char readbuffer[32]; | 216 | char readbuffer[32]; |
216 | #endif | 217 | #endif |
218 | #define STATUS_BUFFER_LEN 200 | ||
219 | char status_buffer[STATUS_BUFFER_LEN]; // messages to the user | ||
220 | #if ENABLE_FEATURE_VI_DOT_CMD | ||
221 | char last_modifying_cmd[MAX_INPUT_LEN]; // last modifying cmd for "." | ||
222 | #endif | ||
223 | char get_input_line__buf[MAX_INPUT_LEN]; /* former static */ | ||
217 | 224 | ||
218 | char scr_out_buf[MAX_SCR_COLS + MAX_TABSTOP * 2]; | 225 | char scr_out_buf[MAX_SCR_COLS + MAX_TABSTOP * 2]; |
219 | }; | 226 | }; |
@@ -223,6 +230,50 @@ struct globals { | |||
223 | #define end (G.end ) | 230 | #define end (G.end ) |
224 | #define dot (G.dot ) | 231 | #define dot (G.dot ) |
225 | #define reg (G.reg ) | 232 | #define reg (G.reg ) |
233 | |||
234 | #define vi_setops (G.vi_setops ) | ||
235 | #define editing (G.editing ) | ||
236 | #define cmd_mode (G.cmd_mode ) | ||
237 | #define file_modified (G.file_modified ) | ||
238 | #define last_file_modified (G.last_file_modified ) | ||
239 | #define fn_start (G.fn_start ) | ||
240 | #define save_argc (G.save_argc ) | ||
241 | #define cmdcnt (G.cmdcnt ) | ||
242 | #define rows (G.rows ) | ||
243 | #define columns (G.columns ) | ||
244 | #define crow (G.crow ) | ||
245 | #define ccol (G.ccol ) | ||
246 | #define offset (G.offset ) | ||
247 | #define status_buffer (G.status_buffer ) | ||
248 | #define have_status_msg (G.have_status_msg ) | ||
249 | #define last_status_cksum (G.last_status_cksum ) | ||
250 | #define current_filename (G.current_filename ) | ||
251 | #define screen (G.screen ) | ||
252 | #define screensize (G.screensize ) | ||
253 | #define screenbegin (G.screenbegin ) | ||
254 | #define tabstop (G.tabstop ) | ||
255 | #define erase_char (G.erase_char ) | ||
256 | #define last_input_char (G.last_input_char ) | ||
257 | #define last_forward_char (G.last_forward_char ) | ||
258 | #if ENABLE_FEATURE_VI_READONLY | ||
259 | #define readonly_mode (G.readonly_mode ) | ||
260 | #else | ||
261 | #define readonly_mode 0 readonly_mode ) | ||
262 | #endif | ||
263 | #define adding2q (G.adding2q ) | ||
264 | #define lmc_len (G.lmc_len ) | ||
265 | #define ioq (G.ioq ) | ||
266 | #define ioq_start (G.ioq_start ) | ||
267 | #define last_row (G.last_row ) | ||
268 | #define my_pid (G.my_pid ) | ||
269 | #define modifying_cmds (G.modifying_cmds ) | ||
270 | #define last_search_pattern (G.last_search_pattern) | ||
271 | #define chars_to_parse (G.chars_to_parse ) | ||
272 | |||
273 | #define edit_file__cur_line (G.edit_file__cur_line) | ||
274 | #define refresh__old_offset (G.refresh__old_offset) | ||
275 | #define format_edit_status__tot (G.format_edit_status__tot) | ||
276 | |||
226 | #define YDreg (G.YDreg ) | 277 | #define YDreg (G.YDreg ) |
227 | #define Ureg (G.Ureg ) | 278 | #define Ureg (G.Ureg ) |
228 | #define mark (G.mark ) | 279 | #define mark (G.mark ) |
@@ -234,10 +285,15 @@ struct globals { | |||
234 | #define initial_cmds (G.initial_cmds ) | 285 | #define initial_cmds (G.initial_cmds ) |
235 | #define readbuffer (G.readbuffer ) | 286 | #define readbuffer (G.readbuffer ) |
236 | #define scr_out_buf (G.scr_out_buf ) | 287 | #define scr_out_buf (G.scr_out_buf ) |
288 | #define last_modifying_cmd (G.last_modifying_cmd ) | ||
289 | #define get_input_line__buf (G.get_input_line__buf) | ||
290 | |||
237 | #define INIT_G() do { \ | 291 | #define INIT_G() do { \ |
238 | SET_PTR_TO_GLOBALS(xzalloc(sizeof(G))); \ | 292 | SET_PTR_TO_GLOBALS(xzalloc(sizeof(G))); \ |
293 | last_file_modified = -1; \ | ||
239 | } while (0) | 294 | } while (0) |
240 | 295 | ||
296 | |||
241 | static int init_text_buffer(char *); // init from file or create new | 297 | static int init_text_buffer(char *); // init from file or create new |
242 | static void edit_file(char *); // edit one file | 298 | static void edit_file(char *); // edit one file |
243 | static void do_cmd(char); // execute a command | 299 | static void do_cmd(char); // execute a command |
@@ -355,22 +411,15 @@ int vi_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | |||
355 | int vi_main(int argc, char **argv) | 411 | int vi_main(int argc, char **argv) |
356 | { | 412 | { |
357 | int c; | 413 | int c; |
358 | RESERVE_CONFIG_BUFFER(STATUS_BUFFER, STATUS_BUFFER_LEN); | 414 | |
415 | INIT_G(); | ||
359 | 416 | ||
360 | #if ENABLE_FEATURE_VI_USE_SIGNALS || ENABLE_FEATURE_VI_CRASHME | 417 | #if ENABLE_FEATURE_VI_USE_SIGNALS || ENABLE_FEATURE_VI_CRASHME |
361 | my_pid = getpid(); | 418 | my_pid = getpid(); |
362 | #endif | 419 | #endif |
363 | |||
364 | INIT_G(); | ||
365 | |||
366 | #if ENABLE_FEATURE_VI_CRASHME | 420 | #if ENABLE_FEATURE_VI_CRASHME |
367 | srand((long) my_pid); | 421 | srand((long) my_pid); |
368 | #endif | 422 | #endif |
369 | |||
370 | status_buffer = STATUS_BUFFER; | ||
371 | last_status_cksum = 0; | ||
372 | text = NULL; | ||
373 | |||
374 | #ifdef NO_SUCH_APPLET_YET | 423 | #ifdef NO_SUCH_APPLET_YET |
375 | /* If we aren't "vi", we are "view" */ | 424 | /* If we aren't "vi", we are "view" */ |
376 | if (ENABLE_FEATURE_VI_READONLY && applet_name[2]) { | 425 | if (ENABLE_FEATURE_VI_READONLY && applet_name[2]) { |
@@ -379,9 +428,6 @@ int vi_main(int argc, char **argv) | |||
379 | #endif | 428 | #endif |
380 | 429 | ||
381 | vi_setops = VI_AUTOINDENT | VI_SHOWMATCH | VI_IGNORECASE; | 430 | vi_setops = VI_AUTOINDENT | VI_SHOWMATCH | VI_IGNORECASE; |
382 | #if ENABLE_FEATURE_VI_YANKMARK | ||
383 | memset(reg, 0, sizeof(reg)); // init the yank regs | ||
384 | #endif | ||
385 | #if ENABLE_FEATURE_VI_DOT_CMD || ENABLE_FEATURE_VI_YANKMARK | 431 | #if ENABLE_FEATURE_VI_DOT_CMD || ENABLE_FEATURE_VI_YANKMARK |
386 | modifying_cmds = (char *) "aAcCdDiIJoOpPrRsxX<>~"; // cmds modifying text[] | 432 | modifying_cmds = (char *) "aAcCdDiIJoOpPrRsxX<>~"; // cmds modifying text[] |
387 | #endif | 433 | #endif |
@@ -417,7 +463,6 @@ int vi_main(int argc, char **argv) | |||
417 | case 'H': | 463 | case 'H': |
418 | show_help(); | 464 | show_help(); |
419 | /* fall through */ | 465 | /* fall through */ |
420 | |||
421 | default: | 466 | default: |
422 | bb_show_usage(); | 467 | bb_show_usage(); |
423 | return 1; | 468 | return 1; |
@@ -451,9 +496,7 @@ static int init_text_buffer(char *fn) | |||
451 | 496 | ||
452 | /* allocate/reallocate text buffer */ | 497 | /* allocate/reallocate text buffer */ |
453 | free(text); | 498 | free(text); |
454 | text_size = size * 2; | 499 | text_size = size + 10240; |
455 | if (text_size < 10240) | ||
456 | text_size = 10240; // have a minimum size for new files | ||
457 | screenbegin = dot = end = text = xzalloc(text_size); | 500 | screenbegin = dot = end = text = xzalloc(text_size); |
458 | 501 | ||
459 | if (fn != current_filename) { | 502 | if (fn != current_filename) { |
@@ -479,15 +522,14 @@ static int init_text_buffer(char *fn) | |||
479 | 522 | ||
480 | static void edit_file(char *fn) | 523 | static void edit_file(char *fn) |
481 | { | 524 | { |
525 | #if ENABLE_FEATURE_VI_YANKMARK | ||
526 | #define cur_line edit_file__cur_line | ||
527 | #endif | ||
482 | char c; | 528 | char c; |
483 | int size; | 529 | int size; |
484 | |||
485 | #if ENABLE_FEATURE_VI_USE_SIGNALS | 530 | #if ENABLE_FEATURE_VI_USE_SIGNALS |
486 | int sig; | 531 | int sig; |
487 | #endif | 532 | #endif |
488 | #if ENABLE_FEATURE_VI_YANKMARK | ||
489 | static char *cur_line; | ||
490 | #endif | ||
491 | 533 | ||
492 | editing = 1; // 0 = exit, 1 = one file, 2 = multiple files | 534 | editing = 1; // 0 = exit, 1 = one file, 2 = multiple files |
493 | rawmode(); | 535 | rawmode(); |
@@ -606,6 +648,7 @@ static void edit_file(char *fn) | |||
606 | place_cursor(rows, 0, FALSE); // go to bottom of screen | 648 | place_cursor(rows, 0, FALSE); // go to bottom of screen |
607 | clear_to_eol(); // Erase to end of line | 649 | clear_to_eol(); // Erase to end of line |
608 | cookmode(); | 650 | cookmode(); |
651 | #undef cur_line | ||
609 | } | 652 | } |
610 | 653 | ||
611 | //----- The Colon commands ------------------------------------- | 654 | //----- The Colon commands ------------------------------------- |
@@ -1611,7 +1654,7 @@ static char *char_insert(char * p, char c) // insert the char c at 'p' | |||
1611 | c = get_one_char(); | 1654 | c = get_one_char(); |
1612 | *p = c; | 1655 | *p = c; |
1613 | p++; | 1656 | p++; |
1614 | file_modified++; // has the file been modified | 1657 | file_modified++; |
1615 | } else if (c == 27) { // Is this an ESC? | 1658 | } else if (c == 27) { // Is this an ESC? |
1616 | cmd_mode = 0; | 1659 | cmd_mode = 0; |
1617 | cmdcnt = 0; | 1660 | cmdcnt = 0; |
@@ -1654,12 +1697,9 @@ static char *char_insert(char * p, char c) // insert the char c at 'p' | |||
1654 | static char *stupid_insert(char * p, char c) // stupidly insert the char c at 'p' | 1697 | static char *stupid_insert(char * p, char c) // stupidly insert the char c at 'p' |
1655 | { | 1698 | { |
1656 | p = text_hole_make(p, 1); | 1699 | p = text_hole_make(p, 1); |
1657 | if (p != 0) { | 1700 | *p = c; |
1658 | *p = c; | 1701 | //file_modified++; - done by text_hole_make() |
1659 | file_modified++; // has the file been modified | 1702 | return p + 1; |
1660 | p++; | ||
1661 | } | ||
1662 | return p; | ||
1663 | } | 1703 | } |
1664 | 1704 | ||
1665 | static int find_range(char ** start, char ** stop, char c) | 1705 | static int find_range(char ** start, char ** stop, char c) |
@@ -1842,24 +1882,21 @@ static void showmatching(char *p) | |||
1842 | // open a hole in text[] | 1882 | // open a hole in text[] |
1843 | static char *text_hole_make(char * p, int size) // at "p", make a 'size' byte hole | 1883 | static char *text_hole_make(char * p, int size) // at "p", make a 'size' byte hole |
1844 | { | 1884 | { |
1845 | char *src, *dest; | ||
1846 | int cnt; | ||
1847 | |||
1848 | if (size <= 0) | 1885 | if (size <= 0) |
1849 | goto thm0; | 1886 | return p; |
1850 | src = p; | 1887 | end += size; // adjust the new END |
1851 | dest = p + size; | 1888 | if (end >= (text + text_size)) { |
1852 | cnt = end - src; // the rest of buffer | 1889 | char *new_text; |
1853 | if ( ((end + size) >= (text + text_size)) // TODO: realloc here | 1890 | text_size += end - (text + text_size) + 10240; |
1854 | || memmove(dest, src, cnt) != dest) { | 1891 | new_text = xrealloc(text, text_size); |
1855 | status_line_bold("can't create room for new characters"); | 1892 | screenbegin = new_text + (screenbegin - text); |
1856 | p = NULL; | 1893 | dot = new_text + (dot - text); |
1857 | goto thm0; | 1894 | end = new_text + (end - text); |
1895 | p = new_text + (p - text); | ||
1896 | text = new_text; | ||
1858 | } | 1897 | } |
1859 | memset(p, ' ', size); // clear new hole | 1898 | memset(p, ' ', size); // clear new hole |
1860 | end += size; // adjust the new END | 1899 | file_modified++; |
1861 | file_modified++; // has the file been modified | ||
1862 | thm0: | ||
1863 | return p; | 1900 | return p; |
1864 | } | 1901 | } |
1865 | 1902 | ||
@@ -1885,16 +1922,14 @@ static char *text_hole_delete(char * p, char * q) // delete "p" through "q", inc | |||
1885 | goto thd0; | 1922 | goto thd0; |
1886 | if (src >= end) | 1923 | if (src >= end) |
1887 | goto thd_atend; // just delete the end of the buffer | 1924 | goto thd_atend; // just delete the end of the buffer |
1888 | if (memmove(dest, src, cnt) != dest) { | 1925 | memmove(dest, src, cnt); |
1889 | status_line_bold("can't delete the character"); | ||
1890 | } | ||
1891 | thd_atend: | 1926 | thd_atend: |
1892 | end = end - hole_size; // adjust the new END | 1927 | end = end - hole_size; // adjust the new END |
1893 | if (dest >= end) | 1928 | if (dest >= end) |
1894 | dest = end - 1; // make sure dest in below end-1 | 1929 | dest = end - 1; // make sure dest in below end-1 |
1895 | if (end <= text) | 1930 | if (end <= text) |
1896 | dest = end = text; // keep pointers valid | 1931 | dest = end = text; // keep pointers valid |
1897 | file_modified++; // has the file been modified | 1932 | file_modified++; |
1898 | thd0: | 1933 | thd0: |
1899 | return dest; | 1934 | return dest; |
1900 | } | 1935 | } |
@@ -1973,8 +2008,6 @@ static void show_help(void) | |||
1973 | static void start_new_cmd_q(char c) | 2008 | static void start_new_cmd_q(char c) |
1974 | { | 2009 | { |
1975 | // get buffer for new cmd | 2010 | // get buffer for new cmd |
1976 | if (!last_modifying_cmd) | ||
1977 | last_modifying_cmd = xzalloc(MAX_INPUT_LEN); | ||
1978 | // if there is a current cmd count put it in the buffer first | 2011 | // if there is a current cmd count put it in the buffer first |
1979 | if (cmdcnt > 0) | 2012 | if (cmdcnt > 0) |
1980 | lmc_len = sprintf(last_modifying_cmd, "%d%c", cmdcnt, c); | 2013 | lmc_len = sprintf(last_modifying_cmd, "%d%c", cmdcnt, c); |
@@ -2164,8 +2197,6 @@ static int mysleep(int hund) // sleep for 'h' 1/100 seconds | |||
2164 | return safe_poll(pfd, 1, hund*10) > 0; | 2197 | return safe_poll(pfd, 1, hund*10) > 0; |
2165 | } | 2198 | } |
2166 | 2199 | ||
2167 | static int chars_to_parse; | ||
2168 | |||
2169 | //----- IO Routines -------------------------------------------- | 2200 | //----- IO Routines -------------------------------------------- |
2170 | static char readit(void) // read (maybe cursor) key from stdin | 2201 | static char readit(void) // read (maybe cursor) key from stdin |
2171 | { | 2202 | { |
@@ -2300,13 +2331,11 @@ static char get_one_char(void) | |||
2300 | } else { | 2331 | } else { |
2301 | // adding STDIN chars to q | 2332 | // adding STDIN chars to q |
2302 | c = readit(); // get the users input | 2333 | c = readit(); // get the users input |
2303 | if (last_modifying_cmd != NULL) { | 2334 | if (lmc_len >= MAX_INPUT_LEN - 1) { |
2304 | if (lmc_len >= MAX_INPUT_LEN - 1) { | 2335 | status_line_bold("last_modifying_cmd overrun"); |
2305 | status_line_bold("last_modifying_cmd overrun"); | 2336 | } else { |
2306 | } else { | 2337 | // add new char to q |
2307 | // add new char to q | 2338 | last_modifying_cmd[lmc_len++] = c; |
2308 | last_modifying_cmd[lmc_len++] = c; | ||
2309 | } | ||
2310 | } | 2339 | } |
2311 | } | 2340 | } |
2312 | #else | 2341 | #else |
@@ -2318,13 +2347,12 @@ static char get_one_char(void) | |||
2318 | // Get input line (uses "status line" area) | 2347 | // Get input line (uses "status line" area) |
2319 | static char *get_input_line(const char *prompt) | 2348 | static char *get_input_line(const char *prompt) |
2320 | { | 2349 | { |
2321 | static char *buf; // [MAX_INPUT_LEN] | 2350 | // char [MAX_INPUT_LEN] |
2351 | #define buf get_input_line__buf | ||
2322 | 2352 | ||
2323 | char c; | 2353 | char c; |
2324 | int i; | 2354 | int i; |
2325 | 2355 | ||
2326 | if (!buf) buf = xmalloc(MAX_INPUT_LEN); | ||
2327 | |||
2328 | strcpy(buf, prompt); | 2356 | strcpy(buf, prompt); |
2329 | last_status_cksum = 0; // force status update | 2357 | last_status_cksum = 0; // force status update |
2330 | place_cursor(rows - 1, 0, FALSE); // go to Status line, bottom of screen | 2358 | place_cursor(rows - 1, 0, FALSE); // go to Status line, bottom of screen |
@@ -2350,6 +2378,7 @@ static char *get_input_line(const char *prompt) | |||
2350 | } | 2378 | } |
2351 | refresh(FALSE); | 2379 | refresh(FALSE); |
2352 | return buf; | 2380 | return buf; |
2381 | #undef buf | ||
2353 | } | 2382 | } |
2354 | 2383 | ||
2355 | static int file_size(const char *fn) // what is the byte size of "fn" | 2384 | static int file_size(const char *fn) // what is the byte size of "fn" |
@@ -2451,7 +2480,7 @@ static int file_write(char * fn, char * first, char * last) | |||
2451 | ftruncate(fd, charcnt); | 2480 | ftruncate(fd, charcnt); |
2452 | if (charcnt == cnt) { | 2481 | if (charcnt == cnt) { |
2453 | // good write | 2482 | // good write |
2454 | //file_modified = FALSE; // the file has not been modified | 2483 | //file_modified = FALSE; |
2455 | } else { | 2484 | } else { |
2456 | charcnt = 0; | 2485 | charcnt = 0; |
2457 | } | 2486 | } |
@@ -2701,8 +2730,10 @@ static void not_implemented(const char *s) | |||
2701 | // show file status on status line | 2730 | // show file status on status line |
2702 | static int format_edit_status(void) | 2731 | static int format_edit_status(void) |
2703 | { | 2732 | { |
2704 | static int tot; | ||
2705 | static const char cmd_mode_indicator[] ALIGN1 = "-IR-"; | 2733 | static const char cmd_mode_indicator[] ALIGN1 = "-IR-"; |
2734 | |||
2735 | #define tot format_edit_status__tot | ||
2736 | |||
2706 | int cur, percent, ret, trunc_at; | 2737 | int cur, percent, ret, trunc_at; |
2707 | 2738 | ||
2708 | // file_modified is now a counter rather than a flag. this | 2739 | // file_modified is now a counter rather than a flag. this |
@@ -2753,13 +2784,14 @@ static int format_edit_status(void) | |||
2753 | return ret; /* it all fit */ | 2784 | return ret; /* it all fit */ |
2754 | 2785 | ||
2755 | return trunc_at; /* had to truncate */ | 2786 | return trunc_at; /* had to truncate */ |
2787 | #undef tot | ||
2756 | } | 2788 | } |
2757 | 2789 | ||
2758 | //----- Force refresh of all Lines ----------------------------- | 2790 | //----- Force refresh of all Lines ----------------------------- |
2759 | static void redraw(int full_screen) | 2791 | static void redraw(int full_screen) |
2760 | { | 2792 | { |
2761 | place_cursor(0, 0, FALSE); // put cursor in correct place | 2793 | place_cursor(0, 0, FALSE); // put cursor in correct place |
2762 | clear_to_eos(); // tel terminal to erase display | 2794 | clear_to_eos(); // tell terminal to erase display |
2763 | screen_erase(); // erase the internal screen buffer | 2795 | screen_erase(); // erase the internal screen buffer |
2764 | last_status_cksum = 0; // force status update | 2796 | last_status_cksum = 0; // force status update |
2765 | refresh(full_screen); // this will redraw the entire display | 2797 | refresh(full_screen); // this will redraw the entire display |
@@ -2831,7 +2863,7 @@ static char* format_line(char *src /*, int li*/) | |||
2831 | // | 2863 | // |
2832 | static void refresh(int full_screen) | 2864 | static void refresh(int full_screen) |
2833 | { | 2865 | { |
2834 | static int old_offset; | 2866 | #define old_offset refresh__old_offset |
2835 | 2867 | ||
2836 | int li, changed; | 2868 | int li, changed; |
2837 | char *tp, *sp; // pointer into text[] and screen[] | 2869 | char *tp, *sp; // pointer into text[] and screen[] |
@@ -2919,6 +2951,7 @@ static void refresh(int full_screen) | |||
2919 | place_cursor(crow, ccol, TRUE); | 2951 | place_cursor(crow, ccol, TRUE); |
2920 | 2952 | ||
2921 | old_offset = offset; | 2953 | old_offset = offset; |
2954 | #undef old_offset | ||
2922 | } | 2955 | } |
2923 | 2956 | ||
2924 | //--------------------------------------------------------------------- | 2957 | //--------------------------------------------------------------------- |
@@ -3276,7 +3309,7 @@ static void do_cmd(char c) | |||
3276 | case '.': // .- repeat the last modifying command | 3309 | case '.': // .- repeat the last modifying command |
3277 | // Stuff the last_modifying_cmd back into stdin | 3310 | // Stuff the last_modifying_cmd back into stdin |
3278 | // and let it be re-executed. | 3311 | // and let it be re-executed. |
3279 | if (last_modifying_cmd != NULL && lmc_len > 0) { | 3312 | if (lmc_len > 0) { |
3280 | last_modifying_cmd[lmc_len] = 0; | 3313 | last_modifying_cmd[lmc_len] = 0; |
3281 | ioq = ioq_start = xstrdup(last_modifying_cmd); | 3314 | ioq = ioq_start = xstrdup(last_modifying_cmd); |
3282 | } | 3315 | } |
@@ -3750,7 +3783,7 @@ static void do_cmd(char c) | |||
3750 | c1 = get_one_char(); // get the replacement char | 3783 | c1 = get_one_char(); // get the replacement char |
3751 | if (*dot != '\n') { | 3784 | if (*dot != '\n') { |
3752 | *dot = c1; | 3785 | *dot = c1; |
3753 | file_modified++; // has the file been modified | 3786 | file_modified++; |
3754 | } | 3787 | } |
3755 | end_cmd_q(); // stop adding to q | 3788 | end_cmd_q(); // stop adding to q |
3756 | break; | 3789 | break; |
@@ -3795,10 +3828,10 @@ static void do_cmd(char c) | |||
3795 | } // repeat cnt | 3828 | } // repeat cnt |
3796 | if (islower(*dot)) { | 3829 | if (islower(*dot)) { |
3797 | *dot = toupper(*dot); | 3830 | *dot = toupper(*dot); |
3798 | file_modified++; // has the file been modified | 3831 | file_modified++; |
3799 | } else if (isupper(*dot)) { | 3832 | } else if (isupper(*dot)) { |
3800 | *dot = tolower(*dot); | 3833 | *dot = tolower(*dot); |
3801 | file_modified++; // has the file been modified | 3834 | file_modified++; |
3802 | } | 3835 | } |
3803 | dot_right(); | 3836 | dot_right(); |
3804 | end_cmd_q(); // stop adding to q | 3837 | end_cmd_q(); // stop adding to q |