sh.lex.c
来自「<B>Digital的Unix操作系统VAX 4.2源码</B>」· C语言 代码 · 共 1,440 行 · 第 1/2 页
C
1,440 行
if (c != delim /* && c != '~' */) *cp++ = '\\'; } *cp++ = c; } *cp++ = 0; break; default: if (c == '\n') unreadc(c); seterrc("Bad ! modifier: ", (char) c); goto ret; } (void) strcpy(slhs, lhsb); if (exclc) en = dosub(sc, en, global);ret: return (en);}struct wordent *dosub(sc, en, global) int sc; struct wordent *en; bool global;{ struct wordent lex; bool didsub = 0; struct wordent *hp = &lex; register struct wordent *wdp; register int i = exclc; wdp = hp; while (--i >= 0) { register struct wordent *new = (struct wordent *) calloc(1, sizeof *wdp); new->prev = wdp; new->next = hp; wdp->next = new; wdp = new; en = en->next; wdp->word = global || didsub == 0 ? subword(en->word, sc, &didsub) : savestr(en->word); } if (didsub == 0) seterr("Modifier failed"); hp->prev = wdp; return (&enthist(-1000, &lex, 0)->Hlex);}char *subword(cp, type, adid) char *cp; int type; bool *adid;{ char wbuf[BUFSIZ]; register char *wp, *mp, *np; register int i; switch (type) { case 'r': case 'e': case 'h': case 't': case 'q': case 'x': wp = domod(cp, type); if (wp == 0) return (savestr(cp)); *adid = 1; return (wp); default: wp = wbuf; i = BUFSIZ - 4; for (mp = cp; *mp; mp++) if (matchs(mp, lhsb)) { for (np = cp; np < mp;) *wp++ = *np++, --i; for (np = rhsb; *np; np++) switch (*np) { case '\\': if (np[1] == '&') np++; /* fall into ... */ default: if (--i < 0) goto ovflo; *wp++ = *np; continue; case '&': i -= strlen(lhsb); if (i < 0) goto ovflo; *wp = 0; (void) strcat(wp, lhsb); wp = strend(wp); continue; } mp += strlen(lhsb); i -= strlen(mp); if (i < 0) {ovflo: seterr("Subst buf ovflo"); return (""); } *wp = 0; (void) strcat(wp, mp); *adid = 1; return (savestr(wbuf)); } return (savestr(cp)); }}char *domod(cp, type) char *cp; int type;{ char wbuf[BUFSIZ]; register char *wp, *xp; register int c; switch (type) { case 'x': case 'q': for (xp = wbuf; c = *cp++; ) { if ((c != ' ' && c != '\t') || type == 'q') *xp++ = QUOTECHAR; *xp++ = c; } *xp = '\0'; return (savestr(wbuf)); case 'h': case 't': if (!any('/', cp)) return (type == 't' ? savestr(cp) : 0); wp = strend(cp); while (*--wp != '/') continue; if (type == 'h') xp = savestr(cp), xp[wp - cp] = 0; else xp = savestr(wp + 1); return (xp); case 'e': case 'r': wp = strend(cp); for (wp--; wp >= cp && *wp != '/'; wp--) if (*wp == '.') { if (type == 'e') xp = savestr(wp + 1); else xp = savestr(cp), xp[wp - cp] = 0; return (xp); } return (savestr(type == 'e' ? "" : cp)); } return (0);}matchs(str, pat) register char *str, *pat;{ while (*str && *pat && *str == *pat) str++, pat++; return (*pat == 0);}getsel(al, ar, dol) register int *al, *ar; int dol;{ register int c = getC(0); register int i; bool first = *al < 0; switch (c) { case '%': if (quesarg == -1) goto bad; if (*al < 0) *al = quesarg; *ar = quesarg; break; case '-': if (*al < 0) { *al = 0; *ar = dol - 1; unreadc(c); } return (1); case '^': if (*al < 0) *al = 1; *ar = 1; break; case '$': if (*al < 0) *al = dol; *ar = dol; break; case '*': if (*al < 0) *al = 1; *ar = dol; if (*ar < *al) { *ar = 0; *al = 1; return (1); } break; default: if (digit(c)) { i = 0; while (digit(c)) { i = i * 10 + c - '0'; c = getC(0); } if (i < 0) i = dol + 1; if (*al < 0) *al = i; *ar = i; } else if (*al < 0) *al = 0, *ar = dol; else *ar = dol - 1; unreadc(c); break; } if (first) { c = getC(0); unreadc(c); if (any(c, "-$*")) return (1); } if (*al > *ar || *ar > dol) {bad: seterr("Bad ! arg selector"); return (0); } return (1);}struct wordent *gethent(sc) int sc;{ register struct Hist *hp; register char *np; register int c; int event; bool back = 0; c = sc == HISTSUB ? HIST : getC(0); if (c == HIST) { if (alhistp) return (alhistp); event = eventno; goto skip; } switch (c) { case ':': case '^': case '$': case '*': case '%': ungetC(c); if (lastev == eventno && alhistp) return (alhistp); event = lastev; break; case '-': back = 1; c = getC(0); goto number; case '#': /* !# is command being typed in (mrh) */ return(¶ml); default: if (any(c, "(=~")) { unreadc(c); ungetC(HIST); return (0); } if (digit(c)) goto number; np = lhsb; while (!any(c, ": \t\\\n}")) { if (np < &lhsb[sizeof lhsb - 2]) *np++ = c; c = getC(0); } unreadc(c); if (np == lhsb) { ungetC(HIST); return (0); } *np++ = 0; hp = findev(lhsb, 0); if (hp) lastev = hp->Hnum; return (&hp->Hlex); case '?': np = lhsb; for (;;) { c = getC(0); if (c == '\n') { unreadc(c); break; } if (c == '?') break; if (np < &lhsb[sizeof lhsb - 2]) *np++ = c; } if (np == lhsb) { if (lhsb[0] == 0) { seterr("No prev search"); return (0); } } else *np++ = 0; hp = findev(lhsb, 1); if (hp) lastev = hp->Hnum; return (&hp->Hlex); number: event = 0; while (digit(c)) { event = event * 10 + c - '0'; c = getC(0); } if (back) event = eventno + (alhistp == 0) - (event ? event : 0); unreadc(c); break; }skip: for (hp = Histlist.Hnext; hp; hp = hp->Hnext) if (hp->Hnum == event) { hp->Href = eventno; lastev = hp->Hnum; return (&hp->Hlex); } np = putn(event); noev(np); return (0);}struct Hist *findev(cp, anyarg) char *cp; bool anyarg;{ register struct Hist *hp; for (hp = Histlist.Hnext; hp; hp = hp->Hnext) { char *dp; register char *p, *q; register struct wordent *lp = hp->Hlex.next; int argno = 0; if (lp->word[0] == '\n') continue; if (!anyarg) { p = cp; q = lp->word; do if (!*p) return (hp); while (*p++ == *q++); continue; } do { for (dp = lp->word; *dp; dp++) { p = cp; q = dp; do if (!*p) { quesarg = argno; return (hp); } while (*p++ == *q++); } lp = lp->next; argno++; } while (lp->word[0] != '\n'); } noev(cp); return (0);}noev(cp) char *cp;{ seterr2(cp, ": Event not found");}setexclp(cp) register char *cp;{ if (cp && cp[0] == '\n') return; exclp = cp;}unreadc(c) unsigned char c;{ peekread = c;}readc(wanteof) bool wanteof;{ register int c; static sincereal; if (c = peekread) { peekread = 0; return (c); }top: if (alvecp) { if (c = *alvecp++) return (c); if (*alvec) { alvecp = *alvec++; return (' '); } } if (alvec) { if (alvecp = *alvec) { alvec++; goto top; } /* Infinite source! */ return ('\n'); } if (evalp) { if (c = *evalp++) return (c); if (*evalvec) { evalp = *evalvec++; return (' '); } evalp = 0; } if (evalvec) { if (evalvec == (char **)1) { doneinp = 1; reset(); } if (evalp = *evalvec) { evalvec++; goto top; } evalvec = (char **)1; return ('\n'); } do { if (arginp == (char *) 1 || onelflg == 1) { if (wanteof) return (-1); exitstat(); } if (arginp) { if ((c = *arginp++) == 0) { arginp = (char *) 1; return ('\n'); } return (c); }reread: c = bgetc(); if (c == -1) { struct sgttyb tty; if (wanteof) return (-1); /* was isatty but raw with ignoreeof yields problems */ if (ioctl(SHIN, TIOCGETP, (char *)&tty) == 0 && (tty.sg_flags & RAW) == 0) { /* was 'short' for FILEC */ int ctpgrp; if (++sincereal > 25) goto oops; if (tpgrp != -1 && ioctl(FSHTTY, TIOCGPGRP, (char *)&ctpgrp) == 0 && tpgrp != ctpgrp) { (void) ioctl(FSHTTY, TIOCSPGRP, (char *)&tpgrp); (void) killpg(ctpgrp, SIGHUP);csh_printf("Reset tty pgrp from %d to %d\n", ctpgrp, tpgrp); /* 005 RNF */ goto reread; } if (adrof("ignoreeof")) { if (loginsh) csh_printf("\nUse \"logout\" to logout.\n"); /* 005 RNF */ else csh_printf("\nUse \"exit\" to leave csh.\n"); /* 005 RNF */ reset(); } if (chkstop == 0) panystop(1); } else { /* 002 - GAG */ /*Perror ("ioctl");*/ }oops: doneinp = 1; reset(); } sincereal = 0; if (c == '\n' && onelflg) onelflg--; } while (c == 0); return (c);}bgetc(){ register int buf, off, c; register int roomleft;#ifdef TENEX register int numleft = 0; char ttyline[BUFSIZ];#endif#ifdef TELL if (cantell) { if (fseekp < fbobp || fseekp > feobp) { fbobp = feobp = fseekp; (void) lseek(SHIN, fseekp, 0); } if (fseekp == feobp) { fbobp = feobp; do c = read(SHIN, fbuf[0], BUFSIZ); while (c < 0 && errno == EINTR); if (c <= 0) return (-1); feobp += c; } c = fbuf[0][fseekp - fbobp]; fseekp++; return (c & TRIM); }#endifagain: buf = (int) fseekp / BUFSIZ; if (buf >= fblocks) { register char **nfbuf = (char **) calloc((unsigned) (fblocks + 2), sizeof (char **)); if (fbuf) { (void) blkcpy(nfbuf, fbuf); xfree((char *)fbuf); } fbuf = nfbuf; fbuf[fblocks] = calloc(BUFSIZ, sizeof (char)); fblocks++; goto again; } if (fseekp >= feobp) { buf = (int) feobp / BUFSIZ; off = (int) feobp % BUFSIZ; roomleft = BUFSIZ - off; for (;;) { /* break out: see below */#ifdef TENEX if (intty) /* then use tenex routine */ { c = numleft ? numleft : tenex(ttyline, BUFSIZ); if (c > roomleft) /* No room in this buffer? */ { /* start with fresh buffer */ feobp = fseekp = fblocks * BUFSIZ; numleft = c; goto again; } if (c > 0) copy (fbuf[buf] + off, ttyline, c); numleft = 0; } else c = read(SHIN, fbuf[buf] + off, roomleft); if ((c >= 0) || (errno != EINTR)) break;#else not tenex c = read(SHIN, fbuf[buf] + off, BUFSIZ - off); if (c >= 0) break; if (errno == EWOULDBLOCK) { int off = 0; (void) ioctl(SHIN, FIONBIO, (char *)&off); } else if (errno != EINTR) break;#endif } /* end "for (;;)" */ if (c <= 0) return (-1); feobp += c;#ifdef TENEX if (!intty)#endif goto again; } c = fbuf[buf][(int) fseekp % BUFSIZ]; fseekp++; return (c);}bfree(){ register int sb, i;#ifdef TELL if (cantell) return;#endif if (whyles) return; sb = (int) (fseekp - 1) / BUFSIZ; if (sb > 0) { for (i = 0; i < sb; i++) xfree(fbuf[i]); (void) blkcpy(fbuf, &fbuf[sb]); fseekp -= BUFSIZ * sb; feobp -= BUFSIZ * sb; fblocks -= sb; }}bseek(l) off_t l;{ register struct whyle *wp; fseekp = l;#ifdef TELL if (!cantell) {#endif if (!whyles) return; for (wp = whyles; wp->w_next; wp = wp->w_next) continue; if (wp->w_start > l) l = wp->w_start;#ifdef TELL }#endif}/* any similarity to bell telephone is purely accidental */#ifndef btelloff_tbtell(){ return (fseekp);}#endifbtoeof(){ (void) lseek(SHIN, (off_t)0, 2); fseekp = feobp; wfree(); bfree();}#ifdef TELLsettell(){ cantell = 0; if (arginp || onelflg || intty) return; if (lseek(SHIN, (off_t)0, 1) < 0 || errno == ESPIPE) return; fbuf = (char **) calloc(2, sizeof (char **)); fblocks = 1; fbuf[0] = calloc(BUFSIZ, sizeof (char)); fseekp = fbobp = feobp = lseek(SHIN, (off_t)0, 1); cantell = 1;}#endif
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?