adding feature to LESS V5

Alexander Dupuy dupuy at douglass.columbia.edu
Mon Sep 26 08:59:16 AEST 1988


In my last set of patches, I inadvertently included two copies of the patch for
filename globbing.  This may have produced complaints from patch about reversed
patches.  You probably knew enough to ignore that..

As I promised, here are the rest of my less patches.  If you have a recent
version of patch, you can just feed patch the entire article.  Otherwise,
unshar it, and feed patch the pieces which are relevant.  There's a brief
description at the beginning of each one.

@alex

: This is a shar archive.  Extract with sh, not csh.
: The rest of this file will extract: 
:
:	PATCH.7
:	PATCH.8
:	PATCH.9
:
echo x - PATCH.7
sed 's/^X//' > PATCH.7 << '//go.sysin dd *'
XIt is often the case that one wants to look at a typescript (from the script(1)
Xcommand, for example) where there are trailing carriage returns at the end of
Xeach line.  Less frequently, one wants to look at a document which has been
Xformatted for a printer using CR rather than BS to underline a whole line.
X
XThis patch deals with this by creating a new option: -o/O (for overstrike),
Xwhich parallels the -u/U option that controls the BS mode.  The default is to
Xignore CRs at ends of lines, and to print ^M elsewhere.  With -o, CRs are
Xalways output as is (the behavior of more), and with -O, they are always output
Xas ^M (less' current behavior).
X
X*** /tmp/,RCSt1a04332	Sun Sep 25 02:57:20 1988
X--- less.h	Sun Sep 25 02:56:47 1988
X***************
X*** 58,63 ****
X--- 58,68 ----
X  #define	BS_NORMAL	1	/* \b treated as normal char; actually output */
X  #define	BS_CONTROL	2	/* \b treated as control char; prints as ^H */
X  
X+ /* How should we handle carriage returns? */
X+ #define	CR_SPECIAL	0	/* Ignore at end of line, ^M elsewhere */
X+ #define	CR_NORMAL	1	/* \r treated as normal char; actually output */
X+ #define	CR_CONTROL	2	/* \r treated as control char; prints as ^H */
X+ 
X  /* Special chars used to tell put_line() to do something special */
X  #define	UL_CHAR		(unsigned) 0201	/* Enter underline mode */
X  #define	UE_CHAR		(unsigned) 0202	/* Exit underline mode */
X*** /tmp/,RCSt1a04332	Sun Sep 25 02:57:21 1988
X--- less.nro	Sun Sep 25 02:56:50 1988
X***************
X*** 2,8 ****
X  .SH NAME
X  less \- opposite of more
X  .SH SYNOPSIS
X! .B "less [-[+]aABcCdeEimMnqQuUsw] [-b\fIN\fB] [-h\fIN\fB] [-x\fIN\fB] [-[z]\fIN\fB]"
X  .br
X  .B "     [-P[mM=]\fIstring\fB] [-[lL]\fIlogfile\fB] [+\fIcmd\fB]"
X  .br
X--- 2,8 ----
X  .SH NAME
X  less \- opposite of more
X  .SH SYNOPSIS
X! .B "less [-[+]aABcCdeEimMnoOqQuUsw] [-b\fIN\fB] [-h\fIN\fB] [-x\fIN\fB] [-[z]\fIN\fB]"
X  .br
X  .B "     [-P[mM=]\fIstring\fB] [-[lL]\fIlogfile\fB] [+\fIcmd\fB]"
X  .br
X***************
X*** 343,348 ****
X--- 343,359 ----
X  Using line numbers means: the line number will be displayed in the verbose
X  prompt and in the = command,
X  and the v command will pass the current line number to the editor.
X+ .IP -o
X+ If the -o option is given, 
X+ carriage returns are treated as printable characters;
X+ that is, they are sent to the terminal when they appear in the input.
X+ .IP -O
X+ If the -O option is given,
X+ carriage returns are printed as the two character sequence "^M".
X+ .sp
X+ If neither -o nor -O is given,
X+ carriage returns at the end of a line are ignored, and
X+ carriage returns elsewhere are printed as the two character sequence "^M".
X  .IP -P
X  The -P option provides a way to tailor the three prompt
X  styles to your own preference.
X*** /tmp/,RCSt1a04332	Sun Sep 25 02:57:22 1988
X--- line.c	Sun Sep 25 02:56:53 1988
X***************
X*** 47,56 ****
X--- 47,66 ----
X  #define	LN_BO_X		5	/* In boldface, got char, need \b */
X  #define	LN_BO_XB	6	/* In boldface, got char & \b, need same char */
X  
X+ /*
X+  * An extremely simple state machine takes care of carriage returns
X+  * when in CR_SPECIAL mode.  We put carriage returns into the line buffer,
X+  * and backpatch them if something else comes in before we start a new line.
X+  */
X+ static int cr_seen;		/* Was the last character a carriage return? */
X+ #define CR_NOTSEEN	0
X+ #define CR_SEEN		1
X+ 
X  public char *line;		/* Pointer to the current line.
X  				   Usually points to linebuf. */
X  
X  extern int bs_mode;
X+ extern int cr_mode;
X  extern int tabstop;
X  extern int bo_width, be_width;
X  extern int ul_width, ue_width;
X***************
X*** 64,69 ****
X--- 74,80 ----
X  {
X  	line = curr = linebuf;
X  	ln_state = LN_NORMAL;
X+ 	cr_seen = CR_NOTSEEN;
X  	column = 0;
X  }
X  
X***************
X*** 108,113 ****
X--- 119,125 ----
X  			break;
X  		}
X  		ln_state = LN_NORMAL;
X+ 		cr_seen = CR_NOTSEEN;
X  		*curr = '\0';
X  		return (0);
X  	}
X***************
X*** 122,127 ****
X--- 134,165 ----
X  		 */
X  		return (1);
X  
X+ 	if (cr_mode == CR_SPECIAL)
X+ 	{
X+ 		if (cr_seen == CR_SEEN)
X+ 		{
X+ 			/*
X+ 			 * Multiple carriage returns can be treated as one
X+ 			 */
X+ 			if (c == '\r')
X+ 				return (0);
X+ 			/*
X+ 			 * Patch the old carriage return to display as "^M"
X+ 			 */
X+ 			cr_seen = CR_NOTSEEN;
X+ 			curr[-1] = ('M' | 0200);
X+ 		} else if (c == '\r')
X+ 		{
X+ 			/*
X+ 			 * Leave a carriage return in the buffer for now
X+ 			 */
X+ 			NEW_COLUMN(column+2);
X+ 			cr_seen = CR_SEEN;
X+ 			*curr++ = '\r';
X+ 			return (0);
X+ 		}
X+ 	}
X+ 	
X  	if (bs_mode == BS_SPECIAL)
X  	{
X  		/*
X***************
X*** 357,362 ****
X--- 395,420 ----
X  			 */
X  			column--;
X  			*curr++ = '\b';
X+ 		}
X+ 		return (0);
X+ 	} 
X+ 
X+ 	if (c == '\r')
X+ 	{
X+ 		if (cr_mode == CR_CONTROL)
X+ 		{
X+ 			/*
X+ 			 * Treat carriage return as control char: output "^M".
X+ 			 */
X+ 			NEW_COLUMN(column+2);
X+ 			*curr++ = ('M' | 0200);
X+ 		} else
X+ 		{
X+ 			/*
X+ 			 * Output a real carriage return
X+ 			 */
X+ 			column = 0;
X+ 			*curr++ = '\r';
X  		}
X  		return (0);
X  	} 
X*** /tmp/,RCSt1a04332	Sun Sep 25 02:57:23 1988
X--- option.c	Sun Sep 25 02:56:55 1988
X***************
X*** 31,36 ****
X--- 31,37 ----
X  				   (alternative is scroll from bottom) */
X  public int pr_type;		/* Type of prompt (short, medium, long) */
X  public int bs_mode;		/* How to process backspaces */
X+ public int cr_mode;		/* How to process carriage returns */
X  public int know_dumb;		/* Don't complain about dumb terminals */
X  public int quit_at_eof;		/* Quit after hitting end of file twice */
X  public int squeeze;		/* Squeeze multiple blank lines into one */
X***************
X*** 125,130 ****
X--- 126,137 ----
X  		{ "Don't use line numbers",
X  		  "Use line numbers",
X  		  NULL
X+ 		}
X+ 	},
X+ 	{ 'o', TRIPLE|REPAINT, 0, &cr_mode,
X+ 		{ "Ignore CR at end of line, print as ^M elsewhere",
X+ 		  "Carriage Returns cause overstrike",
X+ 		  "Carriage Returns print as ^M"
X  		}
X  	},
X  	{ 'q', TRIPLE, 0, &quiet,
X*** /tmp/,RCSt1a04332	Sun Sep 25 02:57:24 1988
X--- output.c	Sun Sep 25 02:56:58 1988
X***************
X*** 73,78 ****
X--- 73,82 ----
X  			putbs();
X  			column--;
X  			break;
X+ 		case '\r':
X+ 			putchr('\r');
X+ 			column = 0;
X+ 			break;
X  		default:
X  			if (c & 0200)
X  			{
//go.sysin dd *
echo x - PATCH.8
sed 's/^X//' > PATCH.8 << '//go.sysin dd *'
XWhile "Can't take input from a terminal" is a perfectly reasonable and correct
Xerror message, it is not the most illuminating when you type "less" and have
Xno idea what sorts of arguments it expects.  This patch modifies the behavior
Xof less so that it prints a more conventional usage message if called with no
Xarguments.
X
XNow, if you type "less < /dev/tty", the error message may be less illuminating,
Xbut you probably deserve it.  More does the same thing in this case.
X
X*** /tmp/,RCSt1a04937	Sun Sep 25 04:08:55 1988
X--- main.c	Sun Sep 25 04:08:21 1988
X***************
X*** 19,24 ****
X--- 19,25 ----
X  public char **	av;
X  public int 	curr_ac;
X  public int	quitting;
X+ public int	usage[128];
X  
X  extern int	file;
X  extern int	quit_at_eof;
X***************
X*** 108,115 ****
X  		 * but if the control terminal (for commands)
X  		 * and the input file (for data) are the same,
X  		 * we get weird results at best.
X  		 */
X! 		error("Can't take input from a terminal");
X  		if (f > 0)
X  			close(f);
X  		free(filename);
X--- 109,120 ----
X  		 * but if the control terminal (for commands)
X  		 * and the input file (for data) are the same,
X  		 * we get weird results at best.
X+ 		 * If there were no arguments, print a usage note.
X  		 */
X! 		if (ac == 0)
X! 			error(usage);
X! 		else
X! 			error("Can't take input from a terminal");
X  		if (f > 0)
X  			close(f);
X  		free(filename);
X***************
X*** 289,294 ****
X--- 294,303 ----
X  {
X  	char *getenv();
X  
X+ 	sprintf(usage, "Usage: %s %s\n\t%s\n\t%s", *argv,
X+ 		"[-[+]aABcCdeEimMnoOqQuUsw] [-b #] [-h #] [-x #] [-[z] #]",
X+ 		"[-P[mM=] string] [-[lL] logfile] [+ cmd]",
X+ 		"[-t tag] [filename]...");
X  
X  	/*
X  	 * Process command line arguments and LESS environment arguments.
X*** /tmp/,RCSt1a04937	Sun Sep 25 04:08:59 1988
X--- option.c	Sun Sep 25 04:08:24 1988
X***************
X*** 44,49 ****
X--- 44,50 ----
X  public int autobuf;
X  public int plusoption;
X  
X+ extern char usage[];
X  extern char *prproto[];
X  extern char *eqproto;
X  extern int nbufs;
X***************
X*** 529,534 ****
X--- 530,536 ----
X  
X  	sprintf(message, "\"-%c\": invalid flag", c);
X  	error(message);
X+ 	error(usage);
X  	exit(1);
X  }
X  
//go.sysin dd *
echo x - PATCH.9
sed 's/^X//' > PATCH.9 << '//go.sysin dd *'
XAlong with the patch that restores the old less behavior of quitting at the
Xendof of the first and only file if it is on a single screen (ala more), this
Xpatch makes less even "more" convenient for empty files.  If there is nothing
Xto display (since the first and only file is empty) this patch causes less to
Xquit before it displays anything, and to leave the cursor where it already is.
XThis last feature will also take effect if there are errors reading all files.
X
X*** /tmp/,RCSt1a01139	Sun Sep 25 12:06:01 1988
X--- main.c	Sun Sep 25 04:37:10 1988
X***************
X*** 145,150 ****
X--- 145,161 ----
X  	ch_init(cbufs, 0);
X  	init_mark();
X  
X+ 	/*
X+ 	 * Ignore a single empty file if we quit at eof.
X+ 	 */
X+ 	if (quit_at_eof && ac <= 1)
X+ 		if (ch_forw_get() == EOI)
X+ 		{
X+ 			file = -1;
X+ 			return;
X+ 		}
X+ 		else (void) ch_back_get();
X+ 
X  	if (every_first_cmd != NULL)
X  		first_cmd = every_first_cmd;
X  
X***************
X*** 454,461 ****
X  #if LOGFILE
X  	end_logfile();
X  #endif
X! 	lower_left();
X! 	clear_eos();
X  	deinit();
X  	flush();
X  	raw_mode(0);
X--- 465,475 ----
X  #if LOGFILE
X  	end_logfile();
X  #endif
X! 	if (any_display)
X! 	{
X! 		lower_left();
X! 		clear_eos();
X! 	}
X  	deinit();
X  	flush();
X  	raw_mode(0);
//go.sysin dd *
exit
-- 
inet: dupuy at columbia.edu
uucp: ...!rutgers!columbia!dupuy



More information about the Comp.sources.bugs mailing list