sh.glob.c
来自「<B>Digital的Unix操作系统VAX 4.2源码</B>」· C语言 代码 · 共 846 行 · 第 1/2 页
C
846 行
case 0: return (scc == 0); default: if ((c & TRIM) != scc) return (0); continue; case '?': if (scc == 0) return (0); continue; case '/': if (scc) return (0);slash: s = entp; sgpathp = gpathp; while (*s) addpath(*s++); addpath('/'); if (stat(gpath, &stb) == 0 && isdir(stb)) if (*p == 0) { Gcat(gpath, ""); globcnt++; } else expand(p); gpathp = sgpathp; *gpathp = 0; return (0); } }}Gmatch(s, p) register char *s, *p;{ register int scc; int ok, lc; int c, cc; for (;;) { if ((scc = (*s++ & TRIM)) == QUOTECHAR) scc = *s++; if ((c = (*p++ & TRIM)) == QUOTECHAR) c = (*p++ & TRIM) | QUOTE; switch (c) { case '[': ok = 0; lc = 077777; while (cc = *p++) { if (cc == ']') { if (ok) break; return (0); } if (cc == '-') { if (lc <= scc && scc <= *p++) ok++; } else if (scc == (lc = cc)) ok++; } if (cc == 0) bferr("Missing ]"); continue; case '*': if (!*p) return (1); for (s--; *s; s++) if (Gmatch(s, p)) return (1); return (0); case 0: return (scc == 0); default: if ((c & TRIM) != scc) return (0); continue; case '?': if (scc == 0) return (0); continue; } }}Gcat(s1, s2) char *s1, *s2;{ register char *p, *q; int n; for (p = s1; *p++;) ; for (q = s2; *q++;) ; gnleft -= (n = (p - s1) + (q - s2) - 1); if (gnleft <= 0 || ++gargc >= GAVSIZ) error("Arguments too long"); gargv[gargc] = 0; p = gargv[gargc - 1] = xalloc((unsigned)n); for (q = s1; *p++ = *q++;) ; for (p--, q = s2; *p++ = *q++;) ;}addpath(c) char c;{ if (gpathp >= lastgpathp) error("Pathname too long"); *gpathp++ = c & TRIM; *gpathp = 0;}rscan(t, f) register char **t; int (*f)();{ register char *p; register CHTYPE c; while (p = *t++) { while (c = *p++) { if ((c & TRIM) == QUOTECHAR) c = (*p++ & TRIM) | QUOTE; (*f)(c); } }}trim(t) register char **t;{ register char *p; while (p = *t++) strip (p);}/* * tests for file expansion characters */tglob(t) register char **t;{ register char *p; register CHTYPE c;#ifdef TGLOBDEBUG printf ("TGLOB: entered; *t = %s\n", *t);#endif while (p = *t++) { if (*p == '~') gflag |= 2; else if (*p == '{' && (p[1] == '\0' || p[1] == '}' && p[2] == '\0')) continue; while (c = (unsigned char) *p++) { if ((c & TRIM) == QUOTECHAR) c = (*p++ & TRIM) | QUOTE; else if (any(c, globchars)) gflag |= c == '{' ? 2 : 1; } }#ifdef TGLOBDEBUG printf ("TGLOB: exiting; *t = %s\n", *t);#endif}char *globone(str) register char *str;{ char *gv[2]; register char **gvp; register char *cp; gv[0] = str; gv[1] = 0; gflag = 0; tglob(gv); if (gflag) { gvp = glob(gv); if (gvp == 0) { setname(str); bferr("No match"); } cp = *gvp++; if (cp == 0) cp = ""; else if (*gvp) { setname(str); bferr("Ambiguous"); } else cp = strip(cp);/* if (cp == 0 || *gvp) { setname(str); bferr(cp ? "Ambiguous" : "No output"); }*/ xfree((char *)gargv); gargv = 0; } else { trim(gv); cp = savestr(gv[0]); } return (cp);}/* * Command substitute cp. If literal, then this is * a substitution from a << redirection, and so we should * not crunch blanks and tabs, separating words only at newlines. */char **dobackp(cp, literal) char *cp; bool literal;{ register char *lp, *rp; char *ep; char word[BUFSIZ]; char *apargv[GAVSIZ + 2]; if (pargv) { blkfree(pargv); } pargv = apargv; pargv[0] = NOSTR; pargcp = pargs = word; pargc = 0; pnleft = BUFSIZ - 4; for (;;) { for (lp = cp; *lp != '`' || (*(lp-1)&TRIM) == QUOTECHAR; lp++) { /* 005 - GAG */ if (*lp == 0) { if (pargcp != pargs) pword();#ifdef GDEBUG printf("leaving dobackp\n");#endif return (pargv = copyblk(pargv)); } psave(*lp & TRIM); } lp++; for (rp = lp; *rp && *rp != '`' || (*(rp-1)&TRIM) == QUOTECHAR; rp++) /* 005 - GAG */ if (*rp == '\\') { rp++; if (!*rp) goto oops; } if (!*rp)oops: error("Unmatched `"); ep = savestr(lp); ep[rp - lp] = 0; backeval(ep, literal);#ifdef GDEBUG printf("back from backeval\n");#endif cp = rp + 1; }}backeval(cp, literal) char *cp; bool literal;{ int pvec[2]; int quoted = (literal || ((cp[0] & TRIM) == QUOTECHAR)) ? QUOTE : 0; char ibuf[BUFSIZ]; register int icnt = 0, c; register char *ip; bool hadnl = 0; char *fakecom[2]; struct command faket; faket.t_dtyp = TCOM; faket.t_dflg = 0; faket.t_dlef = 0; faket.t_drit = 0; faket.t_dspr = 0; faket.t_dcom = fakecom; fakecom[0] = "` ... `"; fakecom[1] = 0; /* * We do the psave job to temporarily change the current job * so that the following fork is considered a separate job. * This is so that when backquotes are used in a * builtin function that calls glob the "current job" is not corrupted. * We only need one level of pushed jobs as long as we are sure to * fork here. */ psavejob(); /* * It would be nicer if we could integrate this redirection more * with the routines in sh.sem.c by doing a fake execute on a builtin * function that was piped out. */ mypipe(pvec); if (pfork(&faket, -1) == 0) { struct wordent paraml; struct command *t; (void) close(pvec[0]); (void) dmove(pvec[1], 1); (void) dmove(SHDIAG, 2); initdesc(); arginp = cp; strip(cp);#ifdef CSHEDIT (void) lex(¶ml, 0);#else (void) lex(¶ml);#endif if (err) error(err); alias(¶ml); t = syntax(paraml.next, ¶ml, 0); if (err) error(err); if (t) t->t_dflg |= FPAR; (void) signal(SIGTSTP, SIG_IGN); (void) signal(SIGTTIN, SIG_IGN); (void) signal(SIGTTOU, SIG_IGN); execute(t, -1); exitstat(); } xfree(cp); (void) close(pvec[1]); do { int cnt = 0; for (;;) { if (icnt == 0) { ip = ibuf; icnt = read(pvec[0], ip, BUFSIZ); if (icnt <= 0) { c = -1; break; } } if (hadnl) break; --icnt; c = (*ip++ & TRIM); if (c == 0) break; if (c == '\n') { /* * Continue around the loop one * more time, so that we can eat * the last newline without terminating * this word. */ hadnl = 1; continue; } if (!quoted && (c == ' ' || c == '\t')) break; cnt++; psave(c | quoted); } /* * Unless at end-of-file, we will form a new word * here if there were characters in the word, or in * any case when we take text literally. If * we didn't make empty words here when literal was * set then we would lose blank lines. */ if (c != -1 && (cnt || literal)) pword(); hadnl = 0; } while (c >= 0);#ifdef GDEBUG printf("done in backeval, pvec: %d %d\n", pvec[0], pvec[1]); printf("also c = %c <%o>\n", c, c);#endif (void) close(pvec[0]); pwait(); prestjob();}psave(c) int c;{ if (--pnleft <= 0) error("Word too long"); if (c & QUOTE) { /* 004 - GAG */ *pargcp++ = QUOTECHAR; if (--pnleft <= 0) error("Word too long"); } *pargcp++ = c & TRIM;}pword(){ psave(0); if (pargc == GAVSIZ) error("Too many words from ``"); pargv[pargc++] = savestr(pargs); pargv[pargc] = NOSTR;#ifdef GDEBUG printf("got word %s\n", pargv[pargc-1]);#endif pargcp = pargs; pnleft = BUFSIZ - 4;}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?