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