Esempio n. 1
0
/**
 * gtags_delete: delete records belong to set of fid.
 *
 *	@param[in]	gtop	#GTOP structure
 *	@param[in]	deleteset bit array of fid
 */
void
gtags_delete(GTOP *gtop, IDSET *deleteset)
{
	const char *tagline;
	int fid;
	long id;

#ifdef USE_SQLITE3
	if (gtop->dbop->openflags & DBOP_SQLITE3) {
		STRBUF *where = strbuf_open(0);
		strbuf_puts(where, "(");
		for (id = idset_first(deleteset); id != END_OF_ID; id = idset_next(deleteset)) {
			strbuf_puts(where, "'");
			strbuf_putn(where, id);
			strbuf_puts(where, "',");
		}
		strbuf_unputc(where, ',');
		strbuf_puts(where, ")");
		dbop_delete(gtop->dbop, strbuf_value(where));
		strbuf_close(where);
	} else
#endif
	for (tagline = dbop_first(gtop->dbop, NULL, NULL, 0); tagline; tagline = dbop_next(gtop->dbop)) {
		/*
		 * Extract path from the tag line.
		 */
		fid = atoi(tagline);
		/*
		 * If the file id exists in the deleteset, delete the tagline.
		 */
		if (idset_contains(deleteset, fid))
			dbop_delete(gtop->dbop, NULL);
	}
}
Esempio 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));
}
Esempio n. 3
0
/*
 * makefileurl: make url which start with 'file:'.
 *
 *	i)	path	path name (absolute)
 *	i)	line	!=0: line number
 *	o)	url	URL
 *
 * makefileurl('/dir/a.html', 10)   => 'file:///dir/a.html#L10'
 *
 * (Windows32 environment)
 * makefileurl('c:/dir/a.html', 10) => 'file://c|/dir/a.html#L10'
 */
void
makefileurl(const char *path, int line, STRBUF *url)
{
	strbuf_puts(url, "file://");
#if _WIN32 || __DJGPP__
	/*
	 * copy drive name. (c: -> c|)
	 */
	if (isalpha(*path) && *(path+1) == ':') {
		strbuf_putc(url, *path);
		strbuf_putc(url, '|');
		path += 2;
	}
#endif
	strbuf_puts(url, path);
	if (line) {
		strbuf_puts(url, "#L");
		strbuf_putn(url, line);
	}
}
Esempio n. 4
0
/**
 * flush_pool: flush the pool and write is as compact format.
 *
 *	@param[in]	gtop	descripter of #GTOP
 *	@param[in]	s_fid
 */
static void
flush_pool(GTOP *gtop, const char *s_fid)
{
	struct sh_entry *entry;
	int header_offset;
	int i, last;

	if (s_fid == NULL && (s_fid = gpath_path2fid(gtop->cur_path, NULL)) == NULL)
		die("GPATH is corrupted.('%s' not found)", gtop->cur_path);
	/*
	 * Write records as compact format and free line number table
	 * for each entry in the pool.
	 */
	for (entry = strhash_first(gtop->path_hash); entry; entry = strhash_next(gtop->path_hash)) {
		VARRAY *vb = (VARRAY *)entry->value;
		int *lno_array = varray_assign(vb, 0, 0);
		const char *key = entry->name;

		/*
		 * 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(entry->name, ".", MATCH_LAST)) != NULL)
				key++;
			else if ((key = locatestring(entry->name, "::", MATCH_LAST)) != NULL)
				key += 2;
			else
				key = entry->name;
		}
		/* Sort line number table */
		qsort(lno_array, vb->length, sizeof(int), compare_lineno); 

		strbuf_reset(gtop->sb);
		strbuf_puts(gtop->sb, s_fid);
		strbuf_putc(gtop->sb, ' ');
		if (gtop->format & GTAGS_COMPNAME) {
			strbuf_puts(gtop->sb, compress(entry->name, key));
		} else {
			strbuf_puts(gtop->sb, entry->name);
		}
		strbuf_putc(gtop->sb, ' ');
		header_offset = strbuf_getlen(gtop->sb);
		/*
		 * If GTAGS_COMPLINE flag is set, each line number is expressed as the
		 * difference from the previous line number except for the head.
		 * GTAGS_COMPLINE is set by default in format version 5.
		 */
		if (gtop->format & GTAGS_COMPLINE) {
			int cont = 0;

			last = 0;			/* line 0 doesn't exist */
			for (i = 0; i < vb->length; i++) {
				int n = lno_array[i];

				if (n == last)
					continue;
				if (last > 0 && n == last + 1) {
					if (!cont) {
						/*
						 * Don't use range expression at the head.
						 */
						if (strbuf_getlen(gtop->sb) == header_offset)
							strbuf_putn(gtop->sb, n);
						else
							cont = last;
					}
				} else {
					/*
					 * Range expression. ex: 10-2 means 10 11 12
					 */
					if (cont) {
						strbuf_putc(gtop->sb, '-');
						strbuf_putn(gtop->sb, last - cont);
						cont = 0;
					}
					if (strbuf_getlen(gtop->sb) > header_offset) {
						strbuf_putc(gtop->sb, ',');
						strbuf_putn(gtop->sb, n - last);
					} else {
						strbuf_putn(gtop->sb, n);
					}
					if (strbuf_getlen(gtop->sb) > DBOP_PAGESIZE / 4) {
						dbop_put(gtop->dbop, key, strbuf_value(gtop->sb));
						strbuf_setlen(gtop->sb, header_offset);
					}
				}
				last = n;
			}
			if (cont) {
				strbuf_putc(gtop->sb, '-');
				strbuf_putn(gtop->sb, last - cont);
			}
		} else {
			/*
			 * This code is to support older format (version 4).
			 */
			last = 0;			/* line 0 doesn't exist */
			for (i = 0; i < vb->length; i++) {
				int n = lno_array[i];

				if (n == last)
					continue;
				if (strbuf_getlen(gtop->sb) > header_offset)
					strbuf_putc(gtop->sb, ',');
				strbuf_putn(gtop->sb, n);
				if (strbuf_getlen(gtop->sb) > DBOP_PAGESIZE / 4) {
					dbop_put(gtop->dbop, key, strbuf_value(gtop->sb));
					strbuf_setlen(gtop->sb, header_offset);
				}
				last = n;
			}
		}
		if (strbuf_getlen(gtop->sb) > header_offset) {
			dbop_put(gtop->dbop, key, strbuf_value(gtop->sb));
		}
		/* Free line number table */
		varray_close(vb);
	}
}
Esempio n. 5
0
/*
 * Make duplicate object index.
 *
 * If referred tag is only one, direct link which points the tag is generated.
 * Else if two or more tag exists, indirect link which points the tag list
 * is generated.
 */
int
makedupindex(void)
{
	STRBUF *sb = strbuf_open(0);
	STRBUF *tmp = strbuf_open(0);
	STRBUF *command = strbuf_open(0);
	int definition_count = 0;
	char srcdir[MAXPATHLEN];
	int db;
	FILEOP *fileop = NULL;
	FILE *op = NULL;
	FILE *ip = NULL;

	snprintf(srcdir, sizeof(srcdir), "../%s", SRCS);
	for (db = GTAGS; db < GTAGLIM; db++) {
		const char *kind = kinds[db];
		const char *option = options[db];
		int writing = 0;
		int count = 0;
		int entry_count = 0;
		const char *ctags_xid, *ctags_x;
		char tag[IDENTLEN], prev[IDENTLEN], first_line[MAXBUFLEN];

		if (gtags_exist[db] == 0)
			continue;
		prev[0] = 0;
		first_line[0] = 0;
		/*
		 * construct command line.
		 */
		strbuf_reset(command);
		strbuf_sprintf(command, "%s -x%s --result=ctags-xid --encode-path=\" \t\" --nofilter=path", quote_shell(global_path), option);
		/*
		 * Optimization when the --dynamic option is specified.
		 */
		if (dynamic) {
			strbuf_puts(command, " --nosource");
			if (db != GSYMS)
				strbuf_puts(command, " --nofilter=sort");
		}
		strbuf_puts(command, " \".*\"");
		if ((ip = popen(strbuf_value(command), "r")) == NULL)
			die("cannot execute command '%s'.", strbuf_value(command));
		while ((ctags_xid = strbuf_fgets(sb, ip, STRBUF_NOCRLF)) != NULL) {
			char fid[MAXFIDLEN];

			ctags_x = parse_xid(ctags_xid, fid, NULL);
			/* tag name */
			(void)strcpy_withterm(tag, ctags_x, sizeof(tag), ' ');
			if (strcmp(prev, tag)) {
				count++;
				if (vflag)
					fprintf(stderr, " [%d] adding %s %s\n", count, kind, tag);
				if (writing) {
					if (!dynamic) {
						fputs_nl(gen_list_end(), op);
						fputs_nl(body_end, op);
						fputs_nl(gen_page_end(), op);
						close_file(fileop);
						html_count++;
					}
					writing = 0;
					/*
					 * cache record: " <fid>\0<entry number>\0"
					 */
					strbuf_reset(tmp);
					strbuf_putc(tmp, ' ');
					strbuf_putn(tmp, count - 1);
					strbuf_putc(tmp, '\0');
					strbuf_putn(tmp, entry_count);
					cache_put(db, prev, strbuf_value(tmp), strbuf_getlen(tmp) + 1);
				}				
				/* single entry */
				if (first_line[0]) {
					char fid[MAXFIDLEN];
					const char *ctags_x = parse_xid(first_line, fid, NULL);
					const char *lno = nextelement(ctags_x);

					strbuf_reset(tmp);
					strbuf_puts_withterm(tmp, lno, ' ');
					strbuf_putc(tmp, '\0');
					strbuf_puts(tmp, fid);
					cache_put(db, prev, strbuf_value(tmp), strbuf_getlen(tmp) + 1);
				}
				/*
				 * Chop the tail of the line. It is not important.
				 * strlimcpy(first_line, ctags_x, sizeof(first_line));
				 */
				strncpy(first_line, ctags_xid, sizeof(first_line));
				first_line[sizeof(first_line) - 1] = '\0';
				strlimcpy(prev, tag, sizeof(prev));
				entry_count = 0;
			} else {
				/* duplicate entry */
				if (first_line[0]) {
					char fid[MAXFIDLEN];
					const char *ctags_x = parse_xid(first_line, fid, NULL);

					if (!dynamic) {
						char path[MAXPATHLEN];

						snprintf(path, sizeof(path), "%s/%s/%d.%s", distpath, dirs[db], count, HTML);
						fileop = open_output_file(path, cflag);
						op = get_descripter(fileop);
						fputs_nl(gen_page_begin(tag, SUBDIR), op);
						fputs_nl(body_begin, op);
						fputs_nl(gen_list_begin(), op);
						fputs_nl(gen_list_body(srcdir, ctags_x, fid), op);
					}
					writing = 1;
					entry_count++;
					first_line[0] = 0;
				}
				if (!dynamic) {
					fputs_nl(gen_list_body(srcdir, ctags_x, fid), op);
				}
				entry_count++;
			}
		}
		if (db == GTAGS)
			definition_count = count;
		if (pclose(ip) != 0)
			die("'%s' failed.", strbuf_value(command));
		if (writing) {
			if (!dynamic) {
				fputs_nl(gen_list_end(), op);
				fputs_nl(body_end, op);
				fputs_nl(gen_page_end(), op);
				close_file(fileop);
				html_count++;
			}
			/*
			 * cache record: " <fid>\0<entry number>\0"
			 */
			strbuf_reset(tmp);
			strbuf_putc(tmp, ' ');
			strbuf_putn(tmp, count);
			strbuf_putc(tmp, '\0');
			strbuf_putn(tmp, entry_count);
			cache_put(db, prev, strbuf_value(tmp), strbuf_getlen(tmp) + 1);
		}
		if (first_line[0]) {
			char fid[MAXFIDLEN];
			const char *ctags_x = parse_xid(first_line, fid, NULL);
			const char *lno = nextelement(ctags_x);

			strbuf_reset(tmp);
			strbuf_puts_withterm(tmp, lno, ' ');
			strbuf_putc(tmp, '\0');
			strbuf_puts(tmp, fid);
			cache_put(db, prev, strbuf_value(tmp), strbuf_getlen(tmp) + 1);
		}
	}
	strbuf_close(sb);
	strbuf_close(tmp);
	strbuf_close(command);
	return definition_count;
}
Esempio n. 6
0
/*
 * compress source line.
 *
 *	i)	in	source line
 *	i)	name	replaced string
 *	r)		compressed string
 */
char *
compress(const char *in, const char *name)
{
	STATIC_STRBUF(sb);
	const char *p = in;
	int length = strlen(name);
	int spaces = 0;

	strbuf_clear(sb);
	while (*p) {
		if (*p == ' ') {
			spaces++;
			p++;
			continue;
		}
		if (spaces > 0) {
			if (spaces >= 10) {
				strbuf_putc(sb, '@');
				strbuf_putc(sb, '{');
				strbuf_putn(sb, spaces);
				strbuf_putc(sb, '}');
			} else if (spaces > 3) {
				strbuf_putc(sb, '@');
				strbuf_putn(sb, spaces);
			} else {
				strbuf_nputc(sb, ' ', spaces);
			}
		}
		spaces = 0;
		if (*p == '@') {
			strbuf_puts(sb, "@@");
			p++;
		} else if (!strncmp(p, name, length)) {
			strbuf_puts(sb, "@n");
			p += length;
		} else if (name2ab) {
			int i, limit = name2ab->length;
			struct abbrmap *ab = (struct abbrmap *)varray_assign(name2ab, 0, 0);

			for (i = 0; i < limit; i++) {
				if (!strncmp(p, ab[i].name, ab[i].length)) {
					strbuf_putc(sb, '@');
					strbuf_putc(sb, ab[i].c);
					p += ab[i].length;
					break;
				}
			}
			if (i >= limit) {
				strbuf_putc(sb, *p);
				p++;
			}
		} else {
			strbuf_putc(sb, *p);
			p++;
		}
	}
	if (spaces > 0) {
		if (spaces < 4) {
			strbuf_nputc(sb, ' ', spaces);
		} else if (spaces < 10) {
			strbuf_putc(sb, '@');
			strbuf_putn(sb, spaces);
		} else {
			strbuf_putc(sb, '@');
			strbuf_putc(sb, '{');
			strbuf_putn(sb, spaces);
			strbuf_putc(sb, '}');
		}
	}
	return strbuf_value(sb);
}