static int
matchdir(struct dirbuf *np, const char *pattern)
{
	struct dirbuf	name = *np;
	DIR		*dir;
	struct dirent	*dp;
	int		nmatches = 0;

	/* If path is not empty, append a path separator */
	if (!dirbuf_addslash(&name))
		return 0;

	if (!(dir = opendir(dirbuf_as_path(&name))))
		return 0;

	while ((dp = readdir(dir)) != NULL) {
		if (dp->d_name[0] == '.' && pattern[0] != '.')
			continue;
		DEBUG(("* matching \"%s\"\n", dp->d_name));
		if (matchfile(&name, dp->d_name, pattern))
			nmatches++;
	}
	closedir(dir);
	return nmatches;
}
예제 #2
0
파일: split.c 프로젝트: 99years/plan9
void
main(int argc, char *argv[])
{
	Reprog *exp;
	char *pattern = 0;
	int n = 1000;
	char *line;
	int xflag = 0;
	int iflag = 0;
	Biobuf bin;
	Biobuf *b = &bin;
	char buf[256];

	ARGBEGIN {
	case 'l':
	case 'n':
		n=atoi(EARGF(usage()));
		break;
	case 'e':
		pattern = strdup(EARGF(usage()));
		break;
	case 'f':
		stem = strdup(EARGF(usage()));
		break;
	case 's':
		suffix = strdup(EARGF(usage()));
		break;
	case 'x':
		xflag++;
		break;
	case 'i':
		iflag++;
		break;
	default:
		usage();
		break;

	} ARGEND;

	if(argc < 0 || argc > 1)
		usage();

	if(argc != 0) {
		b = Bopen(argv[0], OREAD);
		if(b == nil) {
			fprint(2, "split: can't open %s: %r\n", argv[0]);
			exits("open");
		}
	} else
		Binit(b, 0, OREAD);

	if(pattern) {
		Resub match[2];

		if(!(exp = regcomp(iflag? fold(pattern, strlen(pattern)):
		    pattern)))
			badexp();
		memset(match, 0, sizeof match);
		matchfile(match);
		while((line=Brdline(b,'\n')) != 0) {
			memset(match, 0, sizeof match);
			line[Blinelen(b)-1] = 0;
			if(regexec(exp, iflag? fold(line, Blinelen(b)-1): line,
			    match, 2)) {
				if(matchfile(match) && xflag)
					continue;
			} else if(output == 0)
				nextfile();	/* at most once */
			Bwrite(output, line, Blinelen(b)-1);
			Bputc(output, '\n');
		}
	} else {
		int linecnt = n;

		while((line=Brdline(b,'\n')) != 0) {
			if(++linecnt > n) {
				nextfile();
				linecnt = 1;
			}
			Bwrite(output, line, Blinelen(b));
		}

		/*
		 * in case we didn't end with a newline, tack whatever's 
		 * left onto the last file
		 */
		while((n = Bread(b, buf, sizeof(buf))) > 0)
			Bwrite(output, buf, n);
	}
	if(b != nil)
		Bterm(b);
	exits(0);
}
예제 #3
0
파일: address.c 프로젝트: aahud/harvey
Address
address(Addr *ap, Address a, int sign)
{
	File *f = a.f;
	Address a1, a2;

	do{
		switch(ap->type){
		case 'l':
		case '#':
			a = (*(ap->type=='#'?charaddr:lineaddr))(ap->num, a, sign);
			break;

		case '.':
			a = f->dot;
			break;

		case '$':
			a.r.p1 = a.r.p2 = f->Buffer.nc;
			break;

		case '\'':
			a.r = f->mark;
			break;

		case '?':
			sign = -sign;
			if(sign == 0)
				sign = -1;
			/* fall through */
		case '/':
			nextmatch(f, ap->are, sign>=0? a.r.p2 : a.r.p1, sign);
			a.r = sel.p[0];
			break;

		case '"':
			a = matchfile(ap->are)->dot;
			f = a.f;
			if(f->unread)
				load(f);
			break;

		case '*':
			a.r.p1 = 0, a.r.p2 = f->Buffer.nc;
			return a;

		case ',':
		case ';':
			if(ap->left)
				a1 = address(ap->left, a, 0);
			else
				a1.f = a.f, a1.r.p1 = a1.r.p2 = 0;
			if(ap->type == ';'){
				f = a1.f;
				a = a1;
				f->dot = a1;
			}
			if(ap->next)
				a2 = address(ap->next, a, 0);
			else
				a2.f = a.f, a2.r.p1 = a2.r.p2 = f->Buffer.nc;
			if(a1.f != a2.f)
				error(Eorder);
			a.f = a1.f, a.r.p1 = a1.r.p1, a.r.p2 = a2.r.p2;
			if(a.r.p2 < a.r.p1)
				error(Eorder);
			return a;

		case '+':
		case '-':
			sign = 1;
			if(ap->type == '-')
				sign = -1;
			if(ap->next==0 || ap->next->type=='+' || ap->next->type=='-')
				a = lineaddr(1L, a, sign);
			break;
		default:
			panic("address");
			return a;
		}
	}while(ap = ap->next);	/* assign = */
	return a;
}
/*
 * This one deals with the expansion of {...} expressions.
 * This is complicated by nesting ([...] and {...} can occur
 * within).
 *
 * We do this in two passes. If the pattern is
 * 	{alt1,alt2,...,altN}rest
 * then we first go over the pattern finding "rest". Once we have
 * it, we make a second pass, this time matching the given filename
 * against "altK" concatenated with "rest" for each alternative "altK".
 */
static int
dobraces(struct dirbuf *np, const char *fname, const char *pattern)
{
	const char	*begin, *tail = NULL;
	char		patbuf[1024], stack[MAXNEST], pc;
	unsigned int	nc, match = 0, nsp = 0;

	if (strlen(pattern) >= sizeof(patbuf))
		return 0;

	/* Remember where our pattern begins */
	begin = pattern;

again:
	/* We've scanned past the opening brace, but it's there,
	 * so count it */
	stack[0] = RIGHTCURLY;
	nsp = 1;
	nc = 0;

	while (*pattern) {
		pc = *pattern++;

		/* Do we have a complete alternative? */
		if (nsp == 1 && (pc == COMMA || pc == RIGHTCURLY)) {
			if (tail != NULL) {
				struct dirbuf	name = *np;

				ASSERT(nc+strlen(tail) < sizeof(patbuf));
				patbuf[nc] = '\0';
				strcat(patbuf, tail);
				if (matchfile(&name, fname, patbuf))
					match++;
			}
			/* Have we closed the outermost bracket? */
			if (pc == RIGHTCURLY) {
				nsp--;
				break;
			}
			/* Start scanning for the next alternative */
			nc = 0;
			continue;
		}

		/* Nested character classes/alternatives */
		if (pc == LEFTCURLY || pc == LEFTBLOCKY) {
			if (nsp >= MAXNEST)
				return 0;
			stack[nsp++] = (pc == LEFTCURLY)?
					RIGHTCURLY : RIGHTBLOCKY;
		} else
		if (pc == RIGHTCURLY || pc == RIGHTBLOCKY) {
			/* Make sure closing bracket/brace
			 * matches opening one */
			if (!nsp || stack[--nsp] != pc)
				return 0;
		}

		/* Copy to pattern buffer */
		ASSERT(nc < sizeof(patbuf)-2);
		patbuf[nc++] = pc;
		patbuf[nc] = '\0';
	}

	/* No closing brace? Trouble. */
	if (nsp != 0)
		return 0;

	if (tail == NULL) {
		/* We have the remainder. Keep it and start over */
		tail = pattern;
		pattern = begin;
		goto again;
	}

	return match;
}
static int
matchfile(struct dirbuf *np, const char *fname, const char *pattern)
{
	struct dirbuf	name = *np;
	unsigned char	pc, fc;

	/* DEBUG(("* try \"%s\" ~ \"%s\"\n", fname, pattern)); */
	while (*pattern && *pattern != '/') {
		pc = *pattern++;
		fc = *fname;
		switch (pc) {
		case '?':
			if (!fc || !dirbuf_appendc(&name, fc))
				return 0;
			fname++;
			break;

		/* Match 0 or more characters. Try to match greedily
		 * i.e. as many characters as possible. */
		case '*': {
			struct dirbuf	temp;
			unsigned int	n, ok = 0;

			n = strlen(fname);
			do {
				temp = name;
				if (dirbuf_appends(&temp, fname, n)) {
					ok = matchfile(&temp, fname + n,
							pattern);
				}
			} while (!ok && n--);

			return ok;
			}

		/* Match character range */
		case LEFTBLOCKY: {
			unsigned char	from, to;
			int		ok = 0;

			if (fc == '\0')
				return 0;
			while (1) {
				to = from = *pattern++;
				if (from == RIGHTBLOCKY)
					break;
				if (from == '\0')
					return 0;

				if (*pattern == '-') {
					pattern++;
					to = *pattern++;
					if (to == '\0')
						return 0;
				}
				if (from <= fc && fc <= to)
					ok = 1;
			}
			if (!ok || !dirbuf_appendc(&name, fc))
				return 0;
			fname++;
			break;
			}

		case LEFTCURLY:
			/* Handle braces - icky ugly and bad */
			return dobraces(&name, fname, pattern);

		case '\\':
			if ((fc = *++fname) == '\0')
				return 0;
			/* fallthru */
		default:
			if (pc != fc || !dirbuf_appendc(&name, fc))
				return 0;
			fname++;
			break;
		}
	}

	/* Pattern exhausted - make sure we've matched the full
	 * filename! */
	if (*fname != '\0')
		return 0;

	return doglob(&name, pattern);
}
예제 #6
0
/*
 * Note: openinfo is a function for reading info files, and putting
 * uncompressed content into a temporary filename.  For a flexibility, there
 * are two temporary files supported, i.e.  one for keeping opened info file,
 * and second for i.e. regexp search across info nodes, which are in other
 * info-subfiles.  The temporary file 1 is refrenced by number=0, and file 2 by
 * number=1 Openinfo by default first tries the path stored in char
 * *filenameprefix and then in the rest of userdefined paths.
 */
FILE *
openinfo(char *filename, int number)
{
	FILE *id = NULL;
#define BUF_LEN 1024
	char *buf = xmalloc(BUF_LEN);	/* holds local copy of filename */
	char *bufend;			/* points at the trailing 0 of initial name */
	char command[1128];		/* holds command to evaluate for decompression of file */
	int i, j;
	char *tmpfilename;

	if ((strncmp(filename, "dir", 3)==0)  &&  !isalnum(filename[3]))
	{
		xfree(buf);
		return opendirfile(number);
	}

	if (number == 0)		/* initialize tmp filename for file 1 */
	{
		if (tmpfilename1)
		{
			unlink(tmpfilename1);	/* erase old tmpfile */
			free(tmpfilename1);
		}
		tmpfilename1 = make_tempfile();
		tmpfilename = tmpfilename1;	/* later we will refere only to tmp1 */
	}
	else /* initialize tmp filename for file 2 */
	{
		if (tmpfilename2)
		{
			unlink(tmpfilename2);	/* erase old tmpfile */
			free(tmpfilename2);
		}
		tmpfilename2 = make_tempfile();
		tmpfilename = tmpfilename2;	/* later we will refere only to tmp2 */
	}

	for (i = -2; i < infopathcount; i++)	/* go through all paths */
	{
		if (i < 0)
		{
			/*
			 * no filenameprefix, we don't navigate around any specific
			 * infopage set, so simply scan all directories for a hit
			 */
			if (!filenameprefix)
				continue;
			/* build a filename: First (i == -2) try filenameprefix/filename,
			 * then try with a .info appended */
			if (i == -2)
				snprintf(buf, BUF_LEN, "%s/%s", filenameprefix, basename(filename));
			else
				snprintf(buf, BUF_LEN, "%s/%s.info", filenameprefix, basename(filename));
		}
		else
		{
			/* build a filename */
			strcpy(buf, infopaths[i]);
			/* no match found in this directory */
			if (! matchfile(&buf, filename))
				continue;
		}
		bufend = buf;
		/* remember the bufend to make it possible later to glue compression
		 * suffixes. */
		bufend += strlen(buf);
		for (j = 0; j < SuffixesNumber; j++)	/* go through all suffixes */
		{
			strcat(buf, suffixes[j].suffix);
			if ((id = fopen(buf, "r")) != NULL)
			{
				fclose(id);
				clearfilenameprefix();
				filenameprefix = strdup(buf);
				{			/* small scope for removal of filename */
					int prefixi, prefixlen = strlen(filenameprefix);
					for (prefixi = prefixlen; prefixi > 0; prefixi--)
						if (filenameprefix[prefixi] == '/')
						{
							filenameprefix[prefixi] = 0;
							break;
						}
				}
				buildcommand(command, suffixes[j].command, buf, tmpfilename);
				xsystem(command);
				id = fopen(tmpfilename, "r");
				if (id)
				{
					xfree(buf);
					return id;
				}
			}
			(*bufend) = 0;
		}

		/* if we have a nonzero filename prefix, that is we view a set of
		 * infopages, we don't want to search for a page in all
		 * directories, but only in the prefix directory.  Therefore break
		 * here. */
		if ((i == -1) &&(filenameprefix))
			break;
	}
	xfree(buf);


	return 0;
#undef BUF_LEN
}