📄 io.c
字号:
}/* * 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 VT100static 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 VT100static 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'; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -