⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gtags.c

📁 代码检索工具GLOBAL源码。可用来浏览分析LINUX源码。
💻 C
📖 第 1 页 / 共 2 页
字号:
	if (getconfb("extractmethod"))		extractmethod = 1;	strbuf_reset(sb);	if (cflag == 0 && getconfs("format", sb) && !strcmp(strbuf_value(sb), "compact"))		cflag++;	/*	 * Pass the following information to gtags-parser(1)	 * using environment variable.	 *	 * o langmap	 * o DBPATH	 */	strbuf_reset(sb);	if (getconfs("langmap", sb)) {		const char *p = strdup(strbuf_value(sb));		if (p == NULL)			die("short of memory.");		langmap = p;	}	set_env("GTAGSLANGMAP", langmap);	set_env("GTAGSDBPATH", dbpath);	if (wflag)		set_env("GTAGSWARNING", "1");	/*	 * incremental update.	 */	if (iflag) {		/*		 * Version check. If existing tag files are old enough		 * gtagsopen() abort with error message.		 */		GTOP *gtop = gtags_open(dbpath, cwd, GTAGS, GTAGS_MODIFY, 0);		gtags_close(gtop);		/*		 * GPATH is needed for incremental updating.		 * Gtags check whether or not GPATH exist, since it may be		 * removed by mistake.		 */		if (!test("f", makepath(dbpath, dbname(GPATH), NULL)))			die("Old version tag file found. Please remake it.");		(void)incremental(dbpath, cwd);		exit(0);	}	/* 	 * create GTAGS, GRTAGS and GSYMS	 */	signal_setup();	total = 0;					/* counting file */	for (db = GTAGS; db < GTAGLIM; db++) {		if (oflag && db == GSYMS)			continue;		strbuf_reset(sb);		/*		 * get parser for db. (gtags-parser by default)		 */		if (!getconfs(dbname(db), sb))			continue;		if (!usable(strmake(strbuf_value(sb), " \t")))			die("Parser '%s' not found or not executable.", strmake(strbuf_value(sb), " \t"));		if (vflag)			fprintf(stderr, "[%s] Creating '%s'.\n", now(), dbname(db));		createtags(dbpath, cwd, db);		strbuf_reset(sb);		if (db == GTAGS) {			if (getconfs("GTAGS_extra", sb))				if (system(strbuf_value(sb)))					fprintf(stderr, "GTAGS_extra command failed: %s\n", strbuf_value(sb));		} else if (db == GRTAGS) {			if (getconfs("GRTAGS_extra", sb))				if (system(strbuf_value(sb)))					fprintf(stderr, "GRTAGS_extra command failed: %s\n", strbuf_value(sb));		} else if (db == GSYMS) {			if (getconfs("GSYMS_extra", sb))				if (system(strbuf_value(sb)))					fprintf(stderr, "GSYMS_extra command failed: %s\n", strbuf_value(sb));		}		if (exitflag)			exit(1);	}	/*	 * create id-utils index.	 */	if (Iflag) {		if (vflag)			fprintf(stderr, "[%s] Creating indexes for id-utils.\n", now());		strbuf_reset(sb);		strbuf_puts(sb, "mkid");		if (vflag)			strbuf_puts(sb, " -v");		if (vflag) {#ifdef __DJGPP__			if (is_unixy())	/* test for 4DOS as well? */#endif			strbuf_puts(sb, " 1>&2");		} else {			strbuf_puts(sb, " >/dev/null");		}		if (debug)			fprintf(stderr, "executing mkid like: %s\n", strbuf_value(sb));		if (system(strbuf_value(sb)))			die("mkid failed: %s", strbuf_value(sb));		strbuf_reset(sb);		strbuf_puts(sb, "chmod 644 ");		strbuf_puts(sb, makepath(dbpath, "ID", NULL));		if (system(strbuf_value(sb)))			die("chmod failed: %s", strbuf_value(sb));	}	if (vflag)		fprintf(stderr, "[%s] Done.\n", now());	closeconf();	strbuf_close(sb);	return 0;}/* * incremental: incremental update * *	i)	dbpath	dbpath directory *	i)	root	root directory of source tree *	r)		0: not updated, 1: updated */intincremental(dbpath, root)	const char *dbpath;	const char *root;{	struct stat statp;	time_t gtags_mtime;	STRBUF *addlist = strbuf_open(0);	STRBUF *deletelist = strbuf_open(0);	IDSET *deleteset;	int updated = 0;	int addtotal = 0;	const char *path;	if (vflag) {		fprintf(stderr, " Tag found in '%s'.\n", dbpath);		fprintf(stderr, " Incremental update.\n");	}	/*	 * get modified time of GTAGS.	 */	path = makepath(dbpath, dbname(GTAGS), NULL);	if (stat(path, &statp) < 0)		die("stat failed '%s'.", path);	gtags_mtime = statp.st_mtime;	if (gpath_open(dbpath, 0) < 0)		die("GPATH not found.");	deleteset = idset_open(gpath_nextkey());	/*	 * make add list and update list.	 */	if (file_list)		find_open_filelist(file_list, root);	else		find_open(NULL);	while ((path = find_read()) != NULL) {		const char *fid;		/* a blank at the head of path means 'NOT SOURCE'. */		if (*path == ' ')			continue;		if (stat(path, &statp) < 0)			die("stat failed '%s'.", path);		if ((fid = gpath_path2fid(path)) == NULL) {			strbuf_puts0(addlist, path);			addtotal++;		} else if (gtags_mtime < statp.st_mtime) {			strbuf_puts0(addlist, path);			addtotal++;			idset_add(deleteset, atoi(fid));		}	}	find_close();	/*	 * make delete list.	 */	{		char fid[32];		int i, limit = gpath_nextkey();		for (i = 1; i < limit; i++) {			snprintf(fid, sizeof(fid), "%d", i);			if ((path = gpath_fid2path(fid)) == NULL)				continue;			if (!test("f", path)) {				strbuf_puts0(deletelist, path);				idset_add(deleteset, i);			}		}	}	gpath_close();	if (strbuf_getlen(addlist) + strbuf_getlen(deletelist))		updated = 1;	/*	 * execute updating.	 */	signal_setup();	if (updated) {		int db;		for (db = GTAGS; db < GTAGLIM; db++) {			/*			 * GTAGS needed at least.			 */			if ((db == GRTAGS || db == GSYMS)			    && !test("f", makepath(dbpath, dbname(db), NULL)))				continue;			if (vflag)				fprintf(stderr, "[%s] Updating '%s'.\n", now(), dbname(db));			updatetags(dbpath, root, deleteset, addlist, addtotal, db);			if (exitflag)				exit(1);		}	}	if (strbuf_getlen(deletelist) > 0) {		const char *start = strbuf_value(deletelist);		const char *end = start + strbuf_getlen(deletelist);		const char *p;		gpath_open(dbpath, 2);		for (p = start; p < end; p += strlen(p) + 1) {			if (exitflag)				break;			gpath_delete(p);		}		gpath_close();	}	if (exitflag)		exit(1);	if (updated) {		int db;		/*		 * Update modification time of tag files		 * because they may have no definitions.		 */		for (db = GTAGS; db < GTAGLIM; db++)#ifdef HAVE_UTIMES			utimes(makepath(dbpath, dbname(db), NULL), NULL);#else			utime(makepath(dbpath, dbname(db), NULL), NULL);#endif /* HAVE_UTIMES */	}	if (vflag) {		if (updated)			fprintf(stderr, " Global databases have been modified.\n");		else			fprintf(stderr, " Global databases are up to date.\n");		fprintf(stderr, "[%s] Done.\n", now());	}	strbuf_close(addlist);	strbuf_close(deletelist);	idset_close(deleteset);	return updated;}/* * updatetags: update tag file. * *	i)	dbpath		directory in which tag file exist *	i)	root		root directory of source tree *	i)	deleteset	bit array of fid of deleted or modified files  *	i)	addlist		\0 separated list of added or modified files *	i)	addtotal	number of files in addlist *	i)	db		GTAGS, GRTAGS, GSYMS */voidupdatetags(dbpath, root, deleteset, addlist, addtotal, db)	const char *dbpath;	const char *root;	IDSET *deleteset;	STRBUF *addlist;	int addtotal;	int db;{	GTOP *gtop;	STRBUF *comline = strbuf_open(0);	int gflags;	int path_list_max;	int arg_count = 0;	/*	 * GTAGS needed to make GRTAGS.	 */	if (db == GRTAGS && !test("f", makepath(dbpath, dbname(GTAGS), NULL)))		die("GTAGS needed to create GRTAGS.");	/*	 * get tag command.	 */	if (!getconfs(dbname(db), comline))		die("cannot get tag command. (%s)", dbname(db));	/*	 * determine the maximum length of the list of paths.	 */	path_list_max = exec_line_limit(strbuf_getlen(comline));	gtop = gtags_open(dbpath, root, db, GTAGS_MODIFY, 0);	if (vflag) {		char fid[32];		const char *path;		int seqno = 1;		int total = idset_count(deleteset);		int i;		for (i = 0; i < deleteset->max; i++) {			if (idset_contains(deleteset, i)) {				snprintf(fid, sizeof(fid), "%d", i);				path = gpath_fid2path(fid);				if (path == NULL)					die("GPATH is corrupted.");				fprintf(stderr, " [%d/%d] deleting tags of %s\n", seqno++, total, path + 2);			}		}	}	if (deleteset->max > 0)		gtags_delete(gtop, deleteset);	gflags = 0;	if (extractmethod)		gflags |= GTAGS_EXTRACTMETHOD;	if (debug)		gflags |= GTAGS_DEBUG;	/*	 * If the --max-args option is not specified, we pass the parser	 * the source file as a lot as possible to decrease the invoking	 * frequency of the parser.	 */	{		STRBUF *path_list = strbuf_open(0);		const char *path = strbuf_value(addlist);		const char *end = path + strbuf_getlen(addlist);		int seqno = 1;		while (path < end) {			int pathlen = strlen(path);			if (vflag)				fprintf(stderr, " [%d/%d] adding tags of %s\n", seqno++, addtotal, path + 2);			/*			 * Execute parser when path name collects enough.			 * Though the path_list is \0 separated list of path,			 * we can think its length equals to the length of			 * argument string because each \0 can be replaced			 * with a blank.			 */			if (strbuf_getlen(path_list)) {				if (path_list_max == 0 ||				    (max_args > 0 && arg_count >= max_args) ||				    strbuf_getlen(path_list) + pathlen > path_list_max)				{					gtags_add(gtop, strbuf_value(comline), path_list, gflags);					strbuf_reset(path_list);					arg_count = 0;				}			}			if (exitflag)				break;			/*			 * Add a path to the path list.			 */			strbuf_puts0(path_list, path);			path += pathlen + 1;			arg_count++;		}		if (strbuf_getlen(path_list))			gtags_add(gtop, strbuf_value(comline), path_list, gflags);		strbuf_close(path_list);	}	gtags_close(gtop);	strbuf_close(comline);}/* * createtags: create tags file * *	i)	dbpath	dbpath directory *	i)	root	root directory of source tree *	i)	db	GTAGS, GRTAGS, GSYMS */voidcreatetags(dbpath, root, db)	const char *dbpath;	const char *root;	int db;{	const char *path;	GTOP *gtop;	int flags, gflags;	STRBUF *comline = strbuf_open(0);	int count = 0;	int arg_count = 0;	STRBUF *path_list = strbuf_open(MAXPATHLEN);	int path_list_max;	/*	 * get tag command.	 */	if (!getconfs(dbname(db), comline))		die("cannot get tag command. (%s)", dbname(db));	/*	 * GTAGS needed to make GRTAGS.	 */	if (db == GRTAGS && !test("f", makepath(dbpath, dbname(GTAGS), NULL)))		die("GTAGS needed to create GRTAGS.");	/*	 * determine the maximum length of the list of paths.	 */	path_list_max = exec_line_limit(strbuf_getlen(comline));	flags = 0;	/*	 * Compact format:	 *	 * -c: COMPACT format.	 * -cc: PATHINDEX format.	 * Ths -cc is undocumented.	 * In the future, it may become the standard format of GLOBAL.	 */	if (cflag) {		flags |= GTAGS_PATHINDEX;		if (cflag == 1)			flags |= GTAGS_COMPACT;	}	if (vflag > 1)		fprintf(stderr, " using tag command '%s <path>'.\n", strbuf_value(comline));	gtop = gtags_open(dbpath, root, db, GTAGS_CREATE, flags);	gflags = 0;	if (extractmethod)		gflags |= GTAGS_EXTRACTMETHOD;	if (debug)		gflags |= GTAGS_DEBUG;	/*	 * If the --max-args option is not specified, we pass the parser	 * the source file as a lot as possible to decrease the invoking	 * frequency of the parser.	 */	if (file_list)		find_open_filelist(file_list, root);	else		find_open(NULL);	while ((path = find_read()) != NULL) {		int skip = 0;		/* a blank at the head of path means 'NOT SOURCE'. */		if (*path == ' ')			continue;		if (exitflag)			break;		count++;		/*		 * GSYMS doesn't treat asembler.		 */		if (db == GSYMS) {			if (locatestring(path, ".s", MATCH_AT_LAST) != NULL ||			    locatestring(path, ".S", MATCH_AT_LAST) != NULL)				skip = 1;		}		if (vflag) {			if (total)				fprintf(stderr, " [%d/%d]", count, total);			else				fprintf(stderr, " [%d]", count);			fprintf(stderr, " extracting tags of %s", path + 2);			if (skip)				fprintf(stderr, " (skipped)");			fputc('\n', stderr);		}		if (skip)			continue;		/*		 * Execute parser when path name collects enough.		 * Though the path_list is \0 separated list of string,		 * we can think its length equals to the length of		 * argument string because each \0 can be replaced		 * with a blank.		 */		if (strbuf_getlen(path_list)) {			if (path_list_max == 0 ||			    (max_args > 0 && arg_count >= max_args) ||			    strbuf_getlen(path_list) + strlen(path) > path_list_max)			{				gtags_add(gtop, strbuf_value(comline), path_list, gflags);				strbuf_reset(path_list);				arg_count = 0;			}		}		/*		 * Add a path to path_list.		 */		strbuf_puts0(path_list, path);		arg_count++;	}	if (strbuf_getlen(path_list))		gtags_add(gtop, strbuf_value(comline), path_list, gflags);	total = count;				/* save total count */	find_close();	gtags_close(gtop);	strbuf_close(comline);	strbuf_close(path_list);}/* * printconf: print configuration data. * *	i)	name	label of config data *	r)		exit code */intprintconf(name)	const char *name;{	int num;	int exist = 1;	if (getconfn(name, &num))		fprintf(stdout, "%d\n", num);	else if (getconfb(name))		fprintf(stdout, "1\n");	else {		STRBUF *sb = strbuf_open(0);		if (getconfs(name, sb))			fprintf(stdout, "%s\n", strbuf_value(sb));		else			exist = 0;		strbuf_close(sb);	}	return exist;}/* * put_converting: convert path into relative or absolute and print. * *	i)	line	raw output from global(1) *	i)	absolute 1: absolute, 0: relative *	i)	cxref 1: -x format, 0: file name only */static STRBUF *abspath;static char basedir[MAXPATHLEN+1];static int start_point;voidset_base_directory(root, cwd)	const char *root;	const char *cwd;{	abspath = strbuf_open(MAXPATHLEN);	strbuf_puts(abspath, root);	strbuf_unputc(abspath, '/');	start_point = strbuf_getlen(abspath);	if (strlen(cwd) > MAXPATHLEN)		die("current directory name too long.");	strlimcpy(basedir, cwd, sizeof(basedir));	/* leave abspath unclosed. */}voidput_converting(line, absolute, cxref)	const char *line;	int absolute;	int cxref;{	char buf[MAXPATHLEN+1];	const char *p = line;	/*	 * print until path name.	 */	if (cxref) {		/* print tag name */		for (; *p && !isspace((unsigned char)*p); p++)			(void)putc(*p, stdout);		/* print blanks and line number */		for (; *p && *p != '.'; p++)			(void)putc(*p, stdout);	}	if (*p++ == '\0')		return;	/*	 * make absolute path.	 */	strbuf_setlen(abspath, start_point);	for (; *p && !isspace((unsigned char)*p); p++)		strbuf_putc(abspath, *p);	/*	 * put path with converting.	 */	if (absolute) {		(void)fputs(strbuf_value(abspath), stdout);	} else {		const char *a = strbuf_value(abspath);		const char *b = basedir;#if defined(_WIN32) || defined(__DJGPP__)		/* skip drive char in 'c:/usr/bin' */		while (*a != '/')			a++;		while (*b != '/')			b++;#endif		if (!abs2rel(a, b, buf, sizeof(buf)))			die("abs2rel failed. (path=%s, base=%s).", a, b);		(void)fputs(buf, stdout);	}	/*	 * print the rest of the record.	 */	(void)fputs(p, stdout);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -