add LCC - a better C-Compiler for WEGA
This commit is contained in:
commit
0d39383f9b
|
|
@ -0,0 +1,30 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 1980 Regents of the University of California.
|
||||||
|
* All rights reserved. The Berkeley software License Agreement
|
||||||
|
* specifies the terms and conditions for redistribution.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef lint
|
||||||
|
static char sccsid[] = "@(#)tc1.c 5.1 (Berkeley) 6/5/85";
|
||||||
|
#endif not lint
|
||||||
|
|
||||||
|
/*
|
||||||
|
* tc1 [term]
|
||||||
|
* dummy program to test termlib.
|
||||||
|
* gets entry, counts it, and prints it.
|
||||||
|
*/
|
||||||
|
#include <stdio.h>
|
||||||
|
char buf[1024];
|
||||||
|
char *getenv();
|
||||||
|
|
||||||
|
main(argc, argv) char **argv; {
|
||||||
|
char *p;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
if (argc < 2)
|
||||||
|
p = getenv("TERM");
|
||||||
|
else
|
||||||
|
p = argv[1];
|
||||||
|
rc = tgetent(buf,p);
|
||||||
|
printf("tgetent returns %d, len=%d, text=\n'%s'\n",rc,strlen(buf),buf);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,57 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 1980 Regents of the University of California.
|
||||||
|
* All rights reserved. The Berkeley software License Agreement
|
||||||
|
* specifies the terms and conditions for redistribution.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef lint
|
||||||
|
static char sccsid[] = "@(#)tc2.c 5.1 (Berkeley) 6/5/85";
|
||||||
|
#endif not lint
|
||||||
|
|
||||||
|
/*
|
||||||
|
* tc2 [term]
|
||||||
|
* Dummy program to test out termlib.
|
||||||
|
* Commands are "tcc\n" where t is type (s for string, f for flag,
|
||||||
|
* or n for number) and cc is the name of the capability.
|
||||||
|
*/
|
||||||
|
#include <stdio.h>
|
||||||
|
char buf[1024];
|
||||||
|
char *getenv(), *tgetstr();
|
||||||
|
|
||||||
|
main(argc, argv) char **argv; {
|
||||||
|
char *p, *q;
|
||||||
|
int rc;
|
||||||
|
char b[3], c;
|
||||||
|
char area[200];
|
||||||
|
|
||||||
|
if (argc < 2)
|
||||||
|
p = getenv("TERM");
|
||||||
|
else
|
||||||
|
p = argv[1];
|
||||||
|
rc = tgetent(buf,p);
|
||||||
|
for (;;) {
|
||||||
|
c = getchar();
|
||||||
|
if (c < 0)
|
||||||
|
exit(0);
|
||||||
|
b[0] = getchar();
|
||||||
|
if (b[0] < ' ')
|
||||||
|
exit(0);
|
||||||
|
b[1] = getchar();
|
||||||
|
b[2] = 0;
|
||||||
|
getchar();
|
||||||
|
switch(c) {
|
||||||
|
case 'f':
|
||||||
|
printf("%s: %d\n",b,tgetflag(b));
|
||||||
|
break;
|
||||||
|
case 'n':
|
||||||
|
printf("%s: %d\n",b,tgetnum(b));
|
||||||
|
break;
|
||||||
|
case 's':
|
||||||
|
q = area;
|
||||||
|
printf("%s: %s\n",b,tgetstr(b,&q));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,82 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 1980 Regents of the University of California.
|
||||||
|
* All rights reserved. The Berkeley software License Agreement
|
||||||
|
* specifies the terms and conditions for redistribution.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef lint
|
||||||
|
static char sccsid[] = "@(#)tc3.c 5.1 (Berkeley) 6/5/85";
|
||||||
|
#endif not lint
|
||||||
|
|
||||||
|
/*
|
||||||
|
* tc3 [term]
|
||||||
|
* Dummy program to test out termlib.
|
||||||
|
* Input two numbers and it prints out the tgoto string generated.
|
||||||
|
*/
|
||||||
|
#include <stdio.h>
|
||||||
|
char buf[1024];
|
||||||
|
char *getenv(), *tgetstr();
|
||||||
|
char *rdchar();
|
||||||
|
char *tgoto();
|
||||||
|
char *CM;
|
||||||
|
char cmbuff[30];
|
||||||
|
char *x;
|
||||||
|
char *UP;
|
||||||
|
char *tgout;
|
||||||
|
|
||||||
|
main(argc, argv) char **argv; {
|
||||||
|
char *p;
|
||||||
|
int rc;
|
||||||
|
int row, col;
|
||||||
|
|
||||||
|
if (argc < 2)
|
||||||
|
p = getenv("TERM");
|
||||||
|
else
|
||||||
|
p = argv[1];
|
||||||
|
rc = tgetent(buf,p);
|
||||||
|
x = cmbuff;
|
||||||
|
UP = tgetstr("up", &x);
|
||||||
|
printf("UP = %x = ", UP); pr(UP); printf("\n");
|
||||||
|
if (UP && *UP==0)
|
||||||
|
UP = 0;
|
||||||
|
CM = tgetstr("cm", &x);
|
||||||
|
printf("CM = "); pr(CM); printf("\n");
|
||||||
|
for (;;) {
|
||||||
|
if (scanf("%d %d", &row, &col) < 2)
|
||||||
|
exit(0);
|
||||||
|
tgout = tgoto(CM, row, col);
|
||||||
|
pr(tgout);
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pr(p)
|
||||||
|
register char *p;
|
||||||
|
{
|
||||||
|
for (; *p; p++)
|
||||||
|
printf("%s", rdchar(*p));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* rdchar: returns a readable representation of an ASCII char, using ^ notation.
|
||||||
|
*/
|
||||||
|
#include <ctype.h>
|
||||||
|
char *rdchar(c)
|
||||||
|
char c;
|
||||||
|
{
|
||||||
|
static char ret[4];
|
||||||
|
register char *p;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Due to a bug in isprint, this prints spaces as ^`, but this is OK
|
||||||
|
* because we want something to show up on the screen.
|
||||||
|
*/
|
||||||
|
ret[0] = ((c&0377) > 0177) ? '\'' : ' ';
|
||||||
|
c &= 0177;
|
||||||
|
ret[1] = isprint(c) ? ' ' : '^';
|
||||||
|
ret[2] = isprint(c) ? c : c^0100;
|
||||||
|
ret[3] = 0;
|
||||||
|
for (p=ret; *p==' '; p++)
|
||||||
|
;
|
||||||
|
return (p);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,349 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 1980 Regents of the University of California.
|
||||||
|
* All rights reserved. The Berkeley software License Agreement
|
||||||
|
* specifies the terms and conditions for redistribution.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef lint
|
||||||
|
static char sccsid[] = "@(#)termcap.c 5.1 (Berkeley) 6/5/85";
|
||||||
|
#endif not lint
|
||||||
|
|
||||||
|
#define BUFSIZ 1024
|
||||||
|
#define MAXHOP 32 /* max number of tc= indirections */
|
||||||
|
#define E_TERMCAP "/etc/termcap"
|
||||||
|
|
||||||
|
#include <ctype.h>
|
||||||
|
/*
|
||||||
|
* termcap - routines for dealing with the terminal capability data base
|
||||||
|
*
|
||||||
|
* BUG: Should use a "last" pointer in tbuf, so that searching
|
||||||
|
* for capabilities alphabetically would not be a n**2/2
|
||||||
|
* process when large numbers of capabilities are given.
|
||||||
|
* Note: If we add a last pointer now we will screw up the
|
||||||
|
* tc capability. We really should compile termcap.
|
||||||
|
*
|
||||||
|
* Essentially all the work here is scanning and decoding escapes
|
||||||
|
* in string capabilities. We don't use stdio because the editor
|
||||||
|
* doesn't, and because living w/o it is not hard.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static char *tbuf;
|
||||||
|
static int hopcount; /* detect infinite loops in termcap, init 0 */
|
||||||
|
char *tskip();
|
||||||
|
char *tgetstr();
|
||||||
|
char *tdecode();
|
||||||
|
char *getenv();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Get an entry for terminal name in buffer bp,
|
||||||
|
* from the termcap file. Parse is very rudimentary;
|
||||||
|
* we just notice escaped newlines.
|
||||||
|
*/
|
||||||
|
tgetent(bp, name)
|
||||||
|
char *bp, *name;
|
||||||
|
{
|
||||||
|
register char *cp;
|
||||||
|
register int c;
|
||||||
|
register int i = 0, cnt = 0;
|
||||||
|
char ibuf[BUFSIZ];
|
||||||
|
int tf;
|
||||||
|
|
||||||
|
tbuf = bp;
|
||||||
|
tf = -1;
|
||||||
|
#ifndef V6
|
||||||
|
cp = getenv("TERMCAP");
|
||||||
|
/*
|
||||||
|
* TERMCAP can have one of two things in it. It can be the
|
||||||
|
* name of a file to use instead of /etc/termcap. In this
|
||||||
|
* case it better start with a "/". Or it can be an entry to
|
||||||
|
* use so we don't have to read the file. In this case it
|
||||||
|
* has to already have the newlines crunched out.
|
||||||
|
*/
|
||||||
|
if (cp && *cp) {
|
||||||
|
if (*cp == '/') {
|
||||||
|
tf = open(cp, 0);
|
||||||
|
} else {
|
||||||
|
tbuf = cp;
|
||||||
|
c = tnamatch(name);
|
||||||
|
tbuf = bp;
|
||||||
|
if (c) {
|
||||||
|
strcpy(bp,cp);
|
||||||
|
return(tnchktc());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (tf < 0)
|
||||||
|
tf = open(E_TERMCAP, 0);
|
||||||
|
#else
|
||||||
|
tf = open(E_TERMCAP, 0);
|
||||||
|
#endif
|
||||||
|
if (tf < 0)
|
||||||
|
return (-1);
|
||||||
|
for (;;) {
|
||||||
|
cp = bp;
|
||||||
|
for (;;) {
|
||||||
|
if (i == cnt) {
|
||||||
|
cnt = read(tf, ibuf, BUFSIZ);
|
||||||
|
if (cnt <= 0) {
|
||||||
|
close(tf);
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
i = 0;
|
||||||
|
}
|
||||||
|
c = ibuf[i++];
|
||||||
|
if (c == '\n') {
|
||||||
|
if (cp > bp && cp[-1] == '\\'){
|
||||||
|
cp--;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (cp >= bp+BUFSIZ) {
|
||||||
|
write(2,"Termcap entry too long\n", 23);
|
||||||
|
break;
|
||||||
|
} else
|
||||||
|
*cp++ = c;
|
||||||
|
}
|
||||||
|
*cp = 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The real work for the match.
|
||||||
|
*/
|
||||||
|
if (tnamatch(name)) {
|
||||||
|
close(tf);
|
||||||
|
return(tnchktc());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* tnchktc: check the last entry, see if it's tc=xxx. If so,
|
||||||
|
* recursively find xxx and append that entry (minus the names)
|
||||||
|
* to take the place of the tc=xxx entry. This allows termcap
|
||||||
|
* entries to say "like an HP2621 but doesn't turn on the labels".
|
||||||
|
* Note that this works because of the left to right scan.
|
||||||
|
*/
|
||||||
|
tnchktc()
|
||||||
|
{
|
||||||
|
register char *p, *q;
|
||||||
|
char tcname[16]; /* name of similar terminal */
|
||||||
|
char tcbuf[BUFSIZ];
|
||||||
|
char *holdtbuf = tbuf;
|
||||||
|
int l;
|
||||||
|
|
||||||
|
p = tbuf + strlen(tbuf) - 2; /* before the last colon */
|
||||||
|
while (*--p != ':')
|
||||||
|
if (p<tbuf) {
|
||||||
|
write(2, "Bad termcap entry\n", 18);
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
p++;
|
||||||
|
/* p now points to beginning of last field */
|
||||||
|
if (p[0] != 't' || p[1] != 'c')
|
||||||
|
return(1);
|
||||||
|
strcpy(tcname,p+3);
|
||||||
|
q = tcname;
|
||||||
|
while (*q && *q != ':')
|
||||||
|
q++;
|
||||||
|
*q = 0;
|
||||||
|
if (++hopcount > MAXHOP) {
|
||||||
|
write(2, "Infinite tc= loop\n", 18);
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
if (tgetent(tcbuf, tcname) != 1) {
|
||||||
|
hopcount = 0; /* unwind recursion */
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
for (q=tcbuf; *q != ':'; q++)
|
||||||
|
;
|
||||||
|
l = p - holdtbuf + strlen(q);
|
||||||
|
if (l > BUFSIZ) {
|
||||||
|
write(2, "Termcap entry too long\n", 23);
|
||||||
|
q[BUFSIZ - (p-tbuf)] = 0;
|
||||||
|
}
|
||||||
|
strcpy(p, q+1);
|
||||||
|
tbuf = holdtbuf;
|
||||||
|
hopcount = 0; /* unwind recursion */
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Tnamatch deals with name matching. The first field of the termcap
|
||||||
|
* entry is a sequence of names separated by |'s, so we compare
|
||||||
|
* against each such name. The normal : terminator after the last
|
||||||
|
* name (before the first field) stops us.
|
||||||
|
*/
|
||||||
|
tnamatch(np)
|
||||||
|
char *np;
|
||||||
|
{
|
||||||
|
register char *Np, *Bp;
|
||||||
|
|
||||||
|
Bp = tbuf;
|
||||||
|
if (*Bp == '#')
|
||||||
|
return(0);
|
||||||
|
for (;;) {
|
||||||
|
for (Np = np; *Np && *Bp == *Np; Bp++, Np++)
|
||||||
|
continue;
|
||||||
|
if (*Np == 0 && (*Bp == '|' || *Bp == ':' || *Bp == 0))
|
||||||
|
return (1);
|
||||||
|
while (*Bp && *Bp != ':' && *Bp != '|')
|
||||||
|
Bp++;
|
||||||
|
if (*Bp == 0 || *Bp == ':')
|
||||||
|
return (0);
|
||||||
|
Bp++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Skip to the next field. Notice that this is very dumb, not
|
||||||
|
* knowing about \: escapes or any such. If necessary, :'s can be put
|
||||||
|
* into the termcap file in octal.
|
||||||
|
*/
|
||||||
|
static char *
|
||||||
|
tskip(bp)
|
||||||
|
register char *bp;
|
||||||
|
{
|
||||||
|
|
||||||
|
while (*bp && *bp != ':')
|
||||||
|
bp++;
|
||||||
|
if (*bp == ':')
|
||||||
|
bp++;
|
||||||
|
return (bp);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Return the (numeric) option id.
|
||||||
|
* Numeric options look like
|
||||||
|
* li#80
|
||||||
|
* i.e. the option string is separated from the numeric value by
|
||||||
|
* a # character. If the option is not found we return -1.
|
||||||
|
* Note that we handle octal numbers beginning with 0.
|
||||||
|
*/
|
||||||
|
tgetnum(id)
|
||||||
|
char *id;
|
||||||
|
{
|
||||||
|
register int i, base;
|
||||||
|
register char *bp = tbuf;
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
bp = tskip(bp);
|
||||||
|
if (*bp == 0)
|
||||||
|
return (-1);
|
||||||
|
if (*bp++ != id[0] || *bp == 0 || *bp++ != id[1])
|
||||||
|
continue;
|
||||||
|
if (*bp == '@')
|
||||||
|
return(-1);
|
||||||
|
if (*bp != '#')
|
||||||
|
continue;
|
||||||
|
bp++;
|
||||||
|
base = 10;
|
||||||
|
if (*bp == '0')
|
||||||
|
base = 8;
|
||||||
|
i = 0;
|
||||||
|
while (isdigit(*bp))
|
||||||
|
i *= base, i += *bp++ - '0';
|
||||||
|
return (i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Handle a flag option.
|
||||||
|
* Flag options are given "naked", i.e. followed by a : or the end
|
||||||
|
* of the buffer. Return 1 if we find the option, or 0 if it is
|
||||||
|
* not given.
|
||||||
|
*/
|
||||||
|
tgetflag(id)
|
||||||
|
char *id;
|
||||||
|
{
|
||||||
|
register char *bp = tbuf;
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
bp = tskip(bp);
|
||||||
|
if (!*bp)
|
||||||
|
return (0);
|
||||||
|
if (*bp++ == id[0] && *bp != 0 && *bp++ == id[1]) {
|
||||||
|
if (!*bp || *bp == ':')
|
||||||
|
return (1);
|
||||||
|
else if (*bp == '@')
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Get a string valued option.
|
||||||
|
* These are given as
|
||||||
|
* cl=^Z
|
||||||
|
* Much decoding is done on the strings, and the strings are
|
||||||
|
* placed in area, which is a ref parameter which is updated.
|
||||||
|
* No checking on area overflow.
|
||||||
|
*/
|
||||||
|
char *
|
||||||
|
tgetstr(id, area)
|
||||||
|
char *id, **area;
|
||||||
|
{
|
||||||
|
register char *bp = tbuf;
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
bp = tskip(bp);
|
||||||
|
if (!*bp)
|
||||||
|
return (0);
|
||||||
|
if (*bp++ != id[0] || *bp == 0 || *bp++ != id[1])
|
||||||
|
continue;
|
||||||
|
if (*bp == '@')
|
||||||
|
return(0);
|
||||||
|
if (*bp != '=')
|
||||||
|
continue;
|
||||||
|
bp++;
|
||||||
|
return (tdecode(bp, area));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Tdecode does the grung work to decode the
|
||||||
|
* string capability escapes.
|
||||||
|
*/
|
||||||
|
static char *
|
||||||
|
tdecode(str, area)
|
||||||
|
register char *str;
|
||||||
|
char **area;
|
||||||
|
{
|
||||||
|
register char *cp;
|
||||||
|
register int c;
|
||||||
|
register char *dp;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
cp = *area;
|
||||||
|
while ((c = *str++) && c != ':') {
|
||||||
|
switch (c) {
|
||||||
|
|
||||||
|
case '^':
|
||||||
|
c = *str++ & 037;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case '\\':
|
||||||
|
dp = "E\033^^\\\\::n\nr\rt\tb\bf\f";
|
||||||
|
c = *str++;
|
||||||
|
nextc:
|
||||||
|
if (*dp++ == c) {
|
||||||
|
c = *dp++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
dp++;
|
||||||
|
if (*dp)
|
||||||
|
goto nextc;
|
||||||
|
if (isdigit(c)) {
|
||||||
|
c -= '0', i = 2;
|
||||||
|
do
|
||||||
|
c <<= 3, c |= *str++ - '0';
|
||||||
|
while (--i && isdigit(*str));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
*cp++ = c;
|
||||||
|
}
|
||||||
|
*cp++ = 0;
|
||||||
|
str = *area;
|
||||||
|
*area = cp;
|
||||||
|
return (str);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,180 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 1980 Regents of the University of California.
|
||||||
|
* All rights reserved. The Berkeley software License Agreement
|
||||||
|
* specifies the terms and conditions for redistribution.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef lint
|
||||||
|
static char sccsid[] = "@(#)tgoto.c 5.1 (Berkeley) 6/5/85";
|
||||||
|
#endif not lint
|
||||||
|
|
||||||
|
#define CTRL(c) ('c' & 037)
|
||||||
|
|
||||||
|
#define MAXRETURNSIZE 64
|
||||||
|
|
||||||
|
char *UP;
|
||||||
|
char *BC;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Routine to perform cursor addressing.
|
||||||
|
* CM is a string containing printf type escapes to allow
|
||||||
|
* cursor addressing. We start out ready to print the destination
|
||||||
|
* line, and switch each time we print row or column.
|
||||||
|
* The following escapes are defined for substituting row/column:
|
||||||
|
*
|
||||||
|
* %d as in printf
|
||||||
|
* %2 like %2d
|
||||||
|
* %3 like %3d
|
||||||
|
* %. gives %c hacking special case characters
|
||||||
|
* %+x like %c but adding x first
|
||||||
|
*
|
||||||
|
* The codes below affect the state but don't use up a value.
|
||||||
|
*
|
||||||
|
* %>xy if value > x add y
|
||||||
|
* %r reverses row/column
|
||||||
|
* %i increments row/column (for one origin indexing)
|
||||||
|
* %% gives %
|
||||||
|
* %B BCD (2 decimal digits encoded in one byte)
|
||||||
|
* %D Delta Data (backwards bcd)
|
||||||
|
*
|
||||||
|
* all other characters are ``self-inserting''.
|
||||||
|
*/
|
||||||
|
char *
|
||||||
|
tgoto(CM, destcol, destline)
|
||||||
|
char *CM;
|
||||||
|
int destcol, destline;
|
||||||
|
{
|
||||||
|
static char result[MAXRETURNSIZE];
|
||||||
|
static char added[10];
|
||||||
|
char *cp = CM;
|
||||||
|
register char *dp = result;
|
||||||
|
register int c;
|
||||||
|
int oncol = 0;
|
||||||
|
register int which = destline;
|
||||||
|
|
||||||
|
if (cp == 0) {
|
||||||
|
toohard:
|
||||||
|
/*
|
||||||
|
* ``We don't do that under BOZO's big top''
|
||||||
|
*/
|
||||||
|
return ("OOPS");
|
||||||
|
}
|
||||||
|
added[0] = 0;
|
||||||
|
while (c = *cp++) {
|
||||||
|
if (c != '%') {
|
||||||
|
*dp++ = c;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
switch (c = *cp++) {
|
||||||
|
|
||||||
|
#ifdef CM_N
|
||||||
|
case 'n':
|
||||||
|
destcol ^= 0140;
|
||||||
|
destline ^= 0140;
|
||||||
|
goto setwhich;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
case 'd':
|
||||||
|
if (which < 10)
|
||||||
|
goto one;
|
||||||
|
if (which < 100)
|
||||||
|
goto two;
|
||||||
|
/* fall into... */
|
||||||
|
|
||||||
|
case '3':
|
||||||
|
*dp++ = (which / 100) | '0';
|
||||||
|
which %= 100;
|
||||||
|
/* fall into... */
|
||||||
|
|
||||||
|
case '2':
|
||||||
|
two:
|
||||||
|
*dp++ = which / 10 | '0';
|
||||||
|
one:
|
||||||
|
*dp++ = which % 10 | '0';
|
||||||
|
swap:
|
||||||
|
oncol = 1 - oncol;
|
||||||
|
setwhich:
|
||||||
|
which = oncol ? destcol : destline;
|
||||||
|
continue;
|
||||||
|
|
||||||
|
#ifdef CM_GT
|
||||||
|
case '>':
|
||||||
|
if (which > *cp++)
|
||||||
|
which += *cp++;
|
||||||
|
else
|
||||||
|
cp++;
|
||||||
|
continue;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
case '+':
|
||||||
|
which += *cp++;
|
||||||
|
/* fall into... */
|
||||||
|
|
||||||
|
case '.':
|
||||||
|
casedot:
|
||||||
|
/*
|
||||||
|
* This code is worth scratching your head at for a
|
||||||
|
* while. The idea is that various weird things can
|
||||||
|
* happen to nulls, EOT's, tabs, and newlines by the
|
||||||
|
* tty driver, arpanet, and so on, so we don't send
|
||||||
|
* them if we can help it.
|
||||||
|
*
|
||||||
|
* Tab is taken out to get Ann Arbors to work, otherwise
|
||||||
|
* when they go to column 9 we increment which is wrong
|
||||||
|
* because bcd isn't continuous. We should take out
|
||||||
|
* the rest too, or run the thing through more than
|
||||||
|
* once until it doesn't make any of these, but that
|
||||||
|
* would make termlib (and hence pdp-11 ex) bigger,
|
||||||
|
* and also somewhat slower. This requires all
|
||||||
|
* programs which use termlib to stty tabs so they
|
||||||
|
* don't get expanded. They should do this anyway
|
||||||
|
* because some terminals use ^I for other things,
|
||||||
|
* like nondestructive space.
|
||||||
|
*/
|
||||||
|
if (which == 0 || which == CTRL(d) || /* which == '\t' || */ which == '\n') {
|
||||||
|
if (oncol || UP) /* Assumption: backspace works */
|
||||||
|
/*
|
||||||
|
* Loop needed because newline happens
|
||||||
|
* to be the successor of tab.
|
||||||
|
*/
|
||||||
|
do {
|
||||||
|
strcat(added, oncol ? (BC ? BC : "\b") : UP);
|
||||||
|
which++;
|
||||||
|
} while (which == '\n');
|
||||||
|
}
|
||||||
|
*dp++ = which;
|
||||||
|
goto swap;
|
||||||
|
|
||||||
|
case 'r':
|
||||||
|
oncol = 1;
|
||||||
|
goto setwhich;
|
||||||
|
|
||||||
|
case 'i':
|
||||||
|
destcol++;
|
||||||
|
destline++;
|
||||||
|
which++;
|
||||||
|
continue;
|
||||||
|
|
||||||
|
case '%':
|
||||||
|
*dp++ = c;
|
||||||
|
continue;
|
||||||
|
|
||||||
|
#ifdef CM_B
|
||||||
|
case 'B':
|
||||||
|
which = (which/10 << 4) + which%10;
|
||||||
|
continue;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef CM_D
|
||||||
|
case 'D':
|
||||||
|
which = which - 2 * (which%16);
|
||||||
|
continue;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
default:
|
||||||
|
goto toohard;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
strcpy(dp, added);
|
||||||
|
return (result);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,96 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 1980 Regents of the University of California.
|
||||||
|
* All rights reserved. The Berkeley software License Agreement
|
||||||
|
* specifies the terms and conditions for redistribution.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef lint
|
||||||
|
static char sccsid[] = "@(#)tputs.c 5.1 (Berkeley) 6/5/85";
|
||||||
|
#endif not lint
|
||||||
|
|
||||||
|
#include <sgtty.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The following array gives the number of tens of milliseconds per
|
||||||
|
* character for each speed as returned by gtty. Thus since 300
|
||||||
|
* baud returns a 7, there are 33.3 milliseconds per char at 300 baud.
|
||||||
|
*/
|
||||||
|
static
|
||||||
|
short tmspc10[] = {
|
||||||
|
0, 2000, 1333, 909, 743, 666, 500, 333, 166, 83, 55, 41, 20, 10, 5
|
||||||
|
};
|
||||||
|
|
||||||
|
short ospeed;
|
||||||
|
char PC;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Put the character string cp out, with padding.
|
||||||
|
* The number of affected lines is affcnt, and the routine
|
||||||
|
* used to output one character is outc.
|
||||||
|
*/
|
||||||
|
tputs(cp, affcnt, outc)
|
||||||
|
register char *cp;
|
||||||
|
int affcnt;
|
||||||
|
int (*outc)();
|
||||||
|
{
|
||||||
|
register int i = 0;
|
||||||
|
register int mspc10;
|
||||||
|
|
||||||
|
if (cp == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Convert the number representing the delay.
|
||||||
|
*/
|
||||||
|
if (isdigit(*cp)) {
|
||||||
|
do
|
||||||
|
i = i * 10 + *cp++ - '0';
|
||||||
|
while (isdigit(*cp));
|
||||||
|
}
|
||||||
|
i *= 10;
|
||||||
|
if (*cp == '.') {
|
||||||
|
cp++;
|
||||||
|
if (isdigit(*cp))
|
||||||
|
i += *cp - '0';
|
||||||
|
/*
|
||||||
|
* Only one digit to the right of the decimal point.
|
||||||
|
*/
|
||||||
|
while (isdigit(*cp))
|
||||||
|
cp++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If the delay is followed by a `*', then
|
||||||
|
* multiply by the affected lines count.
|
||||||
|
*/
|
||||||
|
if (*cp == '*')
|
||||||
|
cp++, i *= affcnt;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The guts of the string.
|
||||||
|
*/
|
||||||
|
while (*cp)
|
||||||
|
(*outc)(*cp++);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If no delay needed, or output speed is
|
||||||
|
* not comprehensible, then don't try to delay.
|
||||||
|
*/
|
||||||
|
if (i == 0)
|
||||||
|
return;
|
||||||
|
if (ospeed <= 0 || ospeed >= (sizeof tmspc10 / sizeof tmspc10[0]))
|
||||||
|
return;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Round up by a half a character frame,
|
||||||
|
* and then do the delay.
|
||||||
|
* Too bad there are no user program accessible programmed delays.
|
||||||
|
* Transmitting pad characters slows many
|
||||||
|
* terminals down and also loads the system.
|
||||||
|
*/
|
||||||
|
mspc10 = tmspc10[ospeed];
|
||||||
|
i += mspc10 / 2;
|
||||||
|
for (i /= mspc10; i > 0; i--)
|
||||||
|
(*outc)(PC);
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue