[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#197990: Explanation and solution of the more search bug



Hi folks,

Regarding the problems with searching in manpages when more is the pager:

I've looked into this bug a bit, and the explanation is rather
straightforward. I've also attached a patch to fix this problem.

Generate the manpage:
	man gcc > /tmp/gcc.man

The actual manpage text generated is as follows (start of line skipped):

	-m^Hmp^Hpo^How^Hwe^Her^Hr

where ^H is the backspace-character. This is done to tell the pager that
the text should be underlined and/or bold.

'more' does not consider ^H as a special character; so to find the above 
string, you have to use a regex like this
	PAGER=more man gcc
	/m..p..o..w..e..r

Less, on the other hand, has special processing for the ^H:
	if (cvt_ops & CVT_BS)
	{
		while (line[0] == '\b' && line[1] != '\0')
		{
			/*
			 * Found a backspace.  The file position moves
			 * forward by 2 relative to the processed line
			 * which was searched in hilite_line.
			 */
			npos += 2;
			line += 2;
		}
	}

To surpress this special behaviour, use the -u flag and you have to search
using the many-dots regex as above:
	PAGER="less -u" man gcc 
	/m..p..o..w..e..r
 
Now, more does understand how to display the underlines (you can even switch
that off with the -u argument, like in less), but it does not understand
how to do searching. Interestingly enough, the pg utility, which is in the
same source directory, does understand this.

I have written a patch (attached) which fixes this behaviour. I am also
sending this upstream. The patch is against debian util-linux-2.12-3;
it should apply cleanly against a vanilla util-linux-2.12, with some line
offsets. I would be grateful is the maintainer of more would take a good
look at this too; I think I have it correct, but the sourcecode is somewhat
cryptic at places.

Have fun,
  Frodo

-- 
Frodo Looijaard <frodol@dds.nl>  PGP key and more: http://huizen.dds.nl/~frodol
Defenestration n. (formal or joc.):
  The act of removing Windows from your computer in disgust, usually followed
  by the installation of Linux or some other Unix-like operating system.
--- util-linux-2.12/text-utils/more.c.orig	2003-10-15 21:56:02.000000000 +0200
+++ util-linux-2.12/text-utils/more.c	2003-10-15 21:56:06.000000000 +0200
@@ -1629,4 +1629,5 @@
     int saveln, rv;
     char *s;
+    int i,j;
 
     context.line = saveln = Currline;
@@ -1641,4 +1642,15 @@
 	rdline (file);
 	lncount++;
+
+	/* Remove backspaces */
+	for (i=0,j=0; Line[i] != 0; i++,j++) {
+		if (Line[i] == '\b') {
+			j-=2;
+			continue;
+		}
+		Line[j]=Line[i];
+	}
+	Line[j] = 0;
+
 	if ((rv = re_exec (Line)) == 1) {
 		if (--n == 0) {
@@ -1672,4 +1684,9 @@
 				doclear ();
 			}
+
+			/* Reread the line to restore backspaces! */
+			Fseek(file,line1);
+			rdline (file);
+
 			pr (Line);
 			putchar ('\n');

Reply to: