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