sh.glob.c
来自「<B>Digital的Unix操作系统VAX 4.2源码</B>」· C语言 代码 · 共 846 行 · 第 1/2 页
C
846 行
#ifndef lintstatic char *sccsid = "@(#)sh.glob.c 4.1 (ULTRIX) 7/17/90";#endif lint/************************************************************************ * * * Copyright (c) 1988 by * * Digital Equipment Corporation, Maynard, MA * * All rights reserved. * * * * This software is furnished under a license and may be used and * * copied only in accordance with the terms of such license and * * with the inclusion of the above copyright notice. This * * software or any other copies thereof may not be provided or * * otherwise made available to any other person. No title to and * * ownership of the software is hereby transferred. * * * * This software is derived from software received from the * * University of California, Berkeley, and from Bell * * Laboratories. Use, duplication, or disclosure is subject to * * restrictions under license agreements with University of * * California and with AT&T. * * * * The information in this software is subject to change without * * notice and should not be construed as a commitment by Digital * * Equipment Corporation. * * * * Digital assumes no responsibility for the use or reliability * * of its software on equipment which is not supplied by Digital. * * * ************************************************************************/#include "sh.h"#include <sys/dir.h>/* * C Shell * Modification History * * 006 - Bob Fontaine and Gary A. Gaudet - Fri May 18 1990 * Backed out fix in 004 below for QAR #00649 because the fix introduced * a bug in that *.* also matched all . files include . and .. * * 005 - Gary A. Gaudet - Wed Jan 31 13:22:30 EST 1990 * Fixed escaping command substitution and variable expansion in heredoc * * 004 Mon Dec 18 15:41:53 EST 1989, Gary A. Gaudet * fixed u32_qar #00664: "set a '`pwd`'; echo `a`" dumps core * fixed u32_qar #00649: "echo \.*" doesn't match files * * 003 12-Nov-88, Al Delorey (afd). * Use "ifdef CSHEDIT" around the cmd line edit code. * * 002 20-Sep-88, Al Delorey (afd). * Added command line edit capability: call lex with 2nd * arg of 0 (meaning dont't use editword to get words). * * 001 Sat Aug 13 15:28:57 EDT 1988, Gary A. Gaudet * merging mips & ultrix for 8 bit clean and bug fixes */int globcnt;char *globchars = "`{[*?";char *gpath, *gpathp, *lastgpathp;int globbed;bool noglob;bool nonomatch;char *entp;char **sortbas;int sortscmp();#define sort() qsort((char *)sortbas, &gargv[gargc] - sortbas, \ sizeof(*sortbas), sortscmp), sortbas = &gargv[gargc]char **glob(v) register char **v;{ char agpath[BUFSIZ]; char *agargv[GAVSIZ]; gpath = agpath; gpathp = gpath; *gpathp = 0; lastgpathp = &gpath[sizeof agpath - 2]; ginit(agargv); globcnt = 0;#ifdef GDEBUG printf("glob entered: "); blkpr(v); printf("\n");#endif noglob = adrof("noglob") != 0; nonomatch = adrof("nonomatch") != 0; globcnt = noglob | nonomatch; while (*v) collect(*v++);#ifdef GDEBUG printf("glob done, globcnt=%d, gflag=%d: ", globcnt, gflag); blkpr(gargv); printf("\n");#endif if (globcnt == 0 && (gflag&1)) { blkfree(gargv), gargv = 0; return (0); } else return (gargv = copyblk(gargv));}ginit(agargv) char **agargv;{ agargv[0] = 0; gargv = agargv; sortbas = agargv; gargc = 0; gnleft = NCARGS - 4;}collect(as) register char *as;{ register int i; if (any('`', as)) {#ifdef GDEBUG printf("doing backp of %s\n", as);#endif (void) dobackp(as, 0);#ifdef GDEBUG printf("backp done, acollect'ing\n");#endif for (i = 0; i < pargc; i++) if (noglob) { Gcat(pargv[i], ""); sortbas = &gargv[gargc]; } else acollect(pargv[i]); if (pargv) blkfree(pargv), pargv = 0;#ifdef GDEBUG printf("acollect done\n");#endif } else if (noglob || eq(as, "{") || eq(as, "{}")) { Gcat(as, ""); sort(); } else acollect(as);}acollect(as) register char *as;{ register int ogargc = gargc; gpathp = gpath; *gpathp = 0; globbed = 0; expand(as); if (gargc == ogargc) { if (nonomatch) { Gcat(as, ""); sort(); } } else sort();}/* * String compare for qsort. Also used by filec code in sh.file.c. */sortscmp(a1, a2) char **a1, **a2;{ return (strcmp(*a1, *a2));}expand(as) char *as;{ register char *cs; register char *sgpathp, *oldcs; struct stat stb; sgpathp = gpathp; cs = as; if (*cs == '~' && gpathp == gpath) { addpath('~'); for (cs++; letter(*cs) || digit(*cs) || *cs == '-';) addpath(*cs++); if (!*cs || *cs == '/') { if (gpathp != gpath + 1) { *gpathp = 0; if (gethdir(gpath + 1)) error("Unknown user: %s", gpath + 1); (void) strcpy(gpath, gpath + 1); } else (void) strcpy(gpath, value("home")); gpathp = strend(gpath); } } while (!any(((*cs & TRIM) == QUOTECHAR ? (*++cs & TRIM) | QUOTE : *cs), globchars)) { if (*cs == 0) { if (!globbed) Gcat(gpath, ""); else if (stat(gpath, &stb) >= 0) { Gcat(gpath, ""); globcnt++; } goto endit; } addpath(*cs++); } oldcs = cs; while (cs > as && *cs != '/') { if ((*cs & TRIM) != QUOTECHAR) /* 004 - GAG */ gpathp--; cs--; } if ((*cs & TRIM) == QUOTECHAR) gpathp++; if (*cs == '/') cs++, gpathp++; *gpathp = 0; if (*oldcs == '{') { (void) execbrc(cs, NOSTR); return; } matchdir(cs);endit: gpathp = sgpathp; *gpathp = 0;}matchdir(pattern) char *pattern;{ struct stat stb; register struct direct *dp; register DIR *dirp; dirp = opendir(gpath); if (dirp == NULL) { if (globbed) return; goto patherr2; } if (fstat(dirp->dd_fd, &stb) < 0) goto patherr1; if (!isdir(stb)) { errno = ENOTDIR; goto patherr1; } while ((dp = readdir(dirp)) != NULL) { if (dp->d_ino == 0) continue; if (match(dp->d_name, pattern)) { Gcat(gpath, dp->d_name); globcnt++; } } closedir(dirp); return;patherr1: closedir(dirp);patherr2: Perror(gpath);}execbrc(p, s) char *p, *s;{ char restbuf[BUFSIZ + 2]; register char *pe, *pm, *pl; int brclev = 0; char *lm, savec, *sgpathp; int flag; for (lm = restbuf; *p != '{'; *lm++ = *p++) continue; for (pe = ++p; *pe; pe++) switch (*pe) { case '{': brclev++; continue; case '}': if (brclev == 0) goto pend; brclev--; continue; case '[': for (pe++; *pe && *pe != ']'; pe++) continue; if (!*pe) error("Missing ]"); continue; }pend: if (brclev || !*pe) error("Missing }"); for (pl = pm = p; pm <= pe; pm++) { flag = 0; if ((*pm & TRIM) == QUOTECHAR) { pm++; flag = QUOTE; } switch ((*pm & TRIM) | flag) { case '{': brclev++; continue; case '}': if (brclev) { brclev--; continue; } goto doit; case ','|QUOTE: case ',': if (brclev) continue;doit: savec = *pm; *pm = 0; (void) strcpy(lm, pl); (void) strcat(restbuf, pe + 1); *pm = savec; if (s == 0) { sgpathp = gpathp; expand(restbuf); gpathp = sgpathp; *gpathp = 0; } else if (amatch(s, restbuf)) return (1); sort(); pl = pm + 1; continue; case '[': for (pm++; *pm && *pm != ']'; pm++) continue; if (!*pm) error("Missing ]"); continue; }} return (0);}match(s, p) char *s, *p;{ register int c; register char *sentp; char sglobbed = globbed; if (*s == '.' && *p != '.') return (0); sentp = entp; entp = s; c = amatch(s, p); entp = sentp; globbed = sglobbed; return (c);}amatch(s, p) register char *s, *p;{ register int scc; int ok, lc; char *sgpathp; struct stat stb; int c, cc; globbed = 1; for (;;) { if ((scc = (*s++ & TRIM)) == QUOTECHAR) scc = *s++ & TRIM; switch (c = (*p++ & TRIM)) { case '{': return (execbrc(p - 1, s - 1)); 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) error("Missing ]"); continue; case '*': if (!*p) return (1); if (*p == '/') { p++; goto slash; } for (s--; *s; s++) if (amatch(s, p)) return (1); return (0);
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?