Ejemplo n.º 1
0
/*
 * idutils:  lid(idutils) pattern
 *
 *	i)	pattern	POSIX regular expression
 *	i)	dbpath	GTAGS directory
 */
void
idutils(const char *pattern, const char *dbpath)
{
	FILE *ip;
	CONVERT *cv;
	STRBUF *ib = strbuf_open(0);
	char encoded_pattern[IDENTLEN];
	char path[MAXPATHLEN];
	const char *lid;
	int linenum, count;
	char *p, *q, *grep;

	lid = usable("lid");
	if (!lid)
		die("lid(idutils) not found.");
	/*
	 * convert spaces into %FF format.
	 */
	encode(encoded_pattern, sizeof(encoded_pattern), pattern);
	/*
	 * make lid command line.
	 * Invoke lid with the --result=grep option to generate grep format.
	 */
	strbuf_puts(ib, lid);
	strbuf_sprintf(ib, " --file='%s/ID'", dbpath);
	strbuf_puts(ib, " --separator=newline");
	if (format == FORMAT_PATH)
		strbuf_puts(ib, " --result=filenames --key=none");
	else
		strbuf_puts(ib, " --result=grep");
	if (iflag)
		strbuf_puts(ib, " --ignore-case");
	strbuf_putc(ib, ' ');
	strbuf_puts(ib, quote_string(pattern));
	if (debug)
		fprintf(stderr, "idutils: %s\n", strbuf_value(ib));
	if (!(ip = popen(strbuf_value(ib), "r")))
		die("cannot execute '%s'.", strbuf_value(ib));
	cv = convert_open(type, format, root, cwd, dbpath, stdout);
	count = 0;
	strcpy(path, "./");
	while ((grep = strbuf_fgets(ib, ip, STRBUF_NOCRLF)) != NULL) {
		q = path + 2;
		/* extract path name */
		if (*grep == '/')
			die("The path in the output of lid is assumed absolute. '%s'", grep);
		p = grep;
		while (*p && *p != ':')
			*q++ = *p++;
		*q = '\0'; 
		if ((xflag || tflag) && !*p)
			die("invalid lid(idutils) output format(1). '%s'", grep);
		p++;
		if (lflag) {
			if (!locatestring(path, localprefix, MATCH_AT_FIRST))
				continue;
		}
		count++;
		switch (format) {
		case FORMAT_PATH:
			convert_put_path(cv, path);
			break;
		default:
			/* extract line number */
			while (*p && isspace(*p))
				p++;
			linenum = 0;
			for (linenum = 0; *p && isdigit(*p); linenum = linenum * 10 + (*p++ - '0'))
				;
			if (*p != ':')
				die("invalid lid(idutils) output format(2). '%s'", grep);
			if (linenum <= 0)
				die("invalid lid(idutils) output format(3). '%s'", grep);
			p++;
			/*
			 * print out.
			 */
			convert_put_using(cv, encoded_pattern, path, linenum, p, NULL);
			break;
		}
	}
	if (pclose(ip) < 0)
		die("terminated abnormally.");
	convert_close(cv);
	strbuf_close(ib);
	if (vflag) {
		print_count(count);
		fprintf(stderr, " (using idutils index in '%s').\n", dbpath);
	}
}
Ejemplo n.º 2
0
/*
 * grep: grep pattern
 *
 *	i)	pattern	POSIX regular expression
 */
void
grep(const char *pattern, char *const *argv, const char *dbpath)
{
	FILE *fp;
	CONVERT *cv;
	GFIND *gp = NULL;
	STRBUF *ib = strbuf_open(MAXBUFLEN);
	const char *path;
	char encoded_pattern[IDENTLEN];
	const char *buffer;
	int linenum, count;
	int flags = 0;
	int target = GPATH_SOURCE;
	regex_t	preg;
	int user_specified = 1;

	/*
	 * convert spaces into %FF format.
	 */
	encode(encoded_pattern, sizeof(encoded_pattern), pattern);

	if (oflag)
		target = GPATH_BOTH;
	if (Oflag)
		target = GPATH_OTHER;
	if (!Gflag)
		flags |= REG_EXTENDED;
	if (iflag)
		flags |= REG_ICASE;
	if (regcomp(&preg, pattern, flags) != 0)
		die("invalid regular expression.");
	cv = convert_open(type, format, root, cwd, dbpath, stdout);
	count = 0;

	if (*argv && file_list)
		args_open_both(argv, file_list);
	else if (*argv)
		args_open(argv);
	else if (file_list)
		args_open_filelist(file_list);
	else {
		args_open_gfind(gp = gfind_open(dbpath, localprefix, target));
		user_specified = 0;
	}
	while ((path = args_read()) != NULL) {
		if (user_specified) {
			static char buf[MAXPATHLEN];

			if (normalize(path, get_root_with_slash(), cwd, buf, sizeof(buf)) == NULL)
				if (!qflag)
					fprintf(stderr, "'%s' is out of source tree.\n", path);
			if (!test("f", buf))
				die("'%s' not found. Please remake tag files by invoking gtags(1).", path);
			path = buf;
		}
		if (!(fp = fopen(path, "r")))
			die("cannot open file '%s'.", path);
		linenum = 0;
		while ((buffer = strbuf_fgets(ib, fp, STRBUF_NOCRLF)) != NULL) {
			int result = regexec(&preg, buffer, 0, 0, 0);

			linenum++;
			if ((!Vflag && result == 0) || (Vflag && result != 0)) {
				count++;
				if (format == FORMAT_PATH) {
					convert_put_path(cv, path);
					break;
				} else {
					convert_put_using(cv, encoded_pattern, path, linenum, buffer,
						(user_specified) ? NULL : gp->dbop->lastdat);
				}
			}
		}
		fclose(fp);
	}
	args_close();
	convert_close(cv);
	strbuf_close(ib);
	regfree(&preg);
	if (vflag) {
		print_count(count);
		fprintf(stderr, " (no index used).\n");
	}
}
Ejemplo n.º 3
0
int
search(const char *pattern, const char *root, const char *cwd, const char *dbpath, int db)
{
	CONVERT *cv;
	int count = 0;
	GTOP *gtop;
	GTP *gtp;
	int flags = 0;
	STRBUF *sb = NULL, *ib = NULL;
	char curpath[MAXPATHLEN], curtag[IDENTLEN];
	FILE *fp = NULL;
	const char *src = "";
	int lineno, last_lineno;

	lineno = last_lineno = 0;
	curpath[0] = curtag[0] = '\0';
	/*
	 * open tag file.
	 */
	gtop = gtags_open(dbpath, root, db, GTAGS_READ, 0);
	cv = convert_open(type, format, root, cwd, dbpath, stdout);
	/*
	 * search through tag file.
	 */
	if (nofilter & SORT_FILTER)
		flags |= GTOP_NOSORT;
	if (iflag) {
		if (!isregex(pattern)) {
			sb = strbuf_open(0);
			strbuf_putc(sb, '^');
			strbuf_puts(sb, pattern);
			strbuf_putc(sb, '$');
			pattern = strbuf_value(sb);
		}
		flags |= GTOP_IGNORECASE;
	}
	if (Gflag)
		flags |= GTOP_BASICREGEX;
	if (format == FORMAT_PATH)
		flags |= GTOP_PATH;
	if (gtop->format & GTAGS_COMPACT)
		ib = strbuf_open(0);
	for (gtp = gtags_first(gtop, pattern, flags); gtp; gtp = gtags_next(gtop)) {
		if (lflag && !locatestring(gtp->path, localprefix, MATCH_AT_FIRST))
			continue;
		if (format == FORMAT_PATH) {
			convert_put_path(cv, gtp->path);
			count++;
		} else if (gtop->format & GTAGS_COMPACT) {
			/*
			 * Compact format:
			 *                    a          b
			 * tagline = <file id> <tag name> <line no>,...
			 */
			char *p = (char *)gtp->tagline;
			const char *fid, *tagname;
			int n = 0;

			fid = p;
			while (*p != ' ')
				p++;
			*p++ = '\0';			/* a */
			tagname = p;
			while (*p != ' ')
				p++;
			*p++ = '\0';			/* b */
			/*
			 * Reopen or rewind source file.
			 */
			if (!nosource) {
				if (strcmp(gtp->path, curpath) != 0) {
					if (curpath[0] != '\0' && fp != NULL)
						fclose(fp);
					strlimcpy(curtag, tagname, sizeof(curtag));
					strlimcpy(curpath, gtp->path, sizeof(curpath));
					/*
					 * Use absolute path name to support GTAGSROOT
					 * environment variable.
					 */
					fp = fopen(makepath(root, curpath, NULL), "r");
					if (fp == NULL)
						warning("source file '%s' is not available.", curpath);
					last_lineno = lineno = 0;
				} else if (strcmp(gtp->tag, curtag) != 0) {
					strlimcpy(curtag, gtp->tag, sizeof(curtag));
					if (atoi(p) < last_lineno && fp != NULL) {
						rewind(fp);
						lineno = 0;
					}
					last_lineno = 0;
				}
			}
			/*
			 * Unfold compact format.
			 */
			if (!isdigit(*p))
				die("illegal compact format.");
			if (gtop->format & GTAGS_COMPLINE) {
				/*
				 *
				 * If GTAGS_COMPLINE flag is set, each line number is expressed as
				 * the difference from the previous line number except for the head.
				 * Please see flush_pool() in libutil/gtagsop.c for the details.
				 */
				int last = 0, cont = 0;

				while (*p || cont > 0) {
					if (cont > 0) {
						n = last + 1;
						if (n > cont) {
							cont = 0;
							continue;
						}
					} else if (isdigit(*p)) {
						GET_NEXT_NUMBER(p);
					}  else if (*p == '-') {
						GET_NEXT_NUMBER(p);
						cont = n + last;
						n = last + 1;
					} else if (*p == ',') {
						GET_NEXT_NUMBER(p);
						n += last;
					}
					if (last_lineno != n && fp) {
						while (lineno < n) {
							if (!(src = strbuf_fgets(ib, fp, STRBUF_NOCRLF))) {
								src = "";
								fclose(fp);
								fp = NULL;
								break;
							}
							lineno++;
						}
					}
					if (gtop->format & GTAGS_COMPNAME)
						tagname = (char *)uncompress(tagname, gtp->tag);
					convert_put_using(cv, tagname, gtp->path, n, src, fid);
					count++;
					last_lineno = last = n;
				}
			} else {
				/*
				 * In fact, when GTAGS_COMPACT is set, GTAGS_COMPLINE is allways set.
				 * Therefore, the following code are not actually used.
				 * However, it is left for some test.
				 */
				while (*p) {
					for (n = 0; isdigit(*p); p++)
						n = n * 10 + *p - '0';
					if (*p == ',')
						p++;
					if (last_lineno == n)
						continue;
					if (last_lineno != n && fp) {
						while (lineno < n) {
							if (!(src = strbuf_fgets(ib, fp, STRBUF_NOCRLF))) {
								src = "";
								fclose(fp);
								fp = NULL;
								break;
							}
							lineno++;
						}
					}
					if (gtop->format & GTAGS_COMPNAME)
						tagname = (char *)uncompress(tagname, gtp->tag);
					convert_put_using(cv, tagname, gtp->path, n, src, fid);
					count++;
					last_lineno = n;
				}
			}
		} else {
			/*
			 * Standard format:
			 *                    a          b         c
			 * tagline = <file id> <tag name> <line no> <line image>
			 */
			char *p = (char *)gtp->tagline;
			char namebuf[IDENTLEN];
			const char *fid, *tagname, *image;

			fid = p;
			while (*p != ' ')
				p++;
			*p++ = '\0';			/* a */
			tagname = p;
			while (*p != ' ')
				p++;
			*p++ = '\0';			/* b */
			if (gtop->format & GTAGS_COMPNAME) {
				strlimcpy(namebuf, (char *)uncompress(tagname, gtp->tag), sizeof(namebuf));
				tagname = namebuf;
			}
			if (nosource) {
				image = " ";
			} else {
				while (*p != ' ')
					p++;
				image = p + 1;		/* c + 1 */
				if (gtop->format & GTAGS_COMPRESS)
					image = (char *)uncompress(image, gtp->tag);
			}
			convert_put_using(cv, tagname, gtp->path, gtp->lineno, image, fid);
			count++;
		}
	}
	convert_close(cv);
	if (sb)
		strbuf_close(sb);
	if (ib)
		strbuf_close(ib);
	if (fp)
		fclose(fp);
	gtags_close(gtop);
	return count;
}
Ejemplo n.º 4
0
/*
 * pathlist: print candidate path list.
 *
 *	i)	dbpath
 */
void
pathlist(const char *pattern, const char *dbpath)
{
	GFIND *gp;
	CONVERT *cv;
	const char *path, *p;
	regex_t preg;
	int count;
	int target = GPATH_SOURCE;

	if (oflag)
		target = GPATH_BOTH;
	if (Oflag)
		target = GPATH_OTHER;
	if (pattern) {
		int flags = 0;
		char edit[IDENTLEN];

		if (!Gflag)
			flags |= REG_EXTENDED;
		if (iflag || getconfb("icase_path"))
			flags |= REG_ICASE;
#ifdef _WIN32
		flags |= REG_ICASE;
#endif /* _WIN32 */
		/*
		 * We assume '^aaa' as '^/aaa'.
		 */
		if (*pattern == '^' && *(pattern + 1) != '/') {
			snprintf(edit, sizeof(edit), "^/%s", pattern + 1);
			pattern = edit;
		}
		if (regcomp(&preg, pattern, flags) != 0)
			die("invalid regular expression.");
	}
	if (!localprefix)
		localprefix = "./";
	cv = convert_open(type, format, root, cwd, dbpath, stdout);
	count = 0;

	gp = gfind_open(dbpath, localprefix, target);
	while ((path = gfind_read(gp)) != NULL) {
		/*
		 * skip localprefix because end-user doesn't see it.
		 */
		p = path + strlen(localprefix) - 1;
		if (pattern) {
			int result = regexec(&preg, p, 0, 0, 0);

			if ((!Vflag && result != 0) || (Vflag && result == 0))
				continue;
		} else if (Vflag)
			continue;
		if (format == FORMAT_PATH)
			convert_put_path(cv, path);
		else
			convert_put_using(cv, "path", path, 1, " ", gp->dbop->lastdat);
		count++;
	}
	gfind_close(gp);
	convert_close(cv);
	if (pattern)
		regfree(&preg);
	if (vflag) {
		switch (count) {
		case 0:
			fprintf(stderr, "file not found");
			break;
		case 1:
			fprintf(stderr, "1 file located");
			break;
		default:
			fprintf(stderr, "%d files located", count);
			break;
		}
		fprintf(stderr, " (using '%s').\n", makepath(dbpath, dbname(GPATH), NULL));
	}
}
Ejemplo n.º 5
0
void
literal_search(CONVERT *cv, const char *file)
{
	struct words *c;
	int ccount;
	char *p;
	char *buf;
	struct stat stb;
	char *linep;
	long lineno;
	int f;

	if ((f = open(file, 0)) < 0)
		die("cannot open '%s'.", file);
	if (fstat(f, &stb) < 0)
		die("cannot fstat '%s'.", file);
	if (stb.st_size == 0)
		goto skip_empty_file;
#ifdef HAVE_MMAP
	buf = mmap(0, stb.st_size, PROT_READ, MAP_SHARED, f, 0);
	if (buf == MAP_FAILED)
		die("mmap failed (%s).", file);
#else
#ifdef HAVE_ALLOCA
	buf = (char *)alloca(stb.st_size);
#else
	buf = (char *)malloc(stb.st_size);
#endif
	if (buf == NULL)
		die("short of memory.");
	if (read(f, buf, stb.st_size) < stb.st_size)
		die("read failed (%s).", file);
#endif
	linep = p = buf;
	ccount = stb.st_size;
	lineno = 1;
	c = w;
	for (;;) {
		if (--ccount <= 0)
			break;
		nstate:
			if (ccomp(c->inp, *p)) {
				c = c->nst;
			}
			else if (c->link != 0) {
				c = c->link;
				goto nstate;
			}
			else {
				c = c->fail;
				if (c==0) {
					c = w;
					istate:
					if (ccomp(c->inp , *p)) {
						c = c->nst;
					}
					else if (c->link != 0) {
						c = c->link;
						goto istate;
					}
				}
				else goto nstate;
			}
		if (c->out) {
			while (*p++ != '\n') {
				if (--ccount <= 0)
					break;
			}
			if (Vflag)
				goto nomatch;
	succeed:	if (cv->format == FORMAT_PATH) {
				convert_put_path(cv, file);
				goto finish;
			} else {
				STATIC_STRBUF(sb);

				strbuf_clear(sb);
				strbuf_nputs(sb, linep, p - linep);
				strbuf_unputc(sb, '\n');
				strbuf_unputc(sb, '\r');
				convert_put_using(cv, encoded_pattern, file, lineno, strbuf_value(sb), NULL);
			}
	nomatch:	lineno++;
			linep = p;
			c = w;
			continue;
		}
		if (*p++ == '\n') {
			if (Vflag)
				goto succeed;
			else {
				lineno++;
				linep = p;
				c = w;
			}
		}
	}
finish:
#ifdef HAVE_MMAP
	munmap(buf, stb.st_size);
#elif HAVE_ALLOCA
#else
	free(buf);
#endif
skip_empty_file:
	close(f);
}
Ejemplo n.º 6
0
/**
 * literal_search: execute literal search
 *
 *	@param[in]	cv	CONVERT structure
 *	@param[in]	file	file to search
 *	@return		0: normal, -1: error
 */
int
literal_search(CONVERT *cv, const char *file)
{
# define ccomp(a,b) (iflag ? lca(a)==lca(b) : a==b)
# define lca(x) (isupper(x) ? tolower(x) : x)
	struct words *c;
	int ccount;
	char *p;
	char *buf;
	struct stat stb;
	char *linep;
	long lineno;
	int f;
	int count = 0;

	if ((f = open(file, O_BINARY)) < 0) {
		warning("cannot open '%s'.", file);
		return -1;
	}
	if (fstat(f, &stb) < 0) {
		warning("cannot fstat '%s'.", file);
		goto skip_empty_file;
	}
	if (stb.st_size == 0)
		goto skip_empty_file;
#ifdef HAVE_MMAP
	buf = mmap(0, stb.st_size, PROT_READ, MAP_SHARED, f, 0);
	if (buf == MAP_FAILED)
		die("mmap failed (%s).", file);
#elif _WIN32
	{
	HANDLE hMap = CreateFileMapping((HANDLE)_get_osfhandle(f), NULL, PAGE_READONLY, 0, stb.st_size, NULL);
	if (hMap == NULL)
		die("CreateFileMapping failed (%s).", file);
	buf = MapViewOfFile(hMap, FILE_MAP_READ, 0, 0, 0);
	if (buf == NULL)
		die("MapViewOfFile failed (%s).", file);
#else
#ifdef HAVE_ALLOCA
	buf = (char *)alloca(stb.st_size);
#else
	buf = (char *)malloc(stb.st_size);
#endif
	if (buf == NULL)
		die("short of memory.");
	if (read(f, buf, stb.st_size) < stb.st_size)
		die("read failed (%s).", file);
#endif
	linep = p = buf;
	ccount = stb.st_size;
	lineno = 1;
	c = w;
	for (;;) {
		if (--ccount < 0)
			break;
		nstate:
			if (ccomp(c->inp, *p)) {
				c = c->nst;
			}
			else if (c->link != 0) {
				c = c->link;
				goto nstate;
			}
			else {
				c = c->fail;
				if (c==0) {
					c = w;
					istate:
					if (ccomp(c->inp , *p)) {
						c = c->nst;
					}
					else if (c->link != 0) {
						c = c->link;
						goto istate;
					}
				}
				else goto nstate;
			}
		if (c->out) {
			while (*p++ != '\n') {
				if (--ccount < 0)
					break;
			}
			if (Vflag)
				goto nomatch;
	succeed:	if (cv->format == FORMAT_PATH) {
				convert_put_path(cv, NULL, file);
				count++;
				goto finish;
			} else {
				STATIC_STRBUF(sb);

				strbuf_clear(sb);
				strbuf_nputs(sb, linep, p - linep);
				strbuf_unputc(sb, '\n');
				strbuf_unputc(sb, '\r');
				convert_put_using(cv, pattern, file, lineno, strbuf_value(sb), NULL);
				count++;
			}
	nomatch:	lineno++;
			linep = p;
			c = w;
			continue;
		}
		if (*p++ == '\n' || ccount == 0) {
			if (Vflag)
				goto succeed;
			else {
				lineno++;
				linep = p;
				c = w;
			}
		}
	}
finish:
#ifdef HAVE_MMAP
	munmap(buf, stb.st_size);
#elif _WIN32
	UnmapViewOfFile(buf);
	CloseHandle(hMap);
	}
#elif HAVE_ALLOCA
#else
	free(buf);
#endif
skip_empty_file:
	close(f);
	return count;
}
Ejemplo n.º 7
0
/**
 * grep: @NAME{grep} pattern
 *
 *	@param[in]	pattern	@NAME{POSIX} regular expression
 *	@param	argv
 *	@param	dbpath
 */
void
grep(const char *pattern, char *const *argv, const char *dbpath)
{
	FILE *fp;
	CONVERT *cv;
	GFIND *gp = NULL;
	STRBUF *ib = strbuf_open(MAXBUFLEN);
	const char *path;
	char encoded_pattern[IDENTLEN];
	const char *buffer;
	int linenum, count;
	int flags = 0;
	int target = GPATH_SOURCE;
	regex_t	preg;
	int user_specified = 1;

	/*
	 * convert spaces into %FF format.
	 */
	encode(encoded_pattern, sizeof(encoded_pattern), pattern);
	/*
	 * literal search available?
	 */
	if (!literal) {
		const char *p = pattern;
		int normal = 1;

		for (; *p; p++) {
			if (!(isalpha(*p) || isdigit(*p) || isblank(*p) || *p == '_')) {
				normal = 0;
				break;
			}
		}
		if (normal)
			literal = 1;
	}
	if (oflag)
		target = GPATH_BOTH;
	if (Oflag)
		target = GPATH_OTHER;
	if (literal) {
		literal_comple(pattern);
	} else {
		if (!Gflag)
			flags |= REG_EXTENDED;
		if (iflag)
			flags |= REG_ICASE;
		if (regcomp(&preg, pattern, flags) != 0)
			die("invalid regular expression.");
	}
	cv = convert_open(type, format, root, cwd, dbpath, stdout, NOTAGS);
	cv->tag_for_display = encoded_pattern;
	count = 0;

	if (*argv && file_list)
		args_open_both(argv, file_list);
	else if (*argv)
		args_open(argv);
	else if (file_list)
		args_open_filelist(file_list);
	else {
		args_open_gfind(gp = gfind_open(dbpath, localprefix, target));
		user_specified = 0;
	}
	while ((path = args_read()) != NULL) {
		if (user_specified) {
			static char buf[MAXPATHLEN];

			if (normalize(path, get_root_with_slash(), cwd, buf, sizeof(buf)) == NULL) {
				warning("'%s' is out of the source project.", path);
				continue;
			}
			if (test("d", buf)) {
				warning("'%s' is a directory. Ignored.", path);
				continue;
			}
			if (!test("f", buf)) {
				warning("'%s' not found. Ignored.", path);
				continue;
			}
			path = buf;
		}
		if (Sflag && !locatestring(path, localprefix, MATCH_AT_FIRST))
			continue;
		if (literal) {
			int n = literal_search(cv, path);
			if (n > 0)
				count += n;
		} else {
			if (!(fp = fopen(path, "r")))
				die("cannot open file '%s'.", path);
			linenum = 0;
			while ((buffer = strbuf_fgets(ib, fp, STRBUF_NOCRLF)) != NULL) {
				int result = regexec(&preg, buffer, 0, 0, 0);
				linenum++;
				if ((!Vflag && result == 0) || (Vflag && result != 0)) {
					count++;
					if (format == FORMAT_PATH) {
						convert_put_path(cv, NULL, path);
						break;
					} else {
						convert_put_using(cv, pattern, path, linenum, buffer,
							(user_specified) ? NULL : gp->dbop->lastdat);
					}
				}
			}
			fclose(fp);
		}
	}
	args_close();
	convert_close(cv);
	strbuf_close(ib);
	if (literal == 0)
		regfree(&preg);
	if (vflag) {
		print_count(count);
		fprintf(stderr, " (no index used).\n");
	}
}