aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2008-10-24 10:42:21 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2008-10-24 10:42:21 +0000
commitd908395eae984059785b8a46c97537e1ebad0495 (patch)
tree1050c057f5c66a4f4ade00a07dfa81fbfed9c763
parent8f39b72aba3fbb360ea46c6124c9ac90e54372f6 (diff)
downloadbusybox-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.c137
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
222static 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
218static void fill_match_lines(unsigned pos); 304static 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
723static 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
636static void buffer_fill_and_print(void) 751static 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 */
649static void buffer_down(int nlines) 765static 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))