Ejemplo n.º 1
0
/**
 * Read a tag segment with sorting.
 *
 *	@param[in]	gtop	#GTOP structure <br>
 *		Output:	@CODE{gtop->gtp_array}		segment table <br>
 *		Output:	@CODE{gtop->gtp_count}		segment table size <br>
 *		Output:	@CODE{gtop->gtp_index}		segment table index (initial value = 0) <br>
 *		Output:	@CODE{gtop->cur_tagname}	current tag name
 *
 * A segment is a set of tag records which have same tag name. <br>
 * This function read a segment from tag file, sort it and put it on segment table. <br>
 * This function can treat both of standard format and compact format.
 *
 * Sorting is done by three keys.
 *	- 1st key: tag name
 *	- 2nd key: file name
 *	- 3rd key: line number
 *
 * Since all records in a segment have same tag name, you need not think about 1st key.
 */
void
segment_read(GTOP *gtop)
{
	const char *tagline, *fid, *path, *lineno;
	GTP *gtp;
	struct sh_entry *sh;

	/*
	 * Save tag lines.
	 */
	gtop->cur_tagname[0] = '\0';
	while ((tagline = dbop_next(gtop->dbop)) != NULL) {
		VIRTUAL_GRTAGS_GSYMS_PROCESSING(gtop);
		/*
		 * get tag name and line number.
		 *
		 * tagline = <file id> <tag name> <line number>
		 */
		if (gtop->cur_tagname[0] == '\0') {
			strlimcpy(gtop->cur_tagname, gtop->dbop->lastkey, sizeof(gtop->cur_tagname));
		} else if (strcmp(gtop->cur_tagname, gtop->dbop->lastkey) != 0) {
			/*
			 * Dbop_next() wil read the same record again.
			 */
			dbop_unread(gtop->dbop);
			break;
		}
		gtp = varray_append(gtop->vb);
		gtp->tagline = pool_strdup(gtop->segment_pool, tagline, 0);
		gtp->tag = (const char *)gtop->cur_tagname;
		/*
		 * convert fid into hashed path name to save memory.
		 */
		fid = (const char *)strmake(tagline, " ");
		path = gpath_fid2path(fid, NULL);
		if (path == NULL)
			die("gtags_first: path not found. (fid=%s)", fid);
		sh = strhash_assign(gtop->path_hash, path, 1);
		gtp->path = sh->name;
		lineno = seekto(gtp->tagline, SEEKTO_LINENO);
		if (lineno == NULL)
			die("illegal tag record.\n%s", tagline);
		gtp->lineno = atoi(lineno);
	}
	/*
	 * Sort tag lines.
	 */
	gtop->gtp_array = varray_assign(gtop->vb, 0, 0);
	gtop->gtp_count = gtop->vb->length;
	gtop->gtp_index = 0;
	if (!(gtop->flags & GTOP_NOSORT))
		qsort(gtop->gtp_array, gtop->gtp_count, sizeof(GTP), compare_tags);
}
Ejemplo n.º 2
0
/**
 * gtags_put_using: put tag record with packing.
 *
 *	@param[in]	gtop	descripter of #GTOP
 *	@param[in]	tag	tag name
 *	@param[in]	lno	line number
 *	@param[in]	fid	file id
 *	@param[in]	img	line image
 */
void
gtags_put_using(GTOP *gtop, const char *tag, int lno, const char *fid, const char *img)
{
	const char *key;

	if (gtop->format & GTAGS_COMPACT) {
		struct sh_entry *entry;

		/*
		 * Register each record into the pool.
		 *
		 * Pool image:
		 *
		 * tagname   lno
		 * ------------------------------
		 * "funcA"   | 1| 3| 7|23|11| 2|...
		 * "funcB"   |34| 2| 5|66| 3|...
		 * ...
		 */
		entry = strhash_assign(gtop->path_hash, tag, 1);
		if (entry->value == NULL)
			entry->value = varray_open(sizeof(int), 100);
		*(int *)varray_append((VARRAY *)entry->value) = lno;
		return;
	}
	/*
	 * extract method when class method definition.
	 *
	 * Ex: Class::method(...)
	 *
	 * key	= 'method'
	 * data = 'Class::method  103 ./class.cpp ...'
	 */
	if (gtop->flags & GTAGS_EXTRACTMETHOD) {
		if ((key = locatestring(tag, ".", MATCH_LAST)) != NULL)
			key++;
		else if ((key = locatestring(tag, "::", MATCH_LAST)) != NULL)
			key += 2;
		else
			key = tag;
	} else {
		key = tag;
	}
	strbuf_reset(gtop->sb);
	strbuf_puts(gtop->sb, fid);
	strbuf_putc(gtop->sb, ' ');
	strbuf_puts(gtop->sb, (gtop->format & GTAGS_COMPNAME) ? compress(tag, key) : tag);
	strbuf_putc(gtop->sb, ' ');
	strbuf_putn(gtop->sb, lno);
	strbuf_putc(gtop->sb, ' ');
	strbuf_puts(gtop->sb, (gtop->format & GTAGS_COMPRESS) ? compress(img, key) : img);
	dbop_put(gtop->dbop, key, strbuf_value(gtop->sb));
}
Ejemplo n.º 3
0
/**
 * gfind_open: start iterator using GPATH.
 *
 *	@param[in]	dbpath  dbpath
 *	@param[in]	local   local prefix,
 *			if NULL specified, it assumes "./";
 *	@param[in]      target  GPATH_SOURCE: only source file,
 *			GPATH_OTHER: only other file,
 *			GPATH_BOTH: source file + other file
 *	@param[in]	flags	GPATH_NEARSORT
 *	@return		GFIND structure
 */
GFIND *
gfind_open(const char *dbpath, const char *local, int target, int flags)
{
	GFIND *gfind = (GFIND *)check_calloc(sizeof(GFIND), 1);

	gfind->dbop = dbop_open(makepath(dbpath, dbname(GPATH), NULL), 0, 0, 0);
	if (gfind->dbop == NULL)
		die("GPATH not found.");
	gfind->path = NULL;
	gfind->prefix = check_strdup(local ? local : "./");
	gfind->first = 1;
	gfind->eod = 0;
	gfind->target = target;
	gfind->type = GPATH_SOURCE;
	gfind->flags = flags;
	gfind->path_array = NULL;
	gfind->version = dbop_getversion(gfind->dbop);
	if (gfind->version > support_version)
		die("GPATH seems new format. Please install the latest GLOBAL.");
	else if (gfind->version < support_version)
		die("GPATH seems older format. Please remake tag files."); 
	/*
	 * Nearness sort.
	 * In fact, this timing of sort is not good for performance.
	 * Reconsideration is needed later.
	 */
	if (gfind->flags & GPATH_NEARSORT) {
		const char *path = NULL;
		VARRAY *varray = varray_open(sizeof(char *), 100);
		POOL *pool = pool_open();
		while ((path = gfind_read(gfind)) != NULL) {
			char **a = varray_append(varray);
			*a = pool_strdup(pool, path, 0);
		}
		if ((nearbase = get_nearbase_path()) == NULL)
			die("cannot get nearbase path.");
		qsort(varray_assign(varray, 0, 0), varray->length, sizeof(char *), compare_nearpath);
		gfind->path_array = varray;
		gfind->pool = pool;
		gfind->index = 0;
	}
	return gfind;
}
Ejemplo n.º 4
0
/*
 * setup two internal tables for abbreviation.
 *
 *	i)	abbrev	abbreviation string
 */
void
abbrev_open(const char *abbrev)
{
	int i, limit;
	struct abbrmap *ab;
	char *p;

	/*
	 * abbrev string: "ddefine ttypedef"
	 */
	/* copy abbrev string to static area */
	strlimcpy(abbrev_string, abbrev, sizeof(abbrev_string));
	p = abbrev_string;

	/* initialize ab2name table */
	limit = sizeof(ab2name) / sizeof(struct abbrmap);
	for (i = 0; i < limit; i++) {
		ab2name[i].c = 0;
		ab2name[i].name = NULL;
	}
	name2ab = varray_open(sizeof(struct abbrmap), 5);
	while (*p) {
		ab = (struct abbrmap *)varray_append(name2ab);
		ab->c = *p++;
		ab->name = p;
		for (; *p && *p != ' '; p++)
			;
		if (*p == ' ')
			*p++ = '\0';
		ab->length = strlen(ab->name);
		if (ab->c < 'a' || ab->c > 'z')
			die("Abbrev character must be a lower alphabetic character. (%s)", abbrev);
		i = ab->c - 'a';
		ab2name[i].c = ab->c;
		ab2name[i].name = ab->name;
		ab2name[i].length = ab->length;
	}
}
Ejemplo n.º 5
0
/**
 * anchor_load: load anchor table
 *
 *	@param[in]	path	path name
 */
void
anchor_load(const char *path)
{
	int db, current_fid;

	/* Get fid of the path */
	{
		const char *p = path2fid(path);
		if (p == NULL)
			die("anchor_load: internal error. file '%s' not found in GPATH.", path);
		current_fid = atoi(p);
	}
	FIRST = LAST = 0;
	end = CURRENT = NULL;

	if (vb == NULL)
		vb = varray_open(sizeof(struct anchor), 1000);
	else
		varray_reset(vb);

	for (db = GTAGS; db < GTAGLIM; db++) {
		XARGS *xp;
		char *ctags_xid;

		if ((xp = anchor_input[db]) == NULL)
			continue;
		/*
		 * Read from input stream until it reaches end of file
		 * or the line of another file appears.
		 */
		while ((ctags_xid = xargs_read(xp)) != NULL) {
			SPLIT ptable;
			struct anchor *a;
			int type, fid;
			const char *ctags_x = parse_xid(ctags_xid, NULL, &fid);

			/*
			 * It is the following file.
			 */
			if (current_fid != fid) {
				xargs_unread(xp);
				break;
			}
			if (split(ctags_x, 4, &ptable) < 4) {
				recover(&ptable);
				die("too small number of parts in anchor_load().\n'%s'", ctags_x);
			}
			if (db == GTAGS) {
				char *p = ptable.part[PART_LINE].start;

				for (; *p && isspace((unsigned char)*p); p++)
					;
				if (!*p) {
					recover(&ptable);
					die("The output of parser is illegal.\n%s", ctags_x);
				}
				/*
				 * Function header is applied only to the anchor whoes type is 'D'.
				 * (D: function, M: macro, T: type)
				 */
				type = 'T';
				if (*p == '#')
					type = 'M';
				else if (locatestring(p, "typedef", MATCH_AT_FIRST))
					type = 'T';
				else if ((p = locatestring(p, ptable.part[PART_TAG].start, MATCH_FIRST)) != NULL) {
					/* skip a tag and the following blanks */
					p += strlen(ptable.part[PART_TAG].start);
					for (; *p && isspace((unsigned char)*p); p++)
						;
					if (*p == '(')
						type = 'D';
				}
			}  else if (db == GRTAGS)
				type = 'R';
			else
				type = 'Y';
			/* allocate an entry */
			a = varray_append(vb);
			a->lineno = atoi(ptable.part[PART_LNO].start);
			a->type = type;
			a->done = 0;
			settag(a, ptable.part[PART_TAG].start);
			recover(&ptable);
		}
		if (ctags_xid == NULL) {
			xargs_close(anchor_input[db]);
			anchor_input[db] = NULL;
		}
	}
	if (vb->length == 0) {
		table = NULL;
	} else {
		int i, used = vb->length;
		/*
		 * Sort by lineno.
		 */
		table = varray_assign(vb, 0, 0);
		qsort(table, used, sizeof(struct anchor), cmp); 
		/*
		 * Setup some lineno.
		 */
		for (i = 0; i < used; i++)
			if (table[i].type == 'D')
				break;
		if (i < used)
			FIRST = table[i].lineno;
		for (i = used - 1; i >= 0; i--)
			if (table[i].type == 'D')
				break;
		if (i >= 0)
			LAST = table[i].lineno;
	}
	/*
	 * Setup loop range.
	 */
	start = table;
	curp = NULL;
	end = &table[vb->length];
	/* anchor_dump(stderr, 0);*/
}