📄 otic.c
字号:
; beg_next--; /* Now shuffle string around. */ strcpy(restbuf, beg_next); p = index(tcbuf, SEPARATE); if (p == NULL) p = tcbuf; else p++; strcpy(beg_use, p); p = index(beg_use, '\0'); strcpy(p, restbuf); }}/* * Tnamatch deals with name matching. The first field of the terminfo * entry is a sequence of names separated by |'s, so we compare * against each such name. The normal SEPARATE terminator after the last * name (before the first field) stops us. */tnamatch(np) char *np;{ register char *Np, *Bp;/* printf("tnamatch, np '%s', tbuf '%s'\n", np, tbuf); */ Bp = tbuf; if (*Bp == COMMENT) return(0); for (;;) { for (Np = np; *Np && *Bp == *Np; Bp++, Np++) ; if (*Np == 0 && (*Bp == NAMESEPARATOR || *Bp == SEPARATE || *Bp == 0)) return (1); while (*Bp && *Bp != SEPARATE && *Bp != NAMESEPARATOR) Bp++; if (*Bp == 0 || *Bp == SEPARATE) return (0); Bp++; }}/* * Skip to the next SEPARATE delimited field. Allow \SEPARATE escape. */static char *tskip(bp) register char *bp;{ while (*bp && *bp != SEPARATE) if ((*bp++ == '\\') && *bp) bp++; if (*bp == 0) return bp; bp++; while (isspace(*bp) || *bp == SEPARATE) 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; int idl = strlen(id); int sign = 1; for (;;) { bp = tskip(bp); if (*bp == 0) return (-1); if (strncmp(id, bp, idl)) continue; bp += idl; if (*bp == CANCEL) return(-1); if (*bp != NUMBER) continue; bp++; if (*bp == '-') { sign = -1; bp++; } base = 10; if (*bp == '0') { base = 8; bp++; } if (*bp == 'x' || *bp == 'X') { base = 16; bp++; } i = 0; switch (base) { case 8: while (*bp >= '0' && *bp <= '7') { i *= 8; i += *bp++ - '0'; } break; case 10:while (isdigit(*bp)) { i *= 10; i += *bp++ - '0'; } break; case 16:while (isdigit(*bp) || (*bp >= 'a' && *bp <= 'f') || (*bp >= 'A' && *bp <= 'F')) { i *= 16; if (isdigit(*bp)) i += *bp++ - '0'; else if (*bp >= 'a' && *bp <= 'f') i += *bp++ - 'a' + 10; else i += *bp++ - 'A' + 10; } break; } i *= sign; return (i); }}/* * Handle a flag option. * Flag options are given "naked", i.e. followed by a SEPARATE or the end * of the buffer. Return 1 if we find the option, or 0 if it is * not given or is cancelled. */tgetflag(id) char *id;{ register char *bp = tbuf; int idl = strlen(id); for (;;) { bp = tskip(bp); if (!*bp) return (0); if (strncmp(bp, id, idl) == 0) { bp += idl; if (!*bp || *bp == SEPARATE) return (1); else if (*bp == CANCEL) 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; int idl = strlen(id); for (;;) { bp = tskip(bp); if (!*bp) return (0); if (strncmp(id, bp, idl)) continue; bp += idl; if (*bp == CANCEL) return(0); if (*bp != STRING) 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 != SEPARATE) { switch (c) { case '^': c = *str++ & 037; if (c == 0) c = 0200; break; case '\\': /* * \x escapes understood: * \e escape * \E escape * \^ ^ * \\ \ * \, , * \: : * \l linefeed * \n newline (=linefeed) * \r return * \t tab * \b backspace * \f formfeed * \s space * \0 null * \### octal ### */ dp = "e\033E\033^^\\\\,,::l\012n\nr\rt\tb\bf\fs "; c = *str++;nextc: if (*dp++ == c) { c = *dp++; break; } dp++; if (*dp) goto nextc; if (c >= '0' && c <= '7') { c -= '0'; i = 2; do { if (*str < '0' || *str > '7') break; c <<= 3; c |= *str++ - '0'; } while (--i); if (c == 0) c = 0200; /* don't term. str. */ } break; } *cp++ = c; } *cp++ = 0; str = *area; *area = cp; return (str);}#define TIMAGNUM 0432unstr(cp)char *cp;{ if (cp) for ( ; *cp ; cp++) if ((*cp & 0377) < 0200) printf("%s", unctrl(*cp)); else printf("M-%s", unctrl(*cp));}store(cap)char *cap;{ register char *cp; register int i; register char **pp, **np; char tcpbuf[2048 /* 1024 */]; char *tcp = tcpbuf; char *tname = cap; char *tnp; char tnbuf[256], names[256]; char fnbuf[128 /* 64 */], lnbuf[128 /* 64 */]; char strtab[8192 /* 4096 */]; register char *strtabptr; FILE *fd; int sname, sbool; while (*cap != SEPARATE) /* skip over names */ cap++; *cap = 0; strcpy(tnbuf, tname); strcpy(names, tname); *cap = SEPARATE; for (tnp=tnbuf; *tnp && *tnp != NAMESEPARATOR && *tnp != SEPARATE; tnp++) ; if (*tnp) *tnp++ = 0; if (terminfo) { strcpy(fnbuf, terminfo); strcat(fnbuf, "/"); } else { strcpy(fnbuf, termpath(/)); } strcat(fnbuf, tnbuf); checkon(fnbuf); if (verbose) printf("create '%s'\n", fnbuf); fd = fopen(fnbuf, "w"); if (fd == NULL) { perror(fnbuf); return; } putsh(TIMAGNUM, fd); sname = strlen(names)+1; putsh(sname, fd); sbool = listlen(boolcodes); putsh(sbool, fd); putsh(listlen(numcodes), fd); putsh(listlen(strcodes), fd); putsh(0, fd); /* length of string table */ /* Write out various terminal names to file, null terminated. */ for (cp=names; *cp; cp++) putc(*cp, fd); putc(0, fd); /* Write out the booleans: flag */ for (pp=boolnames, np=boolcodes; *np; pp++,np++) { i = tgetflag(*pp); putc(i, fd); if (verbose > 2) printf("bool cap %s code %s val %d\n", *pp, *np, i); } if ((sname + sbool) & 1) putc(0, fd); /* Numbers: highbyte, lowbyte. 0377,0377 means -1 (missing) */ for (pp=numnames, np=numcodes; *np; pp++,np++) { i = tgetnum(*pp); putsh(i, fd); if (verbose > 1) printf("num cap %s code %s val %d\n", *pp, *np, i); } /* Strings: offset into string table. If cap is missing, -1 is used */ strtabptr = strtab; for (pp=strnames, np=strcodes; *np; pp++,np++) { cp = tgetstr(*pp, &tcp); if (verbose > 3) if (cp) { printf("str %s code %s val ", *pp, *np); unstr(cp); printf("\n"); } else printf("str %s code %s val NULL\n", *pp, *np); if (cp) { putsh(strtabptr-strtab, fd); while (*strtabptr++ = *cp++) ; } else { putsh(-1, fd); } } fwrite(strtab, 1, strtabptr-strtab, fd); fseek(fd, 10L, 0); /* Back to string table size in header */ putsh(strtabptr-strtab, fd); fclose(fd); while (*tnp) { i = 0; for (tname=tnp; *tnp && *tnp != NAMESEPARATOR && *tnp != SEPARATE; tnp++) if (isspace(*tnp)) i = 1; if (*tnp) *tnp++ = 0; if (i) continue; if (terminfo) { strcpy(lnbuf, terminfo); strcat(lnbuf, "/"); } else { strcpy(lnbuf, termpath(/)); } strcat(lnbuf, tname); checkon(lnbuf); if (verbose) printf("link '%s' '%s'\n", fnbuf, lnbuf); if (link(fnbuf, lnbuf) < 0) { fprintf(stderr, "Can't link %s to %s: ", fnbuf, lnbuf); perror(""); } }}/* * Write a short out to the file in machine-independent format. */putsh(val, fd)register val;FILE *fd;{ if (val != -1) { putc(val&0377, fd); putc((val>>8)&0377, fd); } else { /* Write -1 as two 0377's. */ putc(0377, fd); putc(0377, fd); }}listlen(list)register char **list;{ register int rv = 0; while (*list) { list++; rv++; } return rv;}/* * Do various processing on a file name we are about to create. * If it already exists, and it's older than we started, unlink it. * Also insert a / after the 2nd char of the tail, and make sure * that directory exists. */checkon(fn)char *fn;{ struct stat stbuf; char *fp, *cp; char nbuf[64]; /* Find last / */ for (cp=fn; *cp; cp++) if (*cp == '/') fp = cp; if (cp-fp > 2) { cp = fp+2; strcpy(nbuf, fp+1); *cp = 0; if (stat(fn, &stbuf) < 0) { if (verbose) printf("mkdir %s\n", fn); if (mkdir(fn, 0777) < 0) { perror(fn); return; } } *cp++ = '/'; strcpy(cp, nbuf); } else printf("%s: terminal name too short\n", fp+1); if (stat(fn, &stbuf) < 0) return; if (stbuf.st_mtime < starttime) { if (verbose > 1) printf("unlink %s\n", fn); unlink(fn); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -