diff options
Diffstat (limited to 'games/larn/io.c')
-rw-r--r-- | games/larn/io.c | 915 |
1 files changed, 915 insertions, 0 deletions
diff --git a/games/larn/io.c b/games/larn/io.c new file mode 100644 index 0000000..dc0d5e7 --- /dev/null +++ b/games/larn/io.c @@ -0,0 +1,915 @@ +/* io.c Larn is copyrighted 1986 by Noah Morgan. + * + * Below are the functions in this file: + * + * setupvt100() Subroutine to set up terminal in correct mode for game + * clearvt100() Subroutine to clean up terminal when the game is over + * getchar() Routine to read in one character from the terminal + * scbr() Function to set cbreak -echo for the terminal + * sncbr() Function to set -cbreak echo for the terminal + * newgame() Subroutine to save the initial time and seed rnd() + * + * FILE OUTPUT ROUTINES + * + * lprintf(format,args . . .) printf to the output buffer + * lprint(integer) send binary integer to output buffer + * lwrite(buf,len) write a buffer to the output buffer + * lprcat(str) sent string to output buffer + * + * FILE OUTPUT MACROS (in header.h) + * + * lprc(character) put the character into the output buffer + * + * FILE INPUT ROUTINES + * + * long lgetc() read one character from input buffer + * long lrint() read one integer from input buffer + * lrfill(address,number) put input bytes into a buffer + * char *lgetw() get a whitespace ended word from input + * char *lgetl() get a \n or EOF ended line from input + * + * FILE OPEN / CLOSE ROUTINES + * + * lcreat(filename) create a new file for write + * lopen(filename) open a file for read + * lappend(filename) open for append to an existing file + * lrclose() close the input file + * lwclose() close output file + * lflush() flush the output buffer + * + * Other Routines + * + * cursor(x,y) position cursor at [x,y] + * cursors() position cursor at [1,24] (saves memory) + * cl_line(x,y) Clear line at [1,y] and leave cursor at [x,y] + * cl_up(x,y) Clear screen from [x,1] to current line. + * cl_dn(x,y) Clear screen from [1,y] to end of display. + * standout(str) Print the string in standout mode. + * set_score_output() Called when output should be literally printed. + ** putchar(ch) Print one character in decoded output buffer. + ** flush_buf() Flush buffer with decoded output. + ** init_term() Terminal initialization -- setup termcap info + ** char *tmcapcnv(sd,ss) Routine to convert VT100 \33's to termcap format + * beep() Routine to emit a beep if enabled (see no-beep in .larnopts) + * + * Note: ** entries are available only in termcap mode. + */ + +#include "header.h" + +#ifdef SYSV /* system III or system V */ +#include <termio.h> +#define sgttyb termio +#define stty(_a,_b) ioctl(_a,TCSETA,_b) +#define gtty(_a,_b) ioctl(_a,TCGETA,_b) +static int rawflg = 0; +static char saveeof,saveeol; +#define doraw(_a) if(!rawflg){++rawflg;saveeof=_a.c_cc[VMIN];saveeol=_a.c_cc[VTIME];}\ + _a.c_cc[VMIN]=1;_a.c_cc[VTIME]=1;_a.c_lflag &= ~(ICANON|ECHO|ECHOE|ECHOK|ECHONL) +#define unraw(_a) _a.c_cc[VMIN]=saveeof;_a.c_cc[VTIME]=saveeol;_a.c_lflag |= ICANON|ECHO|ECHOE|ECHOK|ECHONL + +#else not SYSV + +#ifndef BSD +#define CBREAK RAW /* V7 has no CBREAK */ +#endif + +#define doraw(_a) (_a.sg_flags |= CBREAK,_a.sg_flags &= ~ECHO) +#define unraw(_a) (_a.sg_flags &= ~CBREAK,_a.sg_flags |= ECHO) +#include <sgtty.h> +#endif not SYSV + +#ifndef NOVARARGS /* if we have varargs */ +#include <varargs.h> +#else NOVARARGS /* if we don't have varargs */ +typedef char *va_list; +#define va_dcl int va_alist; +#define va_start(plist) plist = (char *) &va_alist +#define va_end(plist) +#define va_arg(plist,mode) ((mode *)(plist += sizeof(mode)))[-1] +#endif NOVARARGS + +#define LINBUFSIZE 128 /* size of the lgetw() and lgetl() buffer */ +int lfd; /* output file numbers */ +int fd; /* input file numbers */ +static struct sgttyb ttx; /* storage for the tty modes */ +static int ipoint=MAXIBUF,iepoint=MAXIBUF; /* input buffering pointers */ +static char lgetwbuf[LINBUFSIZE]; /* get line (word) buffer */ + +/* + * setupvt100() Subroutine to set up terminal in correct mode for game + * + * Attributes off, clear screen, set scrolling region, set tty mode + */ +setupvt100() + { + clear(); setscroll(); scbr(); /* system("stty cbreak -echo"); */ + } + +/* + * clearvt100() Subroutine to clean up terminal when the game is over + * + * Attributes off, clear screen, unset scrolling region, restore tty mode + */ +clearvt100() + { + resetscroll(); clear(); sncbr(); /* system("stty -cbreak echo"); */ + } + +/* + * getchar() Routine to read in one character from the terminal + */ +getchar() + { + char byt; +#ifdef EXTRA + c[BYTESIN]++; +#endif + lflush(); /* be sure output buffer is flushed */ + read(0,&byt,1); /* get byte from terminal */ + return(byt); + } + +/* + * scbr() Function to set cbreak -echo for the terminal + * + * like: system("stty cbreak -echo") + */ +scbr() + { + gtty(0,&ttx); doraw(ttx); stty(0,&ttx); + } + +/* + * sncbr() Function to set -cbreak echo for the terminal + * + * like: system("stty -cbreak echo") + */ +sncbr() + { + gtty(0,&ttx); unraw(ttx); stty(0,&ttx); + } + +/* + * newgame() Subroutine to save the initial time and seed rnd() + */ +newgame() + { + register long *p,*pe; + for (p=c,pe=c+100; p<pe; *p++ =0); + time(&initialtime); srand(initialtime); + lcreat((char*)0); /* open buffering for output to terminal */ + } + +/* + * lprintf(format,args . . .) printf to the output buffer + * char *format; + * ??? args . . . + * + * Enter with the format string in "format", as per printf() usage + * and any needed arguments following it + * Note: lprintf() only supports %s, %c and %d, with width modifier and left + * or right justification. + * No correct checking for output buffer overflow is done, but flushes + * are done beforehand if needed. + * Returns nothing of value. + */ +#ifdef lint +/*VARARGS*/ +lprintf(str) + char *str; + { + char *str2; + str2 = str; + str = str2; /* to make lint happy */ + } +/*VARARGS*/ +sprintf(str) + char *str; + { + char *str2; + str2 = str; + str = str2; /* to make lint happy */ + } +#else lint +/*VARARGS*/ +lprintf(va_alist) +va_dcl + { + va_list ap; /* pointer for variable argument list */ + register char *fmt; + register char *outb,*tmpb; + register long wide,left,cont,n; /* data for lprintf */ + char db[12]; /* %d buffer in lprintf */ + + va_start(ap); /* initialize the var args pointer */ + fmt = va_arg(ap, char *); /* pointer to format string */ + if (lpnt >= lpend) lflush(); + outb = lpnt; + for ( ; ; ) + { + while (*fmt != '%') + if (*fmt) *outb++ = *fmt++; else { lpnt=outb; return; } + wide = 0; left = 1; cont=1; + while (cont) + switch(*(++fmt)) + { + case 'd': n = va_arg(ap, long); + if (n<0) { n = -n; *outb++ = '-'; if (wide) --wide; } + tmpb = db+11; *tmpb = (char)(n % 10 + '0'); + while (n>9) *(--tmpb) = (char)((n /= 10) % 10 + '0'); + if (wide==0) while (tmpb < db+12) *outb++ = *tmpb++; + else + { + wide -= db-tmpb+12; + if (left) while (wide-- > 0) *outb++ = ' '; + while (tmpb < db+12) *outb++ = *tmpb++; + if (left==0) while (wide-- > 0) *outb++ = ' '; + } + cont=0; break; + + case 's': tmpb = va_arg(ap, char *); + if (wide==0) { while (*outb++ = *tmpb++); --outb; } + else + { + n = wide - strlen(tmpb); + if (left) while (n-- > 0) *outb++ = ' '; + while (*outb++ = *tmpb++); --outb; + if (left==0) while (n-- > 0) *outb++ = ' '; + } + cont=0; break; + + case 'c': *outb++ = va_arg(ap, int); cont=0; break; + + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': wide = 10*wide + *fmt - '0'; break; + + case '-': left = 0; break; + + default: *outb++ = *fmt; cont=0; break; + }; + fmt++; + } + va_end(ap); + } +#endif lint + +/* + * lprint(long-integer) send binary integer to output buffer + * long integer; + * + * +---------+---------+---------+---------+ + * | high | | | low | + * | order | | | order | + * | byte | | | byte | + * +---------+---------+---------+---------+ + * 31 --- 24 23 --- 16 15 --- 8 7 --- 0 + * + * The save order is low order first, to high order (4 bytes total) + * and is written to be system independent. + * No checking for output buffer overflow is done, but flushes if needed! + * Returns nothing of value. + */ +lprint(x) + register long x; + { + if (lpnt >= lpend) lflush(); + *lpnt++ = 255 & x; *lpnt++ = 255 & (x>>8); + *lpnt++ = 255 & (x>>16); *lpnt++ = 255 & (x>>24); + } + +/* + * lwrite(buf,len) write a buffer to the output buffer + * char *buf; + * int len; + * + * Enter with the address and number of bytes to write out + * Returns nothing of value + */ +lwrite(buf,len) + register char *buf; + int len; + { + register char *str; + register int num2; + if (len > 399) /* don't copy data if can just write it */ + { +#ifdef EXTRA + c[BYTESOUT] += len; +#endif + +#ifndef VT100 + for (str=buf; len>0; --len) + lprc(*str++); +#else VT100 + lflush(); + write(lfd,buf,len); +#endif VT100 + } + else while (len) + { + if (lpnt >= lpend) lflush(); /* if buffer is full flush it */ + num2 = lpbuf+BUFBIG-lpnt; /* # bytes left in output buffer */ + if (num2 > len) num2=len; + str = lpnt; len -= num2; + while (num2--) *str++ = *buf++; /* copy in the bytes */ + lpnt = str; + } + } + +/* + * long lgetc() Read one character from input buffer + * + * Returns 0 if EOF, otherwise the character + */ +long lgetc() + { + register int i; + if (ipoint != iepoint) return(inbuffer[ipoint++]); + if (iepoint!=MAXIBUF) return(0); + if ((i=read(fd,inbuffer,MAXIBUF))<=0) + { + if (i!=0) write(1,"error reading from input file\n",30); + iepoint = ipoint = 0; return(0); + } + ipoint=1; iepoint=i; return(*inbuffer); + } + +/* + * long lrint() Read one integer from input buffer + * + * +---------+---------+---------+---------+ + * | high | | | low | + * | order | | | order | + * | byte | | | byte | + * +---------+---------+---------+---------+ + * 31 --- 24 23 --- 16 15 --- 8 7 --- 0 + * + * The save order is low order first, to high order (4 bytes total) + * Returns the int read + */ +long lrint() + { + register unsigned long i; + i = 255 & lgetc(); i |= (255 & lgetc()) << 8; + i |= (255 & lgetc()) << 16; i |= (255 & lgetc()) << 24; + return(i); + } + +/* + * lrfill(address,number) put input bytes into a buffer + * char *address; + * int number; + * + * Reads "number" bytes into the buffer pointed to by "address". + * Returns nothing of value + */ +lrfill(adr,num) + register char *adr; + int num; + { + register char *pnt; + register int num2; + while (num) + { + if (iepoint == ipoint) + { + if (num>5) /* fast way */ + { + if (read(fd,adr,num) != num) + write(2,"error reading from input file\n",30); + num=0; + } + else { *adr++ = lgetc(); --num; } + } + else + { + num2 = iepoint-ipoint; /* # of bytes left in the buffer */ + if (num2 > num) num2=num; + pnt = inbuffer+ipoint; num -= num2; ipoint += num2; + while (num2--) *adr++ = *pnt++; + } + } + } + +/* + * char *lgetw() Get a whitespace ended word from input + * + * Returns pointer to a buffer that contains word. If EOF, returns a NULL + */ +char *lgetw() + { + register char *lgp,cc; + register int n=LINBUFSIZE,quote=0; + lgp = lgetwbuf; + do cc=lgetc(); while ((cc <= 32) && (cc > NULL)); /* eat whitespace */ + for ( ; ; --n,cc=lgetc()) + { + if ((cc==NULL) && (lgp==lgetwbuf)) return(NULL); /* EOF */ + if ((n<=1) || ((cc<=32) && (quote==0))) { *lgp=NULL; return(lgetwbuf); } + if (cc != '"') *lgp++ = cc; else quote ^= 1; + } + } + +/* + * char *lgetl() Function to read in a line ended by newline or EOF + * + * Returns pointer to a buffer that contains the line. If EOF, returns NULL + */ +char *lgetl() + { + register int i=LINBUFSIZE,ch; + register char *str=lgetwbuf; + for ( ; ; --i) + { + if ((*str++ = ch = lgetc()) == NULL) + { + if (str == lgetwbuf+1) return(NULL); /* EOF */ + ot: *str = NULL; return(lgetwbuf); /* line ended by EOF */ + } + if ((ch=='\n') || (i<=1)) goto ot; /* line ended by \n */ + } + } + +/* + * lcreat(filename) Create a new file for write + * char *filename; + * + * lcreat((char*)0); means to the terminal + * Returns -1 if error, otherwise the file descriptor opened. + */ +lcreat(str) + char *str; + { + lpnt = lpbuf; lpend = lpbuf+BUFBIG; + if (str==NULL) return(lfd=1); + if ((lfd=creat(str,0644)) < 0) + { + lfd=1; lprintf("error creating file <%s>\n",str); lflush(); return(-1); + } + return(lfd); + } + +/* + * lopen(filename) Open a file for read + * char *filename; + * + * lopen(0) means from the terminal + * Returns -1 if error, otherwise the file descriptor opened. + */ +lopen(str) + char *str; + { + ipoint = iepoint = MAXIBUF; + if (str==NULL) return(fd=0); + if ((fd=open(str,0)) < 0) + { + lwclose(); lfd=1; lpnt=lpbuf; return(-1); + } + return(fd); + } + +/* + * lappend(filename) Open for append to an existing file + * char *filename; + * + * lappend(0) means to the terminal + * Returns -1 if error, otherwise the file descriptor opened. + */ +lappend(str) + char *str; + { + lpnt = lpbuf; lpend = lpbuf+BUFBIG; + if (str==NULL) return(lfd=1); + if ((lfd=open(str,2)) < 0) + { + lfd=1; return(-1); + } + lseek(lfd,0,2); /* seek to end of file */ + return(lfd); + } + +/* + * lrclose() close the input file + * + * Returns nothing of value. + */ +lrclose() + { + if (fd > 0) close(fd); + } + +/* + * lwclose() close output file flushing if needed + * + * Returns nothing of value. + */ +lwclose() + { + lflush(); if (lfd > 2) close(lfd); + } + +/* + * lprcat(string) append a string to the output buffer + * avoids calls to lprintf (time consuming) + */ +lprcat(str) + register char *str; + { + register char *str2; + if (lpnt >= lpend) lflush(); + str2 = lpnt; + while (*str2++ = *str++); + lpnt = str2 - 1; + } + +#ifdef VT100 +/* + * cursor(x,y) Subroutine to set the cursor position + * + * x and y are the cursor coordinates, and lpbuff is the output buffer where + * escape sequence will be placed. + */ +static char *y_num[]= { "\33[","\33[","\33[2","\33[3","\33[4","\33[5","\33[6", + "\33[7","\33[8","\33[9","\33[10","\33[11","\33[12","\33[13","\33[14", + "\33[15","\33[16","\33[17","\33[18","\33[19","\33[20","\33[21","\33[22", + "\33[23","\33[24" }; + +static char *x_num[]= { "H","H",";2H",";3H",";4H",";5H",";6H",";7H",";8H",";9H", + ";10H",";11H",";12H",";13H",";14H",";15H",";16H",";17H",";18H",";19H", + ";20H",";21H",";22H",";23H",";24H",";25H",";26H",";27H",";28H",";29H", + ";30H",";31H",";32H",";33H",";34H",";35H",";36H",";37H",";38H",";39H", + ";40H",";41H",";42H",";43H",";44H",";45H",";46H",";47H",";48H",";49H", + ";50H",";51H",";52H",";53H",";54H",";55H",";56H",";57H",";58H",";59H", + ";60H",";61H",";62H",";63H",";64H",";65H",";66H",";67H",";68H",";69H", + ";70H",";71H",";72H",";73H",";74H",";75H",";76H",";77H",";78H",";79H", + ";80H" }; + +cursor(x,y) + int x,y; + { + register char *p; + if (lpnt >= lpend) lflush(); + + p = y_num[y]; /* get the string to print */ + while (*p) *lpnt++ = *p++; /* print the string */ + + p = x_num[x]; /* get the string to print */ + while (*p) *lpnt++ = *p++; /* print the string */ + } +#else VT100 +/* + * cursor(x,y) Put cursor at specified coordinates staring at [1,1] (termcap) + */ +cursor (x,y) + int x,y; + { + if (lpnt >= lpend) lflush (); + + *lpnt++ = CURSOR; *lpnt++ = x; *lpnt++ = y; + } +#endif VT100 + +/* + * Routine to position cursor at beginning of 24th line + */ +cursors() + { + cursor(1,24); + } + +#ifndef VT100 +/* + * Warning: ringing the bell is control code 7. Don't use in defines. + * Don't change the order of these defines. + * Also used in helpfiles. Codes used in helpfiles should be \E[1 to \E[7 with + * obvious meanings. + */ + +static char cap[256]; +char *CM, *CE, *CD, *CL, *SO, *SE, *AL, *DL;/* Termcap capabilities */ +static char *outbuf=0; /* translated output buffer */ + +int putchar (); + +/* + * init_term() Terminal initialization -- setup termcap info + */ +init_term() + { + char termbuf[1024]; + char *capptr = cap+10; + char *term; + + switch (tgetent(termbuf, term = getenv("TERM"))) + { + case -1: + write(2, "Cannot open termcap file.\n", 26); exit(); + case 0: + write(2, "Cannot find entry of ", 21); + write(2, term, strlen (term)); + write(2, " in termcap\n", 12); + exit(); + }; + + CM = tgetstr("cm", &capptr); /* Cursor motion */ + CE = tgetstr("ce", &capptr); /* Clear to eoln */ + CL = tgetstr("cl", &capptr); /* Clear screen */ + +/* OPTIONAL */ + AL = tgetstr("al", &capptr); /* Insert line */ + DL = tgetstr("dl", &capptr); /* Delete line */ + SO = tgetstr("so", &capptr); /* Begin standout mode */ + SE = tgetstr("se", &capptr); /* End standout mode */ + CD = tgetstr("cd", &capptr); /* Clear to end of display */ + + if (!CM) /* can't find cursor motion entry */ + { + write(2, "Sorry, for a ",13); write(2, term, strlen(term)); + write(2, ", I can't find the cursor motion entry in termcap\n",50); + exit(); + } + if (!CE) /* can't find clear to end of line entry */ + { + write(2, "Sorry, for a ",13); write(2, term, strlen(term)); + write(2,", I can't find the clear to end of line entry in termcap\n",57); + exit(); + } + if (!CL) /* can't find clear entire screen entry */ + { + write(2, "Sorry, for a ",13); write(2, term, strlen(term)); + write(2, ", I can't find the clear entire screen entry in termcap\n",56); + exit(); + } + if ((outbuf=malloc(BUFBIG+16))==0) /* get memory for decoded output buffer*/ + { + write(2,"Error malloc'ing memory for decoded output buffer\n",50); + died(-285); /* malloc() failure */ + } + } +#endif VT100 + +/* + * cl_line(x,y) Clear the whole line indicated by 'y' and leave cursor at [x,y] + */ +cl_line(x,y) + int x,y; + { +#ifdef VT100 + cursor(x,y); lprcat("\33[2K"); +#else VT100 + cursor(1,y); *lpnt++ = CL_LINE; cursor(x,y); +#endif VT100 + } + +/* + * cl_up(x,y) Clear screen from [x,1] to current position. Leave cursor at [x,y] + */ +cl_up(x,y) + register int x,y; + { +#ifdef VT100 + cursor(x,y); lprcat("\33[1J\33[2K"); +#else VT100 + register int i; + cursor(1,1); + for (i=1; i<=y; i++) { *lpnt++ = CL_LINE; *lpnt++ = '\n'; } + cursor(x,y); +#endif VT100 + } + +/* + * cl_dn(x,y) Clear screen from [1,y] to end of display. Leave cursor at [x,y] + */ +cl_dn(x,y) + register int x,y; + { +#ifdef VT100 + cursor(x,y); lprcat("\33[J\33[2K"); +#else VT100 + register int i; + cursor(1,y); + if (!CD) + { + *lpnt++ = CL_LINE; + for (i=y; i<=24; i++) { *lpnt++ = CL_LINE; if (i!=24) *lpnt++ = '\n'; } + cursor(x,y); + } + else + *lpnt++ = CL_DOWN; + cursor(x,y); +#endif VT100 + } + +/* + * standout(str) Print the argument string in inverse video (standout mode). + */ +standout(str) + register char *str; + { +#ifdef VT100 + setbold(); + while (*str) + *lpnt++ = *str++; + resetbold(); +#else VT100 + *lpnt++ = ST_START; + while (*str) + *lpnt++ = *str++; + *lpnt++ = ST_END; +#endif VT100 + } + +/* + * set_score_output() Called when output should be literally printed. + */ +set_score_output() + { + enable_scroll = -1; + } + +/* + * lflush() Flush the output buffer + * + * Returns nothing of value. + * for termcap version: Flush output in output buffer according to output + * status as indicated by `enable_scroll' + */ +#ifndef VT100 +static int scrline=18; /* line # for wraparound instead of scrolling if no DL */ +lflush () + { + register int lpoint; + register char *str; + static int curx = 0; + static int cury = 0; + + if ((lpoint = lpnt - lpbuf) > 0) + { +#ifdef EXTRA + c[BYTESOUT] += lpoint; +#endif + if (enable_scroll <= -1) + { + flush_buf(); + if (write(lfd,lpbuf,lpoint) != lpoint) + write(2,"error writing to output file\n",29); + lpnt = lpbuf; /* point back to beginning of buffer */ + return; + } + for (str = lpbuf; str < lpnt; str++) + { + if (*str>=32) { putchar (*str); curx++; } + else switch (*str) + { + case CLEAR: tputs (CL, 0, putchar); curx = cury = 0; + break; + + case CL_LINE: tputs (CE, 0, putchar); + break; + + case CL_DOWN: tputs (CD, 0, putchar); + break; + + case ST_START: tputs (SO, 0, putchar); + break; + + case ST_END: tputs (SE, 0, putchar); + break; + + case CURSOR: curx = *++str - 1; cury = *++str - 1; + tputs (tgoto (CM, curx, cury), 0, putchar); + break; + + case '\n': if ((cury == 23) && enable_scroll) + { + if (!DL || !AL) /* wraparound or scroll? */ + { + if (++scrline > 23) scrline=19; + + if (++scrline > 23) scrline=19; + tputs (tgoto (CM, 0, scrline), 0, putchar); + tputs (CE, 0, putchar); + + if (--scrline < 19) scrline=23; + tputs (tgoto (CM, 0, scrline), 0, putchar); + tputs (CE, 0, putchar); + } + else + { + tputs (tgoto (CM, 0, 19), 0, putchar); + tputs (DL, 0, putchar); + tputs (tgoto (CM, 0, 23), 0, putchar); + /* tputs (AL, 0, putchar); */ + } + } + else + { + putchar ('\n'); cury++; + } + curx = 0; + break; + + default: putchar (*str); curx++; + }; + } + } + lpnt = lpbuf; + flush_buf(); /* flush real output buffer now */ + } +#else VT100 +/* + * lflush() flush the output buffer + * + * Returns nothing of value. + */ +lflush() + { + register int lpoint; + if ((lpoint = lpnt - lpbuf) > 0) + { +#ifdef EXTRA + c[BYTESOUT] += lpoint; +#endif + if (write(lfd,lpbuf,lpoint) != lpoint) + write(2,"error writing to output file\n",29); + } + lpnt = lpbuf; /* point back to beginning of buffer */ + } +#endif VT100 + +#ifndef VT100 +static int index=0; +/* + * putchar(ch) Print one character in decoded output buffer. + */ +int putchar(c) +int c; + { + outbuf[index++] = c; + if (index >= BUFBIG) flush_buf(); + } + +/* + * flush_buf() Flush buffer with decoded output. + */ +flush_buf() + { + if (index) write(lfd, outbuf, index); + index = 0; + } + +/* + * char *tmcapcnv(sd,ss) Routine to convert VT100 escapes to termcap format + * + * Processes only the \33[#m sequence (converts . files for termcap use + */ +char *tmcapcnv(sd,ss) + register char *sd,*ss; + { + register int tmstate=0; /* 0=normal, 1=\33 2=[ 3=# */ + char tmdigit=0; /* the # in \33[#m */ + while (*ss) + { + switch(tmstate) + { + case 0: if (*ss=='\33') { tmstate++; break; } + ign: *sd++ = *ss; + ign2: tmstate = 0; + break; + case 1: if (*ss!='[') goto ign; + tmstate++; + break; + case 2: if (isdigit(*ss)) { tmdigit= *ss-'0'; tmstate++; break; } + if (*ss == 'm') { *sd++ = ST_END; goto ign2; } + goto ign; + case 3: if (*ss == 'm') + { + if (tmdigit) *sd++ = ST_START; + else *sd++ = ST_END; + goto ign2; + } + default: goto ign; + }; + ss++; + } + *sd=0; /* NULL terminator */ + return(sd); + } +#endif VT100 + +/* + * beep() Routine to emit a beep if enabled (see no-beep in .larnopts) + */ +beep() + { + if (!nobeep) *lpnt++ = '\7'; + } |