[comp.sources.atari.st] v02i076: gcclib2 -- Patches to GCC library part05/07

koreth%panarthea.ebay@sun.com (Steven Grimm) (08/20/89)

Submitted-by: uunet.UU.NET!unido!sbsvax!roeder (Edgar Roeder)
Posting-number: Volume 2, Issue 76
Archive-name: gcclib2/part05



#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of archive 5 (of 7)."
# Contents:  crt0.s read.c
# Wrapped by roeder@sbsvax on Wed Aug 16 22:03:03 1989
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'crt0.s' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'crt0.s'\"
else
echo shar: Extracting \"'crt0.s'\" \(11605 characters\)
sed "s/^X//" >'crt0.s' <<'END_OF_FILE'
X|
X|		Cross Development System for Atari ST 
X|      Copyright (c) 1988, Memorial University of Newfoundland
X|
X|  C start-up routine.  Has several tasks to do:
X|	release unneeded memory to the system
X|	set up stack
X|	set up argc, argv, and envp
X|	set up an address trap handler for bsr.l instructions
X|  Also defines _exit() so the address error handler can be restored
X|
X| $Header: /chandra/Gnu/atari/cross-lib/RCS/crt0.s,v 1.3 89/03/10 20:49:42 bammi Exp $
X| $Header: crt0.s,v 1.3 88/02/03 20:23:26 m68k Exp $
X|
X| Revision 1.9  89/08/15  er
X| Merged local version and version from terminator together
X| completely removed __in_trap flag (it's no longer needed - cf. signal.c)
X|
X| FIXME: all this revision number confusion should be cleaned up
X|
X| Revision 1.8  89/08/07  er
X| Added _init_timer and _exit_timer to do signal processing for SIGALRM/SIGHUP
X| Added argc/argv for accessories (just dummies)
X|
X| $Log:	crt0.s,v $
X| Revision 1.3  89/03/10  20:49:42  bammi
X| backed out Fforce(2,Fdup(1)) due to problems with redirections.
X| Revision 1.7  89/08/01  sb
X|     New argc/argv parsing for the commandline. Old code didn't recognize 
X| multiple blanks between arguments and supplied each blank as "" argument.
X|     Accessories need their own stack.
X| Sample code in the main-module: 
X| 	#define STACKSIZE 8000L
X| 	char my_private_acc_stack[STACKSIZE];
X| 	extern long _heapbase = (long) my_private_acc_stack;
X| 	extern long _stksize  = STACKSIZE;
X| 
X| Revision 1.2  89/03/08  22:20:51  bammi
X| Many hacks etc. Version as distributed with Gcc V1.34
X| 
X| Revision 1.1  89/03/08  21:57:52  bammi
X| Initial revision
X| 
X| Revision 1.6  89/07/19  er/sb/AD
X| __in_trap flags removed from early trap calls since alarm can't yet be there
X| added stuff from sb (__app and accessory support) and AD (malloc changes)
X|  Revision 1.2.1  89/02/06  AD (Atze Dijkstra)
X|  Changed malloc/stack mgt so stack is on top of heap
X|  and they will grow to each other.
X|  These will only be if __stksize == -1L
X|  See also memory.c
X|
X| Revision 1.5  89/07/06  er
X| changed to xArg parameter passing
X|
X| Revision 1.4  89/06/02  er
X| Added support for extended argument passing via PBP/ARGV
X| Installs trap handler for etv_term to restore alarm-routine and address-
X| error-handler. This handler catches also ^C pressed during TOS-i/o.
X| Added data_start and _base
X| TODO: _exit could be removed now from this code so the user can redefine it
X|
X| $Log:	crt0.s,v $
X| Revision 1.3  88/02/03  20:23:26  m68k
X| Added __in_trap flag - see atari/alarm()
X| 
X| Revision 1.2  88/01/29  17:24:37  m68k
X| Re-wrote the argument parsing stuff
X| Calls exit() instead of _exit()
X| uses Setvec() trap instead of Super()/mov/Super() to change the ae trap
X| stack now has initial size of 8k (up from 2)
X| 
X|
X	.globl  _data_start
X	.globl	__start
X	.globl	__exit
X	.globl	__base
X	.globl	_environ
X 	.globl	__heapbase		| AD
X	.globl	_main
X	.globl	_errno
X	.globl	__app
X	.globl	__init_timer
X	.globl	__exit_timer
X
X	.data
X
X	.comm	_data_start,4
X	.comm	__base,4
X	.comm	__stksize,4
X	.comm	_environ,4
X	.comm	__heapbase,4		| AD
X	.comm	_errno,4
X	.comm	__act_pd,4
X        .comm   __app,4			| ++sb  acc or prg ?
X
X	.text
X
X__start:
X	cmpl	#0, a7			| ++sb
X	bne	L0_1
X	movl	a0, a5
X	bra	L0_2
XL0_1:	movl	a7@(4), a5
XL0_2:	movl	a5, __base
X
X	movl	#1, __app
X	tstl	a5@(36)			| sb in accessories the father is NULL
X	bne	L25
X	clrl	__app			| please see demo-source for acc's!
X	movl	__heapbase, sp		| ++ sb acc NEED his own stack!
X	addl	__stksize, sp		| ++ sb
X	movl	#1, d3			| argc = 1	(er)
X	lea	acc_argv, a2		| argv = acc_argv = { "", 0L }
X|	lea	arg0, a0
X|	movl	a0, a2@			| argv[0] = ""
X	bra	L31_1			| ++ sb (no envp/argv stuff for acc's)
X
XL25:
X	| set up envp[] and argv[] stuff
X	movl	a5@(0x18), a1		| envp = basepage->bss_address
X	addl	a5@(0x1c), a1		|	+ basepage->bss_size;
X	movl	a1, _environ		| _environ = envp;
X	movl	a5@(0x2c), a2		| ep = basepage->envp;
XL0:	tstb	a2@			| while (*ep) {
X	beq	L3			|
X	movl	a2, a1@+		|	*envp++ = ep;
XL2:	tstb	a2@+			|	while (*ep++)
X	bne	L2			|		;
X	bra	L0			| }
XL3:	clrl	a1@+			| *envp++ = (char *) 0; 
X
X	movl	_environ, a3		| now we search for the xArg env-var
XL1:	tstl	a3@			| for (s = environ ; *s ; s++)
X	beq	L7			|
X	movl	a3@+, a4		|	if (strncmp(*s, "xArg=", 5))
X	cmpb	#0x78, a4@+		|	'x'
X	bne	L1			|
X	cmpb	#0x41, a4@+		|	'A'
X	bne	L1			|
X	cmpb	#0x72, a4@+		|	'r'
X	bne	L1			|
X	cmpb	#0x67, a4@+		|	'g'
X	bne	L1			|
X	cmpb	#0x3d, a4@+		|	'='
X	bne	L1			|
X
X	subl	a2, a2
X	lea	_conv,a0		| here we do a hex to binary conversion
XL14:
X	movl	a2, d3
X	lsll	#4, d3
X	movl	d3, a2
X	moveq	#15,d0
XL15:
X	moveb	a0@(d0:l),d3
X	cmpb	a4@,d3
X	jeq	L16
X	subql	#1,d0
X	jne	L15
XL16:
X	movl	a2, d3
X	orl	d0, d3
X	movl	d3, a2
X	addql	#1,a4
X	tstb	a4@
X	bne	L14
X	cmpl	#0x78417267,a2@		| is this a valid xArg-structure ?
X	bne	L7
X	movel	a2@(14),d3
X	cmpl	a5@(36),d3		| does it come from our father process ?
X	bne	L7
X	movew	a2@(4),d3		| here is argc (as word)
X	extl	d3
X	movel	a2@(6),a2		| and argv
X	movl	a1, a0
X	bra	L6
X_conv:
X	.ascii "0123456789ABCDEF"
XL7:					| /* a1: envp -> argbuf */
X	movl	a1, a0			| argv = argbuf
X	addl	#128, a0		|	 + sizeof(basepage->cmdline);
X	clrw	a0@+			| *((short)argv)++ = 0;
X	movl	a1, d1			| argstart = argbuf;
X	movl	a0, a2			| saveargv = argv;
X|	movew	#1, d3			| argc = 1;
X	movel	#1, d3			| .. jrd
X	movl	#arg0, a0@+		| *argv++ = "";
X	movl	#0x80, a3		| cmdline = basepage->cmdline;
X	addl	a5, a3			|
X| new parsing of cmdline ... sb (1 aug 89)				| sb
X	clrw	d1			| in_arg = FALSE;		| sb
X	movb	a3@+, d0		| count = *cmdline++;		| sb
XL8:	subqb	#1, d0			| while (--count > 0) { 	| sb
X	blt	L9			|				| sb
X	tstb	a3@			|   if (!*cmdline)		| sb
X	beq	L9			|	break;			| sb
X	cmpb	#0x20,a3@		|   } else if (*cmdline==' ') { | sb
X	bne	L12			|				| sb
X	clrw	d1			|	    in_arg = FALSE;	| sb
X	clrb	a3@+			|	    *cmdline = '\0';	| sb
X	bra	L8			|   } else if (!in_arg) {	| sb
XL12:	tstw	d1			|				| sb
X	bne	L11			|				| sb
X	movw	#1, d1			|	    in_arg = TRUE;	| sb
X	addql	#1, d3			|	    argc++;		| sb
X	movl	a3, a0@+		|	    *argv++ = cmdline;	| sb
XL11:	addql	#1, a3			|   } cmdline++;		| sb
X	bra	L8			| }				| sb
XL9:									| sb
X	| remove trailing CR 						| sb
X	clrb	a3@			| *cmdline = '\0';		| sb
X	clrl	a0@+			| *argv++ = NULL;		| sb
X
XL6:
X	cmpl	#0xFFFFFFFF, __stksize	| if ( __stksize == -1 )	| AD
X	bne	L30			|				| AD
X	movl	a0, __heapbase		| __heapbase = argv		| AD
X	movl	sp, a3			| __stksize = ( sp - argv -12K )| AD
X	subl	a0, a3							| AD
X	subl	#0x3000, a3		| no checks !!			| AD
X	movl	a3, __stksize						| AD
X	addl	a0, a3			| reserve = __stksize + argv	| AD
X	subl	a5, a3			|		- __base	| AD
X	bra	L31							| AD
XL30:									| AD
X	movl	#0, __heapbase		| __heapbase = 0		| AD
X	movl	a0, a3			| reserve = argv - __base;
X	subl	a5, a3
X	tstl	__stksize		| if (!__stksize)
X	bne	L13			|
X	movl	#0x2000, __stksize	|	__stksize = 8 * 1024;
XL13:	addl	__stksize, a3		| reserve += __stksize;
XL31:	movl	a3, d1
X	addl	a5, d1			| compute stack top
X	andl	#-2, d1			| even boundary
X	movl	d1, sp			| set up user stack
X
X	movl	a3, sp@-
X	movl	a5, sp@-
X	clrw	sp@-
X	movw	#0x4a, sp@-
X	trap	#1			| release excess storage
X	addl	#12, sp
X
XL31_1:	clrl	sp@-			| act_pd is needed for etv_term
X	movw	#0x20, sp@-
X	trap	#1
X	movl	#0x4F2, a0		| _sysbase
X	movl	a0@, a3			| Super() trashes a0-a1/d0-d1
X	movl	d0, sp@(2)
X	trap	#1
X	addql	#6, sp
X	movl	a3@(24), a4		| os_gendat
X	cmpl	#0x11201985, a4
X	beq	L24
X	cmpl	#0x02061986, a4
X	beq	L24
X	cmpl	#0x04241986, a4
X	beq	L24
X	movl	a3@(40), __act_pd	| it's in the header for newer versions
X	bra	L17
XL24:	movl	#0x602C, __act_pd	| default in old TOS versions
X
XL17:	movl	_environ, sp@-		| push saveenvp
X	movl	a2, sp@-		| push saveargv
X|	movw	d3, sp@-		| push argc
X	movel	d3,sp@-			| .. jrd
X
X	subl	a6, a6			| clear link reg - why I don't know
X
X	| here we set up a trap handler for address errors - this is used in
X	| doing long branches and long bsrs (see comments in Leat()).
X
X	movl	#aet, sp@-	| set address error vector to our handler
X	movew	#0x3, sp@-	|  was 0xc bug! thanks to sarnila@tukki.jyu.fi
X	movew	#0x5, sp@-	|  for finding and reporting it.
X	trap	#13
X	addql	#0x8, sp
X	movl	d0, old_aet	| save old trap handler
X
X	movl	__app, d0	| no terminate handler for accessories
X	beq	L32
X	movl	#term, sp@-	| install our terminate handler
X	bra	L33
XL32:	movl	#-1, sp@-	| for accessories: just ask for old handler
XL33:	movew	#0x102, sp@-
X	movew	#0x5, sp@-
X	trap	#13
X	addql	#0x8, sp
X	movl	d0, old_term	| save old trap handler
X
X|	jsr	_main
X	jsr	__init_timer
X	jsr	__main		| -- jrd.  call the standard wrapper fun
X	movew	d0, sp@-
X	jsr	_exit		| _exit calls __exit
X	| Not reached
X
X|
X| this handler is installed to insure that our signal handling will be removed
X| when it's time to go
X| it does also some signal-processing (^C pressed during TOS-i/o)
X|
X	.ascii	"XBRA"
X	.ascii	"GNUC"
Xold_term:
X	.long	0
Xterm:
X	moveml	d0-d1/a0, sp@-
X	movl	__act_pd, a0	| is the actual running process this one ?
X	movl	a0@, d0
X	movl	__base, d1
X	cmpl	d0, d1
X	beq	L23
X	moveml	sp@+, a0/d0-d1	| this signal was not meant for us
X	rts
XL23:	moveml	sp@+, a0/d0-d1
X	movew	a6@(8), d0
X	cmpw	#-32, d0	| ^C pressed or normal exit ?
X	bne	L22
X| during the following call to raise() we should better not call GEMDOS,
X| because GEMDOS should not be called with its own super stack in effect
X	moveml	d1-d7/a0-a5, sp@-
X	movel	#10, sp@-	| raise(SIGINT)
X	jsr	_raise
X	addql	#4, sp
X	moveml	sp@+, a0-a5/d1-d7
X|
X| ignore ^C now
X| this trick depends on the following facts:
X| 1. the TOS-i/o routine calls Pterm(-32) directly as a function and removes
X|    the parameter (-32) if this routine eventually comes back
X| 2. Pterm itself calls the logical vector 0x102 (etv_term) via assembler
X|    and so the register a6 points to the params of Pterm
X| 3. after the 'unlk a6', we can return to the caller of Pterm just with 'rts'
X|
X	unlk	a6
X	rts
XL22:	movl	old_aet, sp@-	| restore old address trap before we exit
X	movew	#0x3, sp@-
X	movew	#0x5, sp@-
X	trap	#13
X	addql	#0x8, sp
X	movl	old_term, sp@-	| restore old exit trap before we exit
X	movew	#0x102, sp@-
X	movew	#0x5, sp@-
X	trap	#13
X	addql	#0x8, sp
X	jmp	__exit_timer
X__exit:
X	jsr	L22		| remove our stuff
X|	movew	sp@(0x4), sp@-	| .. jrd
X	movel	sp@(4),d0
X	movew	d0,sp@-
X	movew	#0x4c, sp@-
X	trap	#1
X	| The End.
X
X|  This is a trap handler for address errors.  It is used in doing long
X| branches and long bsrs.  It looks to see if a long branch (0x6?ff) caused
X| the trap and if the destination is valid (not an odd address).  If so
X| the branch is taken and we return, otherwise, we call the old address
X| trapper.
X	.ascii	"XBRA"
X	.ascii	"GNUC"
Xold_aet:
X	.long	0
Xaet:
X	| d0, and a1 used 0x8080/101
X	| exp_frame is distance from top of stack to exception frame
X	Lexp_frame = 8			| 2 * sizeof(register)
X	moveml	#0x8080, sp@-		| save registers used
X	movw	sp@(Lexp_frame+6), d0	| the bad instruction
X	andw	#0xf0ff, d0
X	cmpw	#0x60ff, d0		| is a b?? instruction?
X	jne	L20			| nop, call old ae trap
X
X	movl	sp@(Lexp_frame+10), a0	| the pc (currently bewtixt branch)
X	addql	#1, a0			| increment to long offset
X	addl	a0@, a0			| calculate new pc
X	movl	a0, d0
X	andb	#1, d0			| are we still an odd address?
X	jne	L20			| yep, get out.
X
X	movl	a0, sp@(Lexp_frame+10)	| put new pc into the stack frame
X	cmpw	#0x61ff, sp@(Lexp_frame+6)	| if this is a bsrl
X	jne	L21			|  we need to fix up the return
X	movl	usp, a0			|  address on the user stack
X	addql	#4, a0@
XL21:
X	moveml	sp@+, #0x0101		| restore regs
X	addql	#8,sp			| pop part of stack frame
X	rte
X
XL20:
X	moveml	sp@+, #0x0101
X	movl	old_aet, sp@(-4)	| done this way so no regs get mussed up
X	jmp	sp@(-4)
X
X.data
Xacc_argv:				| ANSI Draft: argv[0][0] shall be the
X	.long	arg0			| null character if the program name is
Xarg0:	.long	0			| not available in the host environment
END_OF_FILE
if test 11605 -ne `wc -c <'crt0.s'`; then
    echo shar: \"'crt0.s'\" unpacked with wrong size!
fi
# end of 'crt0.s'
fi
if test -f 'read.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'read.c'\"
else
echo shar: Extracting \"'read.c'\" \(8951 characters\)
sed "s/^X//" >'read.c' <<'END_OF_FILE'
X/*
X *		Cross Development System for Atari ST 
X *     Copyright (c) 1988, Memorial University of Newfoundland
X *
X * $Header: read.c,v 1.2 88/02/03 22:56:30 m68k Exp $
X *
X * $Log:	read.c,v $
X *
X * 1.5		er
X *
X * Added /dev/null dummy handle.
X * Fix it : When adding 'continue' after raise(SIGINT) and raise(SIGQUIT), get
X * 	    unexpected results in Emacs (perhaps problems with EOF in fgetc()).
X * Moved __col_pos to write.c (it's always included because of fflush in exit)
X *
X * 1.4		er
X *
X * Revision 1.4	 89/01/15
X * Added support for function keys (they give an Esc-sequence with the
X * scan-code as parameter), META-key (Alternate sets the highest bit) and
X * O_NDELAY mode (no waiting if there is no available input). META-translation
X * is controled via the META-bit in __ttymode (set by ioctl()).
X *
X * 1.3		jrd
X *
X * Revision 1.2  88/02/03  22:56:30  m68k
X * Added unix like tty driver stuff
X * 
X * Revision 1.1  88/01/29  17:31:39  m68k
X * Initial revision
X * 
X */
X#include	<osbind.h>
X#include	<ioctl.h>
X#include	<file.h>
X#include	<errno.h>
X#include	<signal.h>
X#include	"tchars.h"
X
X/* set this frob if using Bconin to get char.  Leave it off using Fread */
X#define USING_BCONIN	0
X#define META_MASK	0x80
X#define DEL		0x7f
X
X#define	iswhite(c)	((c) == ' ' || (c) == '\t')
X#define	isvisable(c)	((c) >= ' ' && (c) < DEL)
X#define	echochar(c)	if (__ttymode & ECHO) (void) _echochar(c, fd); else
X#define	delchar(n)	if (__ttymode & ECHO) _delchar(n, fd); else
X
X# ifndef	NULL
X#  define	NULL	0
X# endif	/* NULL */
X
Xstatic int str_length(unsigned char * p, int n);
X
Xextern int	__col_pos;
Xstatic int	start_col;
Xstatic unsigned char	*thebuf;
X
Xstatic	int	_echochar();
Xstatic	int	str_length();
Xstatic	void	_delchar();
X
Xunion key {
X	int	i;
X	struct {
X		char	shift_state;
X		char	scan_code;
X		char	filler;
X		unsigned char	ascii_code;
X	} k;
X};
X
X/* possible shift_state's */
X#define	SHIFT_RIGHT	1
X#define	SHIFT_LEFT	2
X#define SHIFT	(SHIFT_LEFT|SHIFT_RIGHT)
X#define	CONTROL		4
X#define	ALTERNATE	8
X#define	CAPS_LOCK	16
X#define	MOUSE_RIGHT	32
X#define	MOUSE_LEFT	64
X#define	MOUSE	(MOUSE_LEFT|MOUSE_RIGHT)
X
Xstatic	enum { Esc, Number, Key }	_fn_state;
Xstatic	char	_fn_key;
X
Xint
Xread(int fd, unsigned char *buf, int nbytes)
X{
X#ifdef DEBUG
X  char dbgbuf[64];
X#endif
X
X  int	rval;
X  int	cnt = 0;
X  unsigned char	*p = buf;
X  union key	ch;
X
X  if (fd == 1234 || nbytes <= 0) return(0);	/* /dev/null */
X  if ((fd >= 0) && (!isatty(fd)))
X	{
X	if ((rval = Fread(fd, nbytes, buf)) < 0) 
X		{
X		errno = -rval;
X		rval = -1;
X		}
X#ifdef DEBUG
X	sprintf(dbgbuf, "read(%d, %X, %d)->%d\r\n", fd, buf, nbytes, rval);
X	dbgstr(dbgbuf);
X#endif
X	return rval;
X        }
X  if ((__handle_stat[fd] & O_NDELAY) && _fn_state == Esc && !Cconis()) {
X    errno = EAGAIN;
X    return -1;
X  }
X  thebuf = buf;
X  start_col = __col_pos;
X  while (1) {
X        switch (_fn_state) {
X                case Number :
X			*p = '#';
X			_fn_state = Key;
X			break;
X		case Key :
X			*p = _fn_key;
X			_fn_state = Esc;
X			break;
X		case Esc :
X			ch.i = console_read_byte(fd);
X			if((__ttymode & META) && !ch.k.shift_state) {
X				struct sgttyb	sg;
X
X				ioctl(fd, TIOCGETP, &sg);
X				ioctl(fd, TIOCSETN, &sg);
X				ch.k.shift_state = Kbshift(-1);
X			}
X			if((__ttymode & META) &&
X			    (ch.k.ascii_code & META_MASK)) {
X				/* these values are on the german keyboard */
X				switch(ch.k.ascii_code) {
X					case 0x81 :
X						ch.k.ascii_code = '@'; break;
X					case 0x84 :
X						ch.k.ascii_code = ']'; break;
X					case 0x8E :
X						ch.k.ascii_code = '}'; break;
X					case 0x94 :
X						ch.k.ascii_code = '['; break;
X					case 0x99 :
X						ch.k.ascii_code = '{'; break;
X					case 0x9A :
X						ch.k.ascii_code = '\\'; break;
X				}
X			}
X			if (ch.k.scan_code == 0x72 && ch.k.ascii_code == '\r')
X				ch.k.ascii_code = '\n';
X			else
X			/* 3B = F1, 72 = Enter, 53 = Delete, 60 = '<' */
X			if ((ch.k.scan_code >= 0x3B && ch.k.scan_code <= 0x72
X			  && ch.k.scan_code != 0x53 && ch.k.scan_code != 0x60))
X			{
X				if (ch.k.ascii_code) _fn_key = ch.k.ascii_code;
X				else _fn_key = ch.k.scan_code;
X				ch.k.ascii_code = 0x1B;	/* ESC */
X				_fn_state = Number;
X			}
X			*p = ch.k.ascii_code;
X			/* Alternate as META-key sets the highest bit */
X			if ((__ttymode & META) &&
X			    (ch.k.shift_state & ALTERNATE)) {
X				if (_fn_state != Esc) _fn_key |= META_MASK;
X				else {
X					if (ch.k.shift_state & SHIFT)
X			ch.k.ascii_code = __keytab->shift[ch.k.scan_code];
X					else if (ch.k.shift_state & CAPS_LOCK)
X			ch.k.ascii_code = __keytab->capslock[ch.k.scan_code];
X					else
X			ch.k.ascii_code = __keytab->unshift[ch.k.scan_code];
X					if (ch.k.shift_state & CONTROL)
X						ch.k.ascii_code &= 0x3F;
X					*p = ch.k.ascii_code | META_MASK;
X				}
X			}
X			break;
X		}
X	if (__ttymode & RAW) 
X	        {
X		if (__ttymode & ECHO) 
X		        {
X			console_write_byte(fd, *p);
X			if (*p == '\r')
X			        __col_pos = 0;
X			    else
X			if (isvisable(*p))
X				__col_pos++;
X			}
X		if (++cnt >= nbytes || !(short)console_status(fd))
X			return cnt;
X		p++;
X		continue;
X		}
X	if ((__ttymode & CRMOD) && *p == '\r')
X		*p = '\n';
X	if (*p == __tchars[TC_INTRC]) 
X		{
X		/* Do the bsd thing here, i.e. flush buffers
X		 * and continue to read after the interupt
X		 */
X		echochar(*p);
X		p = buf;
X		cnt = 0;
X		raise(SIGINT);
X		} 
X	    else 
X	if (*p == __tchars[TC_QUITC]) 
X		{
X		echochar(*p);
X		p = buf;
X		cnt = 0;
X		raise(SIGQUIT);
X		}
X            else
X	if (*p == __tchars[TC_SUSPC]) 
X		{
X		echochar(*p);
X		p = buf;
X		cnt = 0;
X		raise(SIGTSTP);
X		continue;
X		}
X	if (__ttymode & CBREAK) 
X		{
X		if (*p == __tchars[TC_LNEXTC])
X			*p = console_read_byte(fd);
X		if (__ttymode & ECHO) 
X			{
X			if (*p == '\n' && (__ttymode & CRMOD)) 
X				{
X				console_write_byte(fd, '\n');
X				console_write_byte(fd, '\r');
X				__col_pos = 0;
X				}
X			    else
X				(void) _echochar(*p);
X			}
X		if (++cnt >= nbytes || !(short)console_status(fd))
X			return cnt;
X		p++;
X		} 
X	    else
X	if (*p == __tchars[TC_LNEXTC]) 
X		{
X		if (__ttymode & ECHO)
X		        {
X			console_write_byte(fd, '^');
X			console_write_byte(fd, '\b');
X			}
X		*p = console_read_byte(fd);
X		echochar(*p++);
X		cnt++;
X		}
X	    else
X	if (*p == __tchars[TC_EOFC]) 
X		{
X		if (__ttymode & ECHO)
X			{
X			int i = _echochar(*p);
X			__col_pos -= i;
X			while (i-- > 0)
X				console_write_byte(fd, '\b');
X			}
X		return cnt;
X		}
X	    else
X	if (*p == '\n' || *p == __tchars[TC_BRKC]) 
X		{
X		if (__ttymode & ECHO)
X			if (*p == '\n')
X				{
X				console_write_byte(fd, '\n');
X				if (__ttymode & CRMOD) 
X					{
X					console_write_byte(fd, '\r');
X					__col_pos = 0;
X					}
X				}
X			    else
X				(void) _echochar(*p);
X		return ++cnt;
X		}
X	    else
X	if (*p == __tchars[TC_ERASE])
X		{
X		if (cnt) 
X			{
X			p--;
X			delchar(--cnt);
X			}
X		}
X	    else
X	if (*p == __tchars[TC_KILL]) 
X		{
X		while (--cnt >= 0) 
X			{
X			delchar(cnt);
X			p--;
X			}
X		cnt = 0;
X		} 
X	    else
X	if (*p == __tchars[TC_WERASC]) 
X	        {
X		p--;
X		while (cnt && iswhite(*p)) 
X		        {
X			delchar(--cnt);
X			p--;
X		        }
X		while (cnt && !iswhite(*p)) 
X		        {
X			delchar(--cnt);
X			p--;
X		        }
X		p++;
X	        }
X	    else
X	if (*p == __tchars[TC_RPRNTC]) 
X	        {
X		unsigned char	*s;
X
X		echochar(__tchars[TC_RPRNTC]);
X		console_write_byte(fd, '\r');
X		console_write_byte(fd, '\n');
X		__col_pos = 0;
X		start_col = 0;
X		if (__ttymode & ECHO)
X		        for (s = buf ; s < p ; s++)
X			        echochar(*s);
X	        } 
X	    else
X	        {
X		echochar(*p++);
X		cnt++;
X		}
X        if (cnt >= nbytes)
X	        return cnt;
X        }
X	/*NOTREACHED*/
X}
X
Xstatic	int
X_echochar(c, fd)
Xunsigned char c;
Xint fd;
X{
X  int	len = 0;
X
X  if (c & META_MASK)
X  	{
X	console_write_byte(fd, 'M');
X	console_write_byte(fd, '-');
X	c &= ~META_MASK;
X	len += 2;
X	}
X  if (c < ' ') 
X  	{
X	if (c == '\t') 
X		{
X		int	i;
X
X		len = ((__col_pos | 7) + 1) - __col_pos;
X		if (__ttymode & XTABS)
X			for (i = len ; i-- ;)
X				console_write_byte(fd, ' ');
X		    else
X			console_write_byte(fd, '\t');
X		}
X	    else
X	        {
X		console_write_byte(fd, '^');
X		console_write_byte(fd, c + 0x40);
X		len += 2;
X	        }
X        }
X    else
X      if (c == DEL) 
X	{
X	console_write_byte(fd, '^');
X	console_write_byte(fd, '?');
X	len += 2;
X	}
X      else
X	{
X	console_write_byte(fd, c);
X	len++;
X	}
X  __col_pos += len;
X  return len;
X}
X
Xstatic	void
X_delchar(n, fd)
Xint n;
Xint fd;
X{
X  int	len;
X  unsigned char	c = thebuf[n];
X
X  if (c & META_MASK) {
X    len = 2;
X    c &= ~META_MASK;
X  } else
X    len = 0;
X  if (c < ' ' || c == DEL)
X	{
X	if (c == '\t')
X		len = __col_pos - str_length(thebuf, n);
X	    else
X		len += 2;
X	}
X    else
X	len++;
X
X  __col_pos -= len;
X  while (len--) 
X	{
X#if USING_BCONIN
X	console_write_byte(fd, '\b');
X#endif
X	console_write_byte(fd, ' ');
X	console_write_byte(fd, '\b');
X	}
X}
X
Xstatic int str_length(p, n)
Xunsigned char	*p;
Xint	n;
X{
X  int	pos = start_col;
X  unsigned char	c;
X
X  while (n--) {
X	c = *p++;
X	if (c & META_MASK) 
X		{
X		pos += 2;
X		c &= ~META_MASK;
X		}
X        if (c < ' ' || c == DEL)
X		{
X		if (c == '\t')
X			pos = (pos | 7) + 1;
X		    else
X			pos += 2;
X		}
X		else
X			pos++;
X	}
X  return pos;
X}
END_OF_FILE
if test 8951 -ne `wc -c <'read.c'`; then
    echo shar: \"'read.c'\" unpacked with wrong size!
fi
# end of 'read.c'
fi
echo shar: End of archive 5 \(of 7\).
cp /dev/null ark5isdone
MISSING=""
for I in 1 2 3 4 5 6 7 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 7 archives.
    rm -f ark[1-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0