예제 #1
0
파일: dbop.c 프로젝트: luchachen/global
/**
 * dbop_getversion: get format version
 */
int
dbop_getversion(DBOP *dbop)
{
	int format_version = 1;			/* default format version */
	const char *p;

	if ((p = dbop_getoption(dbop, VERSIONKEY)) != NULL)
		format_version = atoi(p);
	return format_version;
}
예제 #2
0
파일: gtagsop.c 프로젝트: lshain/enviroment
/**
 * gtags_open: open global tag.
 *
 *	@param[in]	dbpath	dbpath directory
 *	@param[in]	root	root directory (needed when compact format)
 *	@param[in]	db	#GTAGS, #GRTAGS, #GSYMS
 *	@param[in]	mode	#GTAGS_READ: read only <br>
 *			#GTAGS_CREATE: create tag <br>
 *			#GTAGS_MODIFY: modify tag
 *	@param[in]	flags	#GTAGS_COMPACT: compact format
 *	@return		#GTOP structure
 *
 * @note when error occurred, @NAME{gtags_open()} doesn't return.
 */
GTOP *
gtags_open(const char *dbpath, const char *root, int db, int mode, int flags)
{
	GTOP *gtop;
	char tagfile[MAXPATHLEN];
	int dbmode;

	gtop = (GTOP *)check_calloc(sizeof(GTOP), 1);
	gtop->db = db;
	gtop->mode = mode;
	gtop->openflags = flags;
	/*
	 * Open tag file allowing duplicate records.
	 */
	switch (gtop->mode) {
	case GTAGS_READ:
		dbmode = 0;
		break;
	case GTAGS_CREATE:
		dbmode = 1;
		break;
	case GTAGS_MODIFY:
		dbmode = 2;
		break;
	default:
		assert(0);
	}
	/*
	 * GRTAGS and GSYMS are virtual tag file. They are included in a real GRTAGS file.
	 * In fact, GSYMS doesn't exist now.
	 *
	 * GRTAGS:	tags which belongs to GRTAGS, and are defined in GTAGS.
	 * GSYMS:	tags which belongs to GRTAGS, and is not defined in GTAGS.
	 */
	strlimcpy(tagfile, makepath(dbpath, dbname(db == GSYMS ? GRTAGS : db), NULL), sizeof(tagfile));
	gtop->dbop = dbop_open(tagfile, dbmode, 0644, DBOP_DUP|DBOP_SORTED_WRITE);
	if (gtop->dbop == NULL) {
		if (dbmode == 1)
			die("cannot make %s.", dbname(db));
		die("%s not found.", dbname(db));
	}
	if (gtop->mode == GTAGS_READ && db != GTAGS) {
		const char *gtags = makepath(dbpath, dbname(GTAGS), NULL);
		int format_version;

		gtop->gtags = dbop_open(gtags, 0, 0, 0);
		if (gtop->gtags == NULL)
			die("GTAGS not found.");
		format_version = dbop_getversion(gtop->dbop);
		if (format_version > upper_bound_version)
			die("%s seems new format. Please install the latest GLOBAL.", gtags);
		else if (format_version < lower_bound_version)
			die("%s seems older format. Please remake tag files.", gtags);
	}
	if (gtop->mode == GTAGS_CREATE) {
		/*
		 * Decide format.
		 */
		gtop->format = 0;
		gtop->format_version = new_format_version;
		/*
		 * GRTAGS and GSYSM always use compact format.
		 * GTAGS uses compact format only when the -c option specified.
		 */
		if (gtop->db == GRTAGS || gtop->db == GSYMS || gtop->openflags & GTAGS_COMPACT) {
			gtop->format |= GTAGS_COMPACT;
			gtop->format |= GTAGS_COMPLINE;
		} else {
			/* standard format */
			gtop->format |= GTAGS_COMPRESS;
		}
		gtop->format |= GTAGS_COMPNAME;
		if (gtop->format & GTAGS_COMPACT)
			dbop_putoption(gtop->dbop, COMPACTKEY, NULL);
		if (gtop->format & GTAGS_COMPRESS) {
			dbop_putoption(gtop->dbop, COMPRESSKEY, DEFAULT_ABBREVIATION);
			abbrev_open(DEFAULT_ABBREVIATION);
		}
		if (gtop->format & GTAGS_COMPLINE)
			dbop_putoption(gtop->dbop, COMPLINEKEY, NULL);
		if (gtop->format & GTAGS_COMPNAME)
			dbop_putoption(gtop->dbop, COMPNAMEKEY, NULL);
		dbop_putversion(gtop->dbop, gtop->format_version); 
	} else {
		/*
		 * recognize format version of GTAGS. 'format version record'
		 * is saved as a META record in GTAGS and GRTAGS.
		 * if 'format version record' is not found, it's assumed
		 * version 1.
		 */
		const char *p;
		/*
		 * check format version.
		 */
		gtop->format_version = dbop_getversion(gtop->dbop);
		if (gtop->format_version > upper_bound_version)
			die("%s seems new format. Please install the latest GLOBAL.", tagfile);
		else if (gtop->format_version < lower_bound_version)
			die("%s seems older format. Please remake tag files.", tagfile);
		gtop->format = 0;
		if (dbop_getoption(gtop->dbop, COMPACTKEY) != NULL)
			gtop->format |= GTAGS_COMPACT;
		if ((p = dbop_getoption(gtop->dbop, COMPRESSKEY)) != NULL) {
			abbrev_open(p);
			gtop->format |= GTAGS_COMPRESS;
		}
		if (dbop_getoption(gtop->dbop, COMPLINEKEY) != NULL)
			gtop->format |= GTAGS_COMPLINE;
		if (dbop_getoption(gtop->dbop, COMPNAMEKEY) != NULL)
			gtop->format |= GTAGS_COMPNAME;
	}
	if (gpath_open(dbpath, dbmode) < 0) {
		if (dbmode == 1)
			die("cannot create GPATH.");
		else
			die("GPATH not found.");
	}
	if (gtop->mode != GTAGS_READ)
		gtop->sb = strbuf_open(0);	/* This buffer is used for working area. */
	/*
	 * Stuff for compact format.
	 */
	if (gtop->format & GTAGS_COMPACT) {
		assert(root != NULL);
		strlimcpy(gtop->root, root, sizeof(gtop->root));
		if (gtop->mode != GTAGS_READ)
			gtop->path_hash = strhash_open(HASHBUCKETS);
	}
	return gtop;
}
예제 #3
0
int
decide_tag_by_context(const char *tag, const char *file, int lineno)
{
	STRBUF *sb = NULL;
	char path[MAXPATHLEN], s_fid[MAXFIDLEN];
	const char *tagline, *p;
	DBOP *dbop;
	int db = GSYMS;
	int iscompline = 0;

	if (normalize(file, get_root_with_slash(), cwd, path, sizeof(path)) == NULL)
		die("'%s' is out of source tree.", file);
	/*
	 * get file id
	 */
	if (gpath_open(dbpath, 0) < 0)
		die("GPATH not found.");
	if ((p = gpath_path2fid(path, NULL)) == NULL)
		die("path name in the context is not found.");
	strlimcpy(s_fid, p, sizeof(s_fid));
	gpath_close();
	/*
	 * read btree records directly to avoid the overhead.
	 */
	dbop = dbop_open(makepath(dbpath, dbname(GTAGS), NULL), 0, 0, 0);
	if (dbop == NULL)
		die("cannot open GTAGS.");
	if (dbop_getoption(dbop, COMPLINEKEY))
		iscompline = 1;
	tagline = dbop_first(dbop, tag, NULL, 0);
	if (tagline) {
		db = GTAGS;
		for (; tagline; tagline = dbop_next(dbop)) {
			/*
			 * examine whether the definition record include the context.
			 */
			p = locatestring(tagline, s_fid, MATCH_AT_FIRST);
			if (p != NULL && *p == ' ') {
				for (p++; *p && *p != ' '; p++)
					;
				if (*p++ != ' ' || !isdigit(*p))
					die("Impossible! decide_tag_by_context(1)");
				/*
				 * Standard format	n <blank> <image>$
				 * Compact format	d,d,d,d$
				 */
				if (!iscompline) {			/* Standard format */
					if (atoi(p) == lineno) {
						db = GRTAGS;
						goto finish;
					}
				} else {				/* Compact format */
					int n, cur, last = 0;

					do {
						if (!isdigit(*p))
							die("Impossible! decide_tag_by_context(2)");
						NEXT_NUMBER(p);
						cur = last + n;
						if (cur == lineno) {
							db = GRTAGS;
							goto finish;
						}
						last = cur;
						if (*p == '-') {
							if (!isdigit(*++p))
								die("Impossible! decide_tag_by_context(3)");
							NEXT_NUMBER(p);
							cur = last + n;
							if (lineno >= last && lineno <= cur) {
								db = GRTAGS;
								goto finish;
							}
							last = cur;
						}
						if (*p) {
							if (*p == ',')
								p++;
							else
								die("Impossible! decide_tag_by_context(4)");
						}
					} while (*p);
				}
			}
		}
	}
finish:
	dbop_close(dbop);
	if (db == GSYMS && getenv("GTAGSLIBPATH")) {
		char libdbpath[MAXPATHLEN];
		char *libdir = NULL, *nextp = NULL;

		sb = strbuf_open(0);
		strbuf_puts(sb, getenv("GTAGSLIBPATH"));
		for (libdir = strbuf_value(sb); libdir; libdir = nextp) {
			 if ((nextp = locatestring(libdir, PATHSEP, MATCH_FIRST)) != NULL)
                                *nextp++ = 0;
			if (!gtagsexist(libdir, libdbpath, sizeof(libdbpath), 0))
				continue;
			if (!strcmp(dbpath, libdbpath))
				continue;
			dbop = dbop_open(makepath(libdbpath, dbname(GTAGS), NULL), 0, 0, 0);
			if (dbop == NULL)
				continue;
			tagline = dbop_first(dbop, tag, NULL, 0);
			dbop_close(dbop);
			if (tagline != NULL) {
				db = GTAGS;
				break;
			}
		}
		strbuf_close(sb);
	}
	return db;
}