📄 glob.c
字号:
if ((gflg & G_CSH) && vl != vo) blkfree(vo); if (vl == NULL) { setname(vis_str(str)); stderror(ERR_NAME | ERR_NOMATCH); } if (vl[0] == NULL) { xfree((ptr_t) vl); return (Strsave(STRNULL)); } if (vl[1] != NULL) return (handleone(str, vl, action)); else { str = strip(*vl); xfree((ptr_t) vl); return (str); }}Char **globall(v) Char **v;{ Char **vl, **vo; int gflg = gflag; if (!v || !v[0]) { gargv = saveblk(v); gargc = blklen(gargv); return (gargv); } noglob = adrof(STRnoglob) != 0; if (gflg & G_CSH) /* * Expand back-quote, tilde and brace */ vl = vo = globexpand(v); else vl = vo = saveblk(v); if (!noglob && (gflg & G_GLOB)) { vl = libglob(vo); if ((gflg & G_CSH) && vl != vo) blkfree(vo); } else trim(vl); gargc = vl ? blklen(vl) : 0; return (gargv = vl);}voidginit(){ gargsiz = GLOBSPACE; gargv = (Char **) xmalloc((size_t) sizeof(Char *) * gargsiz); gargv[0] = 0; gargc = 0;}voidrscan(t, f) register Char **t; void (*f) ();{ register Char *p; while ((p = *t++) != NULL) while (*p) (*f) (*p++);}voidtrim(t) register Char **t;{ register Char *p; while ((p = *t++) != NULL) while (*p) *p++ &= TRIM;}voidtglob(t) register Char **t;{ register Char *p, c; while ((p = *t++) != NULL) { if (*p == '~' || *p == '=') gflag |= G_CSH; else if (*p == '{' && (p[1] == '\0' || (p[1] == '}' && p[2] == '\0'))) continue; while ((c = *p++) != '\0') { /* * eat everything inside the matching backquotes */ if (c == '`') { gflag |= G_CSH; while (*p && *p != '`') if (*p++ == '\\') { if (*p) /* Quoted chars */ p++; else break; } if (*p) /* The matching ` */ p++; else break; } else if (c == '{') gflag |= G_CSH; else if (isglob(c)) gflag |= G_GLOB; } }}/* * 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, word[MAXPATHLEN]; if (pargv) {#ifdef notdef abort();#endif blkfree(pargv); } pargsiz = GLOBSPACE; pargv = (Char **) xmalloc((size_t) sizeof(Char *) * pargsiz); pargv[0] = NULL; pargcp = pargs = word; pargc = 0; pnleft = MAXPATHLEN - 4; for (;;) { for (lp = cp; *lp != '`'; lp++) { if (*lp == 0) { if (pargcp != pargs) pword(); return (pargv); } psave(*lp); } lp++; for (rp = lp; *rp && *rp != '`'; rp++) if (*rp == '\\') { rp++; if (!*rp) goto oops; } if (!*rp) oops: stderror(ERR_UNMATCHED, '`'); ep = Strsave(lp); ep[rp - lp] = 0; backeval(ep, literal); cp = rp + 1; }}static voidbackeval(cp, literal) Char *cp; bool literal;{ register int icnt, c; register Char *ip; struct command faket; bool hadnl; int pvec[2], quoted; Char *fakecom[2], ibuf[BUFSIZ]; char tibuf[BUFSIZ]; hadnl = 0; icnt = 0; quoted = (literal || (cp[0] & QUOTE)) ? QUOTE : 0; faket.t_dtyp = NODE_COMMAND; faket.t_dflg = 0; faket.t_dlef = 0; faket.t_drit = 0; faket.t_dspr = 0; faket.t_dcom = fakecom; fakecom[0] = STRfakecom1; 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(SHERR, 2); initdesc(); /* * Bugfix for nested backquotes by Michael Greim <greim@sbsvax.UUCP>, * posted to comp.bugs.4bsd 12 Sep. 1989. */ if (pargv) /* mg, 21.dec.88 */ blkfree(pargv), pargv = 0, pargsiz = 0; /* mg, 21.dec.88 */ arginp = cp; while (*cp) *cp++ &= TRIM; /* * In the child ``forget'' everything about current aliases or * eval vectors. */ alvec = NULL; evalvec = NULL; alvecp = NULL; evalp = NULL; (void) lex(¶ml); if (seterr) stderror(ERR_OLD); alias(¶ml); t = syntax(paraml.next, ¶ml, 0); if (seterr) stderror(ERR_OLD); if (t) t->t_dflg |= F_NOFORK; (void) signal(SIGTSTP, SIG_IGN); (void) signal(SIGTTIN, SIG_IGN); (void) signal(SIGTTOU, SIG_IGN); execute(t, -1, NULL, NULL); exitstat(); } xfree((ptr_t) cp); (void) close(pvec[1]); c = 0; ip = NULL; do { int cnt = 0; for (;;) { if (icnt == 0) { int i; ip = ibuf; do icnt = read(pvec[0], tibuf, BUFSIZ); while (icnt == -1 && errno == EINTR); if (icnt <= 0) { c = -1; break; } for (i = 0; i < icnt; i++) ip[i] = (unsigned char) tibuf[i]; } 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); (void) close(pvec[0]); pwait(); prestjob();}static voidpsave(c) int c;{ if (--pnleft <= 0) stderror(ERR_WTOOLONG); *pargcp++ = c;}static voidpword(){ psave(0); if (pargc == pargsiz - 1) { pargsiz += GLOBSPACE; pargv = (Char **) xrealloc((ptr_t) pargv, (size_t) pargsiz * sizeof(Char *)); } pargv[pargc++] = Strsave(pargs); pargv[pargc] = NULL; pargcp = pargs; pnleft = MAXPATHLEN - 4;}int Gmatch(string, pattern) Char *string, *pattern;{ Char **blk, **p; int gpol = 1, gres = 0; if (*pattern == '^') { gpol = 0; pattern++; } blk = (Char **) xmalloc(GLOBSPACE * sizeof(Char *)); blk[0] = Strsave(pattern); blk[1] = NULL; expbrace(&blk, NULL, GLOBSPACE); for (p = blk; *p; p++) gres |= pmatch(string, *p); blkfree(blk); return(gres == gpol);} static intpmatch(string, pattern) register Char *string, *pattern;{ register Char stringc, patternc; int match, negate_range; Char rangec; for (;; ++string) { stringc = *string & TRIM; patternc = *pattern++; switch (patternc) { case 0: return (stringc == 0); case '?': if (stringc == 0) return (0); break; case '*': if (!*pattern) return (1); while (*string) if (Gmatch(string++, pattern)) return (1); return (0); case '[': match = 0; if ((negate_range = (*pattern == '^')) != 0) pattern++; while ((rangec = *pattern++) != '\0') { if (rangec == ']') break; if (match) continue; if (rangec == '-' && *(pattern-2) != '[' && *pattern != ']') { match = (stringc <= (*pattern & TRIM) && (*(pattern-2) & TRIM) <= stringc); pattern++; } else match = (stringc == (rangec & TRIM)); } if (rangec == 0) stderror(ERR_NAME | ERR_MISSING, ']'); if (match == negate_range) return (0); break; default: if ((patternc & TRIM) != stringc) return (0); break; } }}voidGcat(s1, s2) Char *s1, *s2;{ register Char *p, *q; int n; for (p = s1; *p++;) continue; for (q = s2; *q++;) continue; n = (p - s1) + (q - s2) - 1; if (++gargc >= gargsiz) { gargsiz += GLOBSPACE; gargv = (Char **) xrealloc((ptr_t) gargv, (size_t) gargsiz * sizeof(Char *)); } gargv[gargc] = 0; p = gargv[gargc - 1] = (Char *) xmalloc((size_t) n * sizeof(Char)); for (q = s1; (*p++ = *q++) != '\0';) continue; for (p--, q = s2; (*p++ = *q++) != '\0';) continue;}#ifdef FILECintsortscmp(a, b) register const ptr_t a, b;{#if defined(NLS) && !defined(NOSTRCOLL) char buf[2048];#endif if (!a) /* check for NULL */ return (b ? 1 : 0); if (!b) return (-1); if (!*(Char **)a) /* check for NULL */ return (*(Char **)b ? 1 : 0); if (!*(Char **)b) return (-1);#if defined(NLS) && !defined(NOSTRCOLL) (void) strcpy(buf, short2str(*(Char **)a)); return ((int) strcoll(buf, short2str(*(Char **)b)));#else return ((int) Strcmp(*(Char **)a, *(Char **)b));#endif}#endif /* FILEC */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -