diff options
author | Denis Vlasenko <vda.linux@googlemail.com> | 2008-10-24 10:42:21 +0000 |
---|---|---|
committer | Denis Vlasenko <vda.linux@googlemail.com> | 2008-10-24 10:42:21 +0000 |
commit | d908395eae984059785b8a46c97537e1ebad0495 (patch) | |
tree | 1050c057f5c66a4f4ade00a07dfa81fbfed9c763 | |
parent | 8f39b72aba3fbb360ea46c6124c9ac90e54372f6 (diff) | |
download | busybox-w32-d908395eae984059785b8a46c97537e1ebad0495.tar.gz busybox-w32-d908395eae984059785b8a46c97537e1ebad0495.tar.bz2 busybox-w32-d908395eae984059785b8a46c97537e1ebad0495.zip |
less: experimental code to enable wrap/no-wrap
and adapting to resized xterm windows. disabled for now.
-rw-r--r-- | miscutils/less.c | 137 |
1 files changed, 136 insertions, 1 deletions
diff --git a/miscutils/less.c b/miscutils/less.c index 049814319..c66788007 100644 --- a/miscutils/less.c +++ b/miscutils/less.c | |||
@@ -28,6 +28,9 @@ | |||
28 | #include "xregex.h" | 28 | #include "xregex.h" |
29 | #endif | 29 | #endif |
30 | 30 | ||
31 | /* In progress */ | ||
32 | #define ENABLE_FEATURE_LESS_REWRAP 0 | ||
33 | |||
31 | /* FIXME: currently doesn't work right */ | 34 | /* FIXME: currently doesn't work right */ |
32 | #undef ENABLE_FEATURE_LESS_FLAGCS | 35 | #undef ENABLE_FEATURE_LESS_FLAGCS |
33 | #define ENABLE_FEATURE_LESS_FLAGCS 0 | 36 | #define ENABLE_FEATURE_LESS_FLAGCS 0 |
@@ -81,6 +84,7 @@ enum { | |||
81 | FLAG_TILDE = 1 << 4, | 84 | FLAG_TILDE = 1 << 4, |
82 | FLAG_I = 1 << 5, | 85 | FLAG_I = 1 << 5, |
83 | /* hijack command line options variable for internal state vars */ | 86 | /* hijack command line options variable for internal state vars */ |
87 | LESS_STATE_NO_WRAP = 1 << 14, | ||
84 | LESS_STATE_MATCH_BACKWARDS = 1 << 15, | 88 | LESS_STATE_MATCH_BACKWARDS = 1 << 15, |
85 | }; | 89 | }; |
86 | 90 | ||
@@ -214,6 +218,88 @@ static void less_exit(int code) | |||
214 | exit(code); | 218 | exit(code); |
215 | } | 219 | } |
216 | 220 | ||
221 | #if ENABLE_FEATURE_LESS_REWRAP | ||
222 | static void re_wrap(void) | ||
223 | { | ||
224 | int w = width; | ||
225 | int rem; | ||
226 | int src_idx; | ||
227 | int dst_idx; | ||
228 | int new_cur_fline = 0; | ||
229 | uint32_t lineno; | ||
230 | char linebuf[w + 1]; | ||
231 | const char **old_flines = flines; | ||
232 | const char *s; | ||
233 | char **new_flines = NULL; | ||
234 | char *d; | ||
235 | |||
236 | if (option_mask32 & FLAG_N) | ||
237 | w -= 8; | ||
238 | |||
239 | src_idx = 0; | ||
240 | dst_idx = 0; | ||
241 | s = old_flines[0]; | ||
242 | lineno = LINENO(s); | ||
243 | d = linebuf; | ||
244 | rem = w; | ||
245 | while (1) { | ||
246 | *d = *s; | ||
247 | if (*d != '\0') { | ||
248 | s++; | ||
249 | d++; | ||
250 | rem--; | ||
251 | if (rem == 0) { | ||
252 | int sz; | ||
253 | /* new line is full, create next one */ | ||
254 | *d = '\0'; | ||
255 | next_new: | ||
256 | sz = (d - linebuf) + 1; /* + 1: NUL */ | ||
257 | d = ((char*)xmalloc(sz + 4)) + 4; | ||
258 | LINENO(d) = lineno; | ||
259 | memcpy(d, linebuf, sz); | ||
260 | new_flines = xrealloc_vector(new_flines, 8, dst_idx); | ||
261 | new_flines[dst_idx] = d; | ||
262 | dst_idx++; | ||
263 | if (rem) { | ||
264 | /* did we come here thru "goto next_new"? */ | ||
265 | if (src_idx > max_fline) | ||
266 | break; | ||
267 | lineno = LINENO(s); | ||
268 | } | ||
269 | d = linebuf; | ||
270 | rem = w; | ||
271 | } | ||
272 | continue; | ||
273 | } | ||
274 | /* *d == NUL: old line ended, go to next old one */ | ||
275 | free(MEMPTR(old_flines[src_idx])); | ||
276 | /* btw, convert cur_fline... */ | ||
277 | if (cur_fline == src_idx) { | ||
278 | new_cur_fline = dst_idx; | ||
279 | } | ||
280 | src_idx++; | ||
281 | /* no more lines? finish last new line (and exit the loop) */ | ||
282 | if (src_idx > max_fline) { | ||
283 | goto next_new; | ||
284 | } | ||
285 | s = old_flines[src_idx]; | ||
286 | if (lineno != LINENO(s)) { | ||
287 | /* this is not a continuation line! | ||
288 | * create next _new_ line too */ | ||
289 | goto next_new; | ||
290 | } | ||
291 | } | ||
292 | |||
293 | free(old_flines); | ||
294 | flines = (const char **)new_flines; | ||
295 | |||
296 | max_fline = dst_idx - 1; | ||
297 | linepos = 0; // XXX | ||
298 | cur_fline = new_cur_fline; | ||
299 | /* max_lineno is screen-size independent */ | ||
300 | } | ||
301 | #endif | ||
302 | |||
217 | #if ENABLE_FEATURE_LESS_REGEXP | 303 | #if ENABLE_FEATURE_LESS_REGEXP |
218 | static void fill_match_lines(unsigned pos); | 304 | static void fill_match_lines(unsigned pos); |
219 | #else | 305 | #else |
@@ -502,7 +588,7 @@ static void lineno_str(char *nbuf9, const char *line) | |||
502 | } | 588 | } |
503 | /* Width of 7 preserves tab spacing in the text */ | 589 | /* Width of 7 preserves tab spacing in the text */ |
504 | fmt = "%7u "; | 590 | fmt = "%7u "; |
505 | n = LINENO(line); | 591 | n = LINENO(line) + 1; |
506 | if (n > 9999999) { | 592 | if (n > 9999999) { |
507 | n %= 10000000; | 593 | n %= 10000000; |
508 | fmt = "%07u "; | 594 | fmt = "%07u "; |
@@ -633,6 +719,35 @@ static void buffer_print(void) | |||
633 | status_print(); | 719 | status_print(); |
634 | } | 720 | } |
635 | 721 | ||
722 | #if ENABLE_FEATURE_LESS_REWRAP | ||
723 | static void buffer_fill_and_print(void) | ||
724 | { | ||
725 | unsigned i = 0; | ||
726 | int fpos = cur_fline + i; | ||
727 | |||
728 | if (option_mask32 & LESS_STATE_NO_WRAP) { | ||
729 | /* Go back to the beginning of this line */ | ||
730 | while (fpos && LINENO(flines[fpos]) == LINENO(flines[fpos-1])) | ||
731 | fpos--; | ||
732 | } | ||
733 | |||
734 | while (i <= max_displayed_line && fpos <= max_fline) { | ||
735 | int lineno = LINENO(flines[fpos]); | ||
736 | buffer[i] = flines[fpos]; | ||
737 | i++; | ||
738 | do { | ||
739 | fpos++; | ||
740 | } while ((fpos <= max_fline) | ||
741 | && (option_mask32 & LESS_STATE_NO_WRAP) | ||
742 | && lineno == LINENO(flines[fpos]) | ||
743 | ); | ||
744 | } | ||
745 | for (; i <= max_displayed_line; i++) { | ||
746 | buffer[i] = empty_line_marker; | ||
747 | } | ||
748 | buffer_print(); | ||
749 | } | ||
750 | #else | ||
636 | static void buffer_fill_and_print(void) | 751 | static void buffer_fill_and_print(void) |
637 | { | 752 | { |
638 | unsigned i; | 753 | unsigned i; |
@@ -644,6 +759,7 @@ static void buffer_fill_and_print(void) | |||
644 | } | 759 | } |
645 | buffer_print(); | 760 | buffer_print(); |
646 | } | 761 | } |
762 | #endif | ||
647 | 763 | ||
648 | /* Move the buffer up and down in the file in order to scroll */ | 764 | /* Move the buffer up and down in the file in order to scroll */ |
649 | static void buffer_down(int nlines) | 765 | static void buffer_down(int nlines) |
@@ -1371,6 +1487,25 @@ static void keypress_process(int keypress) | |||
1371 | case ':': | 1487 | case ':': |
1372 | colon_process(); | 1488 | colon_process(); |
1373 | break; | 1489 | break; |
1490 | #if ENABLE_FEATURE_LESS_REWRAP | ||
1491 | case '*': | ||
1492 | option_mask32 ^= FLAG_N; | ||
1493 | get_terminal_width_height(kbd_fd, &width, &max_displayed_line); | ||
1494 | if (width < 20) /* 20: two tabstops + 4 */ | ||
1495 | width = 20; | ||
1496 | if (max_displayed_line < 3) | ||
1497 | max_displayed_line = 3; | ||
1498 | max_displayed_line -= 2; | ||
1499 | free(buffer); | ||
1500 | buffer = xmalloc((max_displayed_line+1) * sizeof(char *)); | ||
1501 | re_wrap(); | ||
1502 | buffer_fill_and_print(); | ||
1503 | break; | ||
1504 | case '&': | ||
1505 | option_mask32 ^= LESS_STATE_NO_WRAP; | ||
1506 | buffer_fill_and_print(); | ||
1507 | break; | ||
1508 | #endif | ||
1374 | } | 1509 | } |
1375 | 1510 | ||
1376 | if (isdigit(keypress)) | 1511 | if (isdigit(keypress)) |