[comp.sources.bugs] Un-official patch to less5, 8-bit code

win@wrkof.UUCP (Winfried Koenig) (09/26/89)

These are patches I had to make to use less5 with 8-bit characters
under Interactive ix/386 version 2.0.2.

Remember, you have to create a character classification table and
define the environmental variable CHRCLASS [see chrtbl (1M)] to
use this feature.

--
Winfried Koenig
win@incom.de

*** ../less/ch.c	Mon Sep 25 03:59:48 1989
--- ch.c	Thu Sep 21 18:15:40 1989
***************
*** 16,22 ****
  	struct buf *next, *prev;
  	long block;
  	int datasize;
! 	char data[BUFSIZ];
  };
  public int nbufs;
  
--- 16,22 ----
  	struct buf *next, *prev;
  	long block;
  	int datasize;
! 	uchar data[BUFSIZ];
  };
  public int nbufs;
  
***************
*** 73,79 ****
  {
  	register struct buf *bp;
  	register int n;
! 	register char *p;
  	POSITION pos;
  
  	/*
--- 73,79 ----
  {
  	register struct buf *bp;
  	register int n;
! 	register uchar *p;
  	POSITION pos;
  
  	/*
***************
*** 164,171 ****
  	/*
  	 * Set an EOI marker in the buffered data itself.
  	 * Then ensure the data is "clean": there are no 
! 	 * extra EOI chars in the data and that the "meta"
! 	 * bit (the 0200 bit) is reset in each char.
  	 */
  	if (n == 0)
  	{
--- 164,170 ----
  	/*
  	 * Set an EOI marker in the buffered data itself.
  	 * Then ensure the data is "clean": there are no 
! 	 * extra EOI chars in the data.
  	 */
  	if (n == 0)
  	{
***************
*** 178,186 ****
  		p = &bp->data[bp->datasize];
  		while (--n >= 0)
  		{
! 			*--p &= 0177;
! 			if (*p == EOI)
  				*p = '@';
  		}
  	}
  
--- 177,186 ----
  		p = &bp->data[bp->datasize];
  		while (--n >= 0)
  		{
! 			if (*--p == EOI)
  				*p = '@';
+ 			if (!(isprint(*p) || iscntrl(*p)))
+ 				*p &= 0177;
  		}
  	}
  
*** ../less/command.c	Mon Sep 25 03:59:49 1989
--- command.c	Thu Sep 21 11:07:57 1989
***************
*** 63,69 ****
  		 */
  		return (1);
  
! 	if (control_char(*--cp))
  	{
  		/*
  		 * Erase an extra character, for the carat.
--- 63,69 ----
  		 */
  		return (1);
  
! 	if (iscntrl((uchar)*--cp))
  	{
  		/*
  		 * Erase an extra character, for the carat.
***************
*** 127,133 ****
  		 * Append the character to the string.
  		 */
  		*cp++ = c;
! 		if (control_char(c))
  		{
  			putchr('^');
  			cmd_col++;
--- 127,133 ----
  		 * Append the character to the string.
  		 */
  		*cp++ = c;
! 		if (iscntrl(c))
  		{
  			putchr('^');
  			cmd_col++;
***************
*** 375,381 ****
  		 * Entering digits of a number.
  		 * Terminated by a non-digit.
  		 */
! 		if ((c < '0' || c > '9') &&
  			c != erase_char && c != kill_char)
  		{
  			/*
--- 375,381 ----
  		 * Entering digits of a number.
  		 * Terminated by a non-digit.
  		 */
! 		if (! isdigit(c) &&
  			c != erase_char && c != kill_char)
  		{
  			/*
***************
*** 842,848 ****
  			 */
  			if (mca != A_PREFIX)
  				start_mca(A_PREFIX, "& ");
! 			if (control_char(c))
  			{
  				putchr('^');
  				c = carat_char(c);
--- 842,848 ----
  			 */
  			if (mca != A_PREFIX)
  				start_mca(A_PREFIX, "& ");
! 			if (iscntrl(c))
  			{
  				putchr('^');
  				c = carat_char(c);
*** ../less/input.c	Mon Sep 25 03:59:51 1989
--- input.c	Thu Sep 21 22:33:43 1989
***************
*** 12,18 ****
  
  extern int squeeze;
  extern int sigs;
! extern char *line;
  
  /*
   * Get the next line.
--- 12,18 ----
  
  extern int squeeze;
  extern int sigs;
! extern short *line;
  
  /*
   * Get the next line.
*** ../less/line.c	Mon Sep 25 03:59:55 1989
--- line.c	Mon Sep 25 02:44:31 1989
***************
*** 7,14 ****
  
  #include "less.h"
  
! static char linebuf[1024];	/* Buffer which holds the current output line */
! static char *curr;		/* Pointer into linebuf */
  static int column;		/* Printable length, accounting for
  				   backspaces, etc. */
  /*
--- 7,14 ----
  
  #include "less.h"
  
! static short linebuf[LINEBUF];	/* Buffer which holds the current output line */
! static short *curr;		/* Pointer into linebuf */
  static int column;		/* Printable length, accounting for
  				   backspaces, etc. */
  /*
***************
*** 47,53 ****
  #define	LN_BO_X		5	/* In boldface, got char, need \b */
  #define	LN_BO_XB	6	/* In boldface, got char & \b, need same char */
  
! public char *line;		/* Pointer to the current line.
  				   Usually points to linebuf. */
  
  extern int bs_mode;
--- 47,53 ----
  #define	LN_BO_X		5	/* In boldface, got char, need \b */
  #define	LN_BO_XB	6	/* In boldface, got char & \b, need same char */
  
! public short *line;		/* Pointer to the current line.
  				   Usually points to linebuf. */
  
  extern int bs_mode;
***************
*** 112,118 ****
  		return (0);
  	}
  
! 	if (curr > linebuf + sizeof(linebuf) - 12)
  		/*
  		 * Almost out of room in the line buffer.
  		 * Don't take any chances.
--- 112,118 ----
  		return (0);
  	}
  
! 	if (curr > linebuf + LINEBUF - 12)
  		/*
  		 * Almost out of room in the line buffer.
  		 * Don't take any chances.
***************
*** 130,136 ****
  		switch (ln_state)
  		{
  		case LN_NORMAL:
! 			if (curr <= linebuf + 1 || curr[-1] != '\b')
  				break;
  
  			if (c == curr[-2])
--- 130,136 ----
  		switch (ln_state)
  		{
  		case LN_NORMAL:
! 			if (curr <= linebuf + 1 || curr[-1] != BS_CHAR)
  				break;
  
  			if (c == curr[-2])
***************
*** 341,380 ****
  		return (0);
  	}
  
! 	if (c == '\b')
  	{
! 		if (bs_mode == BS_CONTROL)
! 		{
! 			/*
! 			 * Treat backspace as a control char: output "^H".
! 			 */
! 			NEW_COLUMN(column+2);
! 			*curr++ = ('H' | 0200);
! 		} else
! 		{
! 			/*
! 			 * Output a real backspace.
! 			 */
! 			column--;
! 			*curr++ = '\b';
! 		}
  		return (0);
  	} 
  
! 	if (control_char(c))
  	{
- 		/*
- 		 * Put a "^X" into the buffer.
- 		 * The 0200 bit is used to tell put_line() to prefix
- 		 * the char with a ^.  We don't actually put the ^
- 		 * in the buffer because we sometimes need to move
- 		 * chars around, and such movement might separate 
- 		 * the ^ from its following character.
- 		 * {{ This should be redone so that we can use an
- 		 *    8 bit (e.g. international) character set. }}
- 		 */
  		NEW_COLUMN(column+2);
! 		*curr++ = (carat_char(c) | 0200);
  		return (0);
  	}
  
--- 341,360 ----
  		return (0);
  	}
  
! 	if (c == '\b' && bs_mode != BS_CONTROL)
  	{
! 		/*
! 		 * Output a real backspace.
! 		 */
! 		column--;
! 		*curr++ = BS_CHAR;
  		return (0);
  	} 
  
! 	if (iscntrl(c))
  	{
  		NEW_COLUMN(column+2);
! 		*curr++ = c;
  		return (0);
  	}
  
***************
*** 395,401 ****
  forw_raw_line(curr_pos)
  	POSITION curr_pos;
  {
! 	register char *p;
  	register int c;
  	POSITION new_pos;
  
--- 375,381 ----
  forw_raw_line(curr_pos)
  	POSITION curr_pos;
  {
! 	register short *p;
  	register int c;
  	POSITION new_pos;
  
***************
*** 412,418 ****
  			new_pos = ch_tell();
  			break;
  		}
! 		if (p >= &linebuf[sizeof(linebuf)-1])
  		{
  			/*
  			 * Overflowed the input buffer.
--- 392,398 ----
  			new_pos = ch_tell();
  			break;
  		}
! 		if (p >= &linebuf[LINEBUF -1 ])
  		{
  			/*
  			 * Overflowed the input buffer.
***************
*** 439,445 ****
  back_raw_line(curr_pos)
  	POSITION curr_pos;
  {
! 	register char *p;
  	register int c;
  	POSITION new_pos;
  
--- 419,425 ----
  back_raw_line(curr_pos)
  	POSITION curr_pos;
  {
! 	register short *p;
  	register int c;
  	POSITION new_pos;
  
***************
*** 447,453 ****
  		ch_seek(curr_pos-1))
  		return (NULL_POSITION);
  
! 	p = &linebuf[sizeof(linebuf)];
  	*--p = '\0';
  
  	for (;;)
--- 427,433 ----
  		ch_seek(curr_pos-1))
  		return (NULL_POSITION);
  
! 	p = &linebuf[LINEBUF];
  	*--p = '\0';
  
  	for (;;)
*** ../less/main.c	Mon Sep 25 03:59:57 1989
--- main.c	Thu Sep 21 13:34:44 1989
***************
*** 294,299 ****
--- 294,300 ----
  	 * Process command line arguments and LESS environment arguments.
  	 * Command line arguments override environment arguments.
  	 */
+ 	setchrclass(NULL);
  	init_prompt();
  	init_option();
  	scan_option(getenv("LESS"));
*** ../less/option.c	Mon Sep 25 03:59:58 1989
--- option.c	Mon Sep 25 03:02:08 1989
***************
*** 346,352 ****
  		return;
  	}
  
! 	if (control_char(c))
  		sprintf(message, "-^%c", carat_char(c));
  	else
  		sprintf(message, "-%c", c);
--- 346,352 ----
  		return;
  	}
  
! 	if (iscntrl(c))
  		sprintf(message, "-^%c", carat_char(c));
  	else
  		sprintf(message, "-%c", c);
***************
*** 558,564 ****
  	char message[80];
  
  	s = *sp;
! 	if (*s < '0' || *s > '9')
  	{
  		if (c == '\0')
  			return (-1);
--- 558,564 ----
  	char message[80];
  
  	s = *sp;
! 	if (! isdigit(*s))
  	{
  		if (c == '\0')
  			return (-1);
***************
*** 568,574 ****
  	}
  
  	n = 0;
! 	while (*s >= '0' && *s <= '9')
  		n = 10 * n + *s++ - '0';
  	*sp = s;
  	return (n);
--- 568,574 ----
  	}
  
  	n = 0;
! 	while (isdigit(*s))
  		n = 10 * n + *s++ - '0';
  	*sp = s;
  	return (n);
*** ../less/os.c	Mon Sep 25 03:59:58 1989
--- os.c	Thu Sep 21 23:43:19 1989
***************
*** 201,207 ****
  		/*
  		 * Read the output of <$SHELL -c "echo filename">.
  		 */
! 		cmd = calloc(strlen(p)+12);
  		if (cmd == NULL)
  			return (filename);
  		sprintf(cmd, "%s -c \"echo %s\"", p, filename);
--- 201,207 ----
  		/*
  		 * Read the output of <$SHELL -c "echo filename">.
  		 */
! 		cmd = calloc(strlen(p)+12, sizeof(char));
  		if (cmd == NULL)
  			return (filename);
  		sprintf(cmd, "%s -c \"echo %s\"", p, filename);
*** ../less/output.c	Mon Sep 25 03:59:58 1989
--- output.c	Mon Sep 25 01:30:10 1989
***************
*** 15,22 ****
  extern int twiddle;
  extern int screen_trashed;
  extern int any_display;
! extern char *line;
  extern char *first_cmd;
  
  /*
   * Display the line which is in the line buffer.
--- 15,24 ----
  extern int twiddle;
  extern int screen_trashed;
  extern int any_display;
! extern short *line;
  extern char *first_cmd;
+ static short twline[] = {'~', 0};
+ static short bline[] = {0};
  
  /*
   * Display the line which is in the line buffer.
***************
*** 24,30 ****
  	public void
  put_line()
  {
! 	register char *p;
  	register int c;
  	register int column;
  	extern int auto_wrap, ignaw;
--- 26,32 ----
  	public void
  put_line()
  {
! 	register short *p;
  	register int c;
  	register int column;
  	extern int auto_wrap, ignaw;
***************
*** 39,45 ****
  	}
  
  	if (line == NULL)
! 		line = (twiddle) ? "~" : "";
  
  	column = 0;
  	for (p = line;  *p != '\0';  p++)
--- 41,47 ----
  	}
  
  	if (line == NULL)
! 		line = (twiddle) ? twline : bline;
  
  	column = 0;
  	for (p = line;  *p != '\0';  p++)
***************
*** 69,88 ****
  				column++;
  			} while ((column % tabstop) != 0);
  			break;
! 		case '\b':
  			putbs();
  			column--;
  			break;
  		default:
! 			if (c & 0200)
  			{
- 				/*
- 				 * Control characters arrive here as the
- 				 * normal character [carat_char(c)] with
- 				 * the 0200 bit set.  See pappend().
- 				 */
  				putchr('^');
! 				putchr(c & 0177);
  				column += 2;
  			} else
  			{
--- 71,85 ----
  				column++;
  			} while ((column % tabstop) != 0);
  			break;
! 		case BS_CHAR:
  			putbs();
  			column--;
  			break;
  		default:
! 			if (iscntrl(c))
  			{
  				putchr('^');
! 				putchr(carat_char(c));
  				column += 2;
  			} else
  			{
***************
*** 95,110 ****
  		putchr('\n');
  }
  
- /*
-  * Is a given character a "control" character?
-  * {{ ASCII DEPENDENT }}
-  */
- 	public int
- control_char(c)
- 	int c;
- {
- 	return (c < ' ' || c == '\177');
- }
  
  /*
   * Return the printable character used to identify a control character
--- 92,97 ----
***************
*** 115,121 ****
  carat_char(c)
  	int c;
  {
! 	return ((c == '\177') ? '?' : (c | 0100));
  }
  
  
--- 102,111 ----
  carat_char(c)
  	int c;
  {
! 	if (c & 200)
! 		return ((c == '\237') ? '/' : ((c & 077) + 0140));
! 	else
! 		return ((c == '\177') ? '?' : (c | 0100));
  }
  
  
*** ../less/prim.c	Mon Sep 25 04:00:00 1989
--- prim.c	Thu Sep 21 23:57:20 1989
***************
*** 20,26 ****
  extern int caseless;
  extern int linenums;
  extern int plusoption;
! extern char *line;
  extern char *first_cmd;
  #if TAGS
  extern int tagoption;
--- 20,26 ----
  extern int caseless;
  extern int linenums;
  extern int plusoption;
! extern short *line;
  extern char *first_cmd;
  #if TAGS
  extern int tagoption;
***************
*** 624,631 ****
  	int wantmatch;
  {
  	POSITION pos, linepos;
  	register char *p;
- 	register char *q;
  	int linenum;
  	int linematch;
  #if RECOMP
--- 624,631 ----
  	int wantmatch;
  {
  	POSITION pos, linepos;
+ 	register short *pi;
  	register char *p;
  	int linenum;
  	int linematch;
  #if RECOMP
***************
*** 815,820 ****
--- 815,822 ----
  		if (linenums)
  			add_lnum(linenum, pos);
  
+ 		pi = line;
+ 		p = (char *)line;
  		if (caseless)
  		{
  			/*
***************
*** 825,843 ****
  			 * This allows us to match text which is 
  			 * underlined or overstruck.
  			 */
! 			for (p = q = line;  *p != '\0';  p++, q++)
! 			{
! 				if (*p >= 'A' && *p <= 'Z')
! 					/* Convert uppercase to lowercase. */
! 					*q = *p + 'a' - 'A';
! 				else if (q > line && *p == '\b')
! 					/* Delete BS and preceeding char. */
! 					q -= 2;
! 				else
! 					/* Otherwise, just copy. */
! 					*q = *p;
  			}
  		}
  
  		/*
  		 * Test the next line to see if we have a match.
--- 827,854 ----
  			 * This allows us to match text which is 
  			 * underlined or overstruck.
  			 */
! 			while (*pi != 0) {
! 				if (*pi & 0400) {
! 					if(*pi++ == BS_CHAR && p > (char *)line)
! 					    /* Delete BS and preceeding char. */
! 					    p -= 1;
! 				} else {
! 					if(isupper(*pi))
! 						*p++ = tolower(*pi++);
! 					else
! 						*p++ = *pi++;
! 				}
! 			}
! 		} else {
! 			while (*pi != 0) {
! 				if (*pi & 0400) {
! 					if (*pi++ == BS_CHAR)
! 						*p++ = '\b';
! 				} else
! 					*p++ = *pi++;
  			}
  		}
+ 		*p = '\0';
  
  		/*
  		 * Test the next line to see if we have a match.
***************
*** 845,856 ****
  		 * on what pattern matching functions are available.
  		 */
  #if REGCMP
! 		linematch = (regex(cpattern, line) != NULL);
  #else
  #if RECOMP
! 		linematch = (re_exec(line) == 1);
  #else
! 		linematch = match(pattern, line);
  #endif
  #endif
  		/*
--- 856,867 ----
  		 * on what pattern matching functions are available.
  		 */
  #if REGCMP
! 		linematch = (regex(cpattern, (char *)line) != NULL);
  #else
  #if RECOMP
! 		linematch = (re_exec((char *)line) == 1);
  #else
! 		linematch = match(pattern, (char *)line);
  #endif
  #endif
  		/*
*** ../less/screen.c	Mon Sep 25 04:00:01 1989
--- screen.c	Thu Sep 21 13:47:43 1989
***************
*** 16,21 ****
--- 16,22 ----
  #else
  #include <sgtty.h>
  #endif
+ #undef TIOCGWINSZ	/*!!!!!!!!!!!!!!!!!!!!!!!?????????????*/
  
  #ifdef TIOCGWINSZ
  #include <sys/ioctl.h>
***************
*** 114,120 ****
  		 * Set the modes to the way we want them.
  		 */
  		s.c_lflag &= ~(ICANON|ECHO|ECHOE|ECHOK|ECHONL);
! 		s.c_oflag |=  (OPOST|ONLCR|TAB3);
  		s.c_oflag &= ~(OCRNL|ONOCR|ONLRET);
  		s.c_cc[VMIN] = 1;
  		s.c_cc[VTIME] = 0;
--- 115,121 ----
  		 * Set the modes to the way we want them.
  		 */
  		s.c_lflag &= ~(ICANON|ECHO|ECHOE|ECHOK|ECHONL);
! 		s.c_oflag |=  (OPOST|ONLCR);
  		s.c_oflag &= ~(OCRNL|ONOCR|ONLRET);
  		s.c_cc[VMIN] = 1;
  		s.c_cc[VTIME] = 0;
*** ../less/tags.c	Mon Sep 25 04:00:01 1989
--- tags.c	Mon Sep 25 03:42:09 1989
***************
*** 12,18 ****
  
  extern int linenums;
  extern int sigs;
! extern char *line;
  
  /*
   * Find a tag in the "tags" file.
--- 12,18 ----
  
  extern int linenums;
  extern int sigs;
! extern short *line;
  
  /*
   * Find a tag in the "tags" file.
***************
*** 119,124 ****
--- 119,126 ----
  {
  	POSITION pos, linepos;
  	int linenum;
+ 	char *p;
+ 	short *pi;
  
  	pos = (POSITION)0;
  	linenum = find_linenum(pos);
***************
*** 158,167 ****
  		if (linenums)
  			add_lnum(linenum, pos);
  
  		/*
  		 * Test the line to see if we have a match.
  		 */
! 		if (strcmp(tagpattern, line) == 0)
  			break;
  	}
  
--- 160,172 ----
  		if (linenums)
  			add_lnum(linenum, pos);
  
+ 		pi = line;
+ 		p = (char *)line;
+ 		while (*p++ = *pi++);
  		/*
  		 * Test the line to see if we have a match.
  		 */
! 		if (strcmp(tagpattern, (char *)line) == 0)
  			break;
  	}
  
*** ../less/defines.h	Mon Sep 25 03:59:50 1989
--- defines.h	Thu Sep 21 10:39:50 1989
***************
*** 1,5 ****
  /* Definition file for less */
! /* Generated Tue Sep 20 00:44:52 GMT 1988 by linstall. */
  
  /*
   * Define XENIX if running under XENIX 3.0.
--- 1,5 ----
  /* Definition file for less */
! /* Generated Wed Sep 20 19:39:54 EET 1989 by linstall. */
  
  /*
   * Define XENIX if running under XENIX 3.0.
*** ../less/funcs.h	Mon Sep 25 03:59:50 1989
--- funcs.h	Thu Sep 21 13:48:49 1989
***************
*** 88,94 ****
  	public int getchr ();
  	public void commands ();
  	public void put_line ();
- 	public int control_char ();
  	public int carat_char ();
  	public void flush ();
  	public void dropout ();
--- 88,93 ----
*** ../less/less.h	Mon Sep 25 03:59:51 1989
--- less.h	Mon Sep 25 02:42:51 1989
***************
*** 1,6 ****
--- 1,7 ----
  /*
   * Standard include file for "less".
   */
+ #include <ctype.h>
  
  /*
   * Include the file of compile-time options.
***************
*** 18,23 ****
--- 19,26 ----
  /*
   * Special types and constants.
   */
+ typedef unsigned char	uchar;
+ 
  typedef long		POSITION;
  /*
   * {{ Warning: if POSITION is changed to other than "long",
***************
*** 35,40 ****
--- 38,44 ----
  
  
  #define	FILENAME	128	/* Max size of a filename */
+ #define LINEBUF		1024	/* Size of linebufer */
  
  #define	EOI		(0)
  #ifndef NULL
***************
*** 59,68 ****
  #define	BS_CONTROL	2	/* \b treated as control char; prints as ^H */
  
  /* Special chars used to tell put_line() to do something special */
! #define	UL_CHAR		'\201'	/* Enter underline mode */
! #define	UE_CHAR		'\202'	/* Exit underline mode */
! #define	BO_CHAR		'\203'	/* Enter boldface mode */
! #define	BE_CHAR		'\204'	/* Exit boldface mode */
  
  #define	CONTROL(c)		((c)&037)
  #define	SIGNAL(sig,func)	signal(sig,func)
--- 63,73 ----
  #define	BS_CONTROL	2	/* \b treated as control char; prints as ^H */
  
  /* Special chars used to tell put_line() to do something special */
! #define	UL_CHAR		0401	/* Enter underline mode */
! #define	UE_CHAR		0402	/* Exit underline mode */
! #define	BO_CHAR		0403	/* Enter boldface mode */
! #define	BE_CHAR		0404	/* Exit boldface mode */
! #define BS_CHAR		0405	/* Output real \b character */
  
  #define	CONTROL(c)		((c)&037)
  #define	SIGNAL(sig,func)	signal(sig,func)