svn commit: trunk/busybox/miscutils

vda at busybox.net vda at busybox.net
Thu Oct 23 22:02:30 UTC 2008


Author: vda
Date: 2008-10-23 15:02:30 -0700 (Thu, 23 Oct 2008)
New Revision: 23774

Log:
less: more sane way of line numbering. Prepares for
 wrap/unwrap and line numbers to be toggleable.



Modified:
   trunk/busybox/miscutils/less.c


Changeset:
Modified: trunk/busybox/miscutils/less.c
===================================================================
--- trunk/busybox/miscutils/less.c	2008-10-23 18:54:10 UTC (rev 23773)
+++ trunk/busybox/miscutils/less.c	2008-10-23 22:02:30 UTC (rev 23774)
@@ -166,6 +166,14 @@
 	USE_FEATURE_LESS_REGEXP(wanted_match = -1;) \
 } while (0)
 
+/* flines[] are lines read from stdin, each in malloc'ed buffer.
+ * Line numbers are stored as uint32_t prepended to each line.
+ * Pointer is adjusted so that flines[i] points directly past
+ * line number. Accesor: */
+#define MEMPTR(p) ((char*)(p) - 4)
+#define LINENO(p) (*(uint32_t*)((p) - 4))
+
+
 /* Reset terminal input to normal */
 static void set_tty_cooked(void)
 {
@@ -252,15 +260,13 @@
 
  USE_FEATURE_LESS_REGEXP(again0:)
 
-	p = current_line = xmalloc(w);
+	p = current_line = ((char*)xmalloc(w + 4)) + 4;
 	max_fline += last_terminated;
 	if (!last_terminated) {
 		const char *cp = flines[max_fline];
-		if (option_mask32 & FLAG_N)
-			cp += 8;
-		strcpy(current_line, cp);
+		strcpy(p, cp);
 		p += strlen(current_line);
-		free((char*)flines[max_fline]);
+		free(MEMPTR(flines[max_fline]));
 		/* linepos is still valid from previous read_lines() */
 	} else {
 		linepos = 0;
@@ -324,17 +330,12 @@
  reached_eof:
 		last_terminated = terminated;
 		flines = xrealloc_vector(flines, 8, max_fline);
-		if (option_mask32 & FLAG_N) {
-			/* Width of 7 preserves tab spacing in the text */
-			flines[max_fline] = xasprintf(
-				(max_lineno <= 9999999) ? "%7u %s" : "%07u %s",
-				max_lineno % 10000000, current_line);
-			free(current_line);
-			if (terminated)
-				max_lineno++;
-		} else {
-			flines[max_fline] = xrealloc(current_line, strlen(current_line) + 1);
-		}
+
+		flines[max_fline] = (char*)xrealloc(MEMPTR(current_line), strlen(current_line) + 1 + 4) + 4;
+		LINENO(flines[max_fline]) = max_lineno;
+		if (terminated)
+			max_lineno++;
+
 		if (max_fline >= MAXLINES) {
 			eof_error = 0; /* Pretend we saw EOF */
 			break;
@@ -380,7 +381,7 @@
 #endif
 		}
 		max_fline++;
-		current_line = xmalloc(w);
+		current_line = ((char*)xmalloc(w + 4)) + 4;
 		p = current_line;
 		linepos = 0;
 	} /* end of "read lines until we reach cur_fline" loop */
@@ -487,6 +488,30 @@
 	"\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x40\x4b\x4c\x4d\x4e\x4f"
 	"\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f";
 
+static void lineno_str(char *nbuf9, const char *line)
+{
+	nbuf9[0] = '\0';
+	if (option_mask32 & FLAG_N) {
+		const char *fmt;
+		unsigned n;
+
+		if (line == empty_line_marker) {
+			memset(nbuf9, ' ', 8);
+			nbuf9[8] = '\0';
+			return;
+		}
+		/* Width of 7 preserves tab spacing in the text */
+		fmt = "%7u ";
+		n = LINENO(line);
+		if (n > 9999999) {
+			n %= 10000000;
+			fmt = "%07u ";
+		}
+		sprintf(nbuf9, fmt, n);
+	}
+}
+
+
 #if ENABLE_FEATURE_LESS_REGEXP
 static void print_found(const char *line)
 {
@@ -496,6 +521,7 @@
 	regmatch_t match_structs;
 
 	char buf[width];
+	char nbuf9[9];
 	const char *str = line;
 	char *p = buf;
 	size_t n;
@@ -532,7 +558,8 @@
 				match_structs.rm_so, str,
 				match_structs.rm_eo - match_structs.rm_so,
 						str + match_structs.rm_so);
-		free(growline); growline = new;
+		free(growline);
+		growline = new;
 		str += match_structs.rm_eo;
 		line += match_structs.rm_eo;
 		eflags = REG_NOTBOL;
@@ -544,11 +571,12 @@
 			match_status = 1;
 	}
 
+	lineno_str(nbuf9, line);
 	if (!growline) {
-		printf(CLEAR_2_EOL"%s\n", str);
+		printf(CLEAR_2_EOL"%s%s\n", nbuf9, str);
 		return;
 	}
-	printf(CLEAR_2_EOL"%s%s\n", growline, str);
+	printf(CLEAR_2_EOL"%s%s%s\n", nbuf9, growline, str);
 	free(growline);
 }
 #else
@@ -558,10 +586,13 @@
 static void print_ascii(const char *str)
 {
 	char buf[width];
+	char nbuf9[9];
 	char *p;
 	size_t n;
 
-	printf(CLEAR_2_EOL);
+	lineno_str(nbuf9, str);
+	printf(CLEAR_2_EOL"%s", nbuf9);
+
 	while (*str) {
 		n = strcspn(str, controls);
 		if (n) {
@@ -670,7 +701,7 @@
 
 	if (flines) {
 		for (i = 0; i <= max_fline; i++)
-			free((void*)(flines[i]));
+			free(MEMPTR(flines[i]));
 		free(flines);
 		flines = NULL;
 	}




More information about the busybox-cvs mailing list