svn commit: trunk/busybox/miscutils

vda at busybox.net vda at busybox.net
Fri Oct 24 10:42:21 UTC 2008


Author: vda
Date: 2008-10-24 03:42:21 -0700 (Fri, 24 Oct 2008)
New Revision: 23776

Log:
less: experimental code to enable wrap/no-wrap
 and adapting to resized xterm windows. disabled for now.



Modified:
   trunk/busybox/miscutils/less.c


Changeset:
Modified: trunk/busybox/miscutils/less.c
===================================================================
--- trunk/busybox/miscutils/less.c	2008-10-24 08:34:31 UTC (rev 23775)
+++ trunk/busybox/miscutils/less.c	2008-10-24 10:42:21 UTC (rev 23776)
@@ -28,6 +28,9 @@
 #include "xregex.h"
 #endif
 
+/* In progress */
+#define ENABLE_FEATURE_LESS_REWRAP 0
+
 /* FIXME: currently doesn't work right */
 #undef ENABLE_FEATURE_LESS_FLAGCS
 #define ENABLE_FEATURE_LESS_FLAGCS 0
@@ -81,6 +84,7 @@
 	FLAG_TILDE = 1 << 4,
 	FLAG_I = 1 << 5,
 /* hijack command line options variable for internal state vars */
+	LESS_STATE_NO_WRAP = 1 << 14,
 	LESS_STATE_MATCH_BACKWARDS = 1 << 15,
 };
 
@@ -214,6 +218,88 @@
 	exit(code);
 }
 
+#if ENABLE_FEATURE_LESS_REWRAP
+static void re_wrap(void)
+{
+	int w = width;
+	int rem;
+	int src_idx;
+	int dst_idx;
+	int new_cur_fline = 0;
+	uint32_t lineno;
+	char linebuf[w + 1];
+	const char **old_flines = flines;
+	const char *s;
+	char **new_flines = NULL;
+	char *d;
+
+	if (option_mask32 & FLAG_N)
+		w -= 8;
+
+	src_idx = 0;
+	dst_idx = 0;
+	s = old_flines[0];
+	lineno = LINENO(s);
+	d = linebuf;
+	rem = w;
+	while (1) {
+		*d = *s;
+		if (*d != '\0') {
+			s++;
+			d++;
+			rem--;
+			if (rem == 0) {
+				int sz;
+				/* new line is full, create next one */
+				*d = '\0';
+ next_new:
+				sz = (d - linebuf) + 1; /* + 1: NUL */
+				d = ((char*)xmalloc(sz + 4)) + 4;
+				LINENO(d) = lineno;
+				memcpy(d, linebuf, sz);
+				new_flines = xrealloc_vector(new_flines, 8, dst_idx);
+				new_flines[dst_idx] = d;
+				dst_idx++;
+				if (rem) {
+					/* did we come here thru "goto next_new"? */
+					if (src_idx > max_fline)
+						break;
+					lineno = LINENO(s);
+				}
+				d = linebuf;
+				rem = w;
+			}
+			continue;
+		}
+		/* *d == NUL: old line ended, go to next old one */
+		free(MEMPTR(old_flines[src_idx]));
+		/* btw, convert cur_fline... */
+		if (cur_fline == src_idx) {
+			new_cur_fline = dst_idx;
+		}
+		src_idx++;
+		/* no more lines? finish last new line (and exit the loop) */
+		if (src_idx > max_fline) {
+			goto next_new;
+		}
+		s = old_flines[src_idx];
+		if (lineno != LINENO(s)) {
+			/* this is not a continuation line!
+			 * create next _new_ line too */
+			goto next_new;
+		}
+	}
+
+	free(old_flines);
+	flines = (const char **)new_flines;
+
+	max_fline = dst_idx - 1;
+	linepos = 0; // XXX
+	cur_fline = new_cur_fline;
+	/* max_lineno is screen-size independent */
+}
+#endif
+
 #if ENABLE_FEATURE_LESS_REGEXP
 static void fill_match_lines(unsigned pos);
 #else
@@ -502,7 +588,7 @@
 		}
 		/* Width of 7 preserves tab spacing in the text */
 		fmt = "%7u ";
-		n = LINENO(line);
+		n = LINENO(line) + 1;
 		if (n > 9999999) {
 			n %= 10000000;
 			fmt = "%07u ";
@@ -633,8 +719,37 @@
 	status_print();
 }
 
+#if ENABLE_FEATURE_LESS_REWRAP
 static void buffer_fill_and_print(void)
 {
+	unsigned i = 0;
+	int fpos = cur_fline + i;
+
+	if (option_mask32 & LESS_STATE_NO_WRAP) {
+		/* Go back to the beginning of this line */
+		while (fpos && LINENO(flines[fpos]) == LINENO(flines[fpos-1]))
+			fpos--;
+	}
+
+	while (i <= max_displayed_line && fpos <= max_fline) {
+		int lineno = LINENO(flines[fpos]);
+		buffer[i] = flines[fpos];
+		i++;
+		do {
+			fpos++;
+		} while ((fpos <= max_fline)
+		      && (option_mask32 & LESS_STATE_NO_WRAP)
+		      && lineno == LINENO(flines[fpos])
+		);
+	}
+	for (; i <= max_displayed_line; i++) {
+		buffer[i] = empty_line_marker;
+	}
+	buffer_print();
+}
+#else
+static void buffer_fill_and_print(void)
+{
 	unsigned i;
 	for (i = 0; i <= max_displayed_line && cur_fline + i <= max_fline; i++) {
 		buffer[i] = flines[cur_fline + i];
@@ -644,6 +759,7 @@
 	}
 	buffer_print();
 }
+#endif
 
 /* Move the buffer up and down in the file in order to scroll */
 static void buffer_down(int nlines)
@@ -1371,6 +1487,25 @@
 	case ':':
 		colon_process();
 		break;
+#if ENABLE_FEATURE_LESS_REWRAP
+	case '*':
+		option_mask32 ^= FLAG_N;
+		get_terminal_width_height(kbd_fd, &width, &max_displayed_line);
+		if (width < 20) /* 20: two tabstops + 4 */
+			width = 20;
+		if (max_displayed_line < 3)
+			max_displayed_line = 3;
+		max_displayed_line -= 2;
+		free(buffer);
+		buffer = xmalloc((max_displayed_line+1) * sizeof(char *));
+		re_wrap();
+		buffer_fill_and_print();
+		break;
+	case '&':
+		option_mask32 ^= LESS_STATE_NO_WRAP;
+		buffer_fill_and_print();
+		break;
+#endif
 	}
 
 	if (isdigit(keypress))




More information about the busybox-cvs mailing list