Index: global/global.c
===================================================================
RCS file: /cvsroot/global/global/global/global.c,v
retrieving revision 1.96
diff -u -r1.96 global.c
--- global/global.c	27 Jun 2005 13:04:38 -0000	1.96
+++ global/global.c	4 Jul 2005 14:32:59 -0000
@@ -64,7 +64,7 @@
 void grep(const char *);
 void pathlist(const char *, const char *);
 void parsefile(int, char **, const char *, const char *, const char *, int);
-static int exec_parser(const char *, const char *, const char *, const char *, FILE *);
+static int exec_parser(const char *, STRBUF *, const char *, const char *, FILE *);
 void printtag(FILE *, const char *);
 int search(const char *, const char *, const char *, int);
 int includepath(const char *, const char *);
@@ -984,20 +984,15 @@
 		}
 
 		if (strbuf_getlen(path_list)
-		    && strbuf_getlen(path_list) + 1 + strlen(path) > path_list_max) {
-			count += exec_parser(parser, strbuf_value(path_list),
-					cwd, root, op);
+		    && strbuf_getlen(path_list) + strlen(path) > path_list_max) {
+			count += exec_parser(parser, path_list, cwd, root, op);
 			strbuf_reset(path_list);
 		}
 
-		if (strbuf_getlen(path_list))
-			strbuf_putc(path_list, ' ');
-		strbuf_puts(path_list, path);
-	}
-	if (strbuf_getlen(path_list)) {
-		count += exec_parser(parser, strbuf_value(path_list),
-				cwd, root, op);
+		strbuf_puts0(path_list, path);
 	}
+	if (strbuf_getlen(path_list))
+		count += exec_parser(parser, path_list, cwd, root, op);
 	gpath_close();
 	closefilter(op);
 	strbuf_close(sb);
@@ -1016,7 +1011,7 @@
  * exec_parser: execute parser
  *
  *	i)	parser		template of command line
- *	i)	path_list	space separated list of path
+ *	i)	path_list	\0 separated list of paths
  *	i)	cwd		current directory
  *	i)	root		root directory of source tree
  *	i)	op		filter to output
@@ -1025,7 +1020,7 @@
 static int
 exec_parser(parser, path_list, cwd, root, op)
 	const char *parser;
-	const char *path_list;
+	STRBUF *path_list;
 	const char *cwd;
 	const char *root;
 	FILE *op;
Index: gtags/gtags.c
===================================================================
RCS file: /cvsroot/global/global/gtags/gtags.c,v
retrieving revision 1.119
diff -u -r1.119 gtags.c
--- gtags/gtags.c	3 Jul 2005 17:38:48 -0000	1.119
+++ gtags/gtags.c	4 Jul 2005 14:32:59 -0000
@@ -59,6 +59,10 @@
 #include "global.h"
 #include "const.h"
 
+#if !defined(ARG_MAX) && defined(_SC_ARG_MAX)
+#define ARG_MAX		sysconf(_SC_ARG_MAX)
+#endif
+
 static void usage(void);
 static void help(void);
 void signal_setup(void);
@@ -66,9 +70,7 @@
 int match(const char *, const char *);
 int main(int, char **);
 int incremental(const char *, const char *);
-void updatetags(const char *, const char *, const char *, int);
-int incremental_optimized_for_speed(const char *, const char *);
-void updatetags_optimized_for_speed(const char *, const char *, const unsigned char *, int, STRBUF *, int);
+void updatetags(const char *, const char *, const unsigned char *, int, STRBUF *, int);
 void createtags(const char *, const char *, int);
 int printconf(const char *);
 void set_base_directory(const char *, const char *);
@@ -97,6 +99,7 @@
 int other_files;
 int debug;
 int secure_mode;
+int noxargs;
 const char *extra_options;
 const char *info_string;
 const char *sed_string;
@@ -138,6 +141,7 @@
 	{"gtagsconf", required_argument, &gtagsconf, 1},
 	{"gtagslabel", required_argument, &gtagslabel, 1},
 	{"idutils", no_argument, NULL, 'I'},
+	{"noxargs", no_argument, &noxargs, 1},
 	{"other", no_argument, &other_files, 1},
 	{"relative", no_argument, &do_relative, 1},
 	{"secure", no_argument, &secure_mode, 1},
@@ -592,10 +596,7 @@
 		 */
 		if (!test("f", makepath(dbpath, dbname(GPATH), NULL)))
 			die("Old version tag file found. Please remake it.");
-		if (vflag)
-			(void)incremental(dbpath, cwd);
-		else
-			(void)incremental_optimized_for_speed(dbpath, cwd);
+		(void)incremental(dbpath, cwd);
 		exit(0);
 	}
 	/*
@@ -684,9 +685,10 @@
 {
 	struct stat statp;
 	time_t gtags_mtime;
-	STRBUF *addlist = strbuf_open(0);
-	STRBUF *updatelist = strbuf_open(0);
+	STRBUF *extractlist = strbuf_open(0);
 	STRBUF *deletelist = strbuf_open(0);
+	unsigned char *fidset;
+	int max_fid = 0;
 	int updated = 0;
 	const char *path;
 
@@ -704,215 +706,6 @@
 
 	if (gpath_open(dbpath, 0) < 0)
 		die("GPATH not found.");
-	/*
-	 * make add list and update list.
-	 */
-	for (find_open(NULL); (path = find_read()) != NULL; ) {
-		/* a blank at the head of path means 'NOT SOURCE'. */
-		if (*path == ' ')
-			continue;
-		if (stat(path, &statp) < 0)
-			die("stat failed '%s'.", path);
-		if (!gpath_path2fid(path))
-			strbuf_puts0(addlist, path);
-		else if (gtags_mtime < statp.st_mtime)
-			strbuf_puts0(updatelist, path);
-	}
-	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);
-		}
-	}
-	gpath_close();
-	if (strbuf_getlen(addlist) + strbuf_getlen(deletelist) + strbuf_getlen(updatelist))
-		updated = 1;
-	/*
-	 * execute updating.
-	 */
-	signal_setup();
-	if (strbuf_getlen(updatelist) > 0) {
-		const char *start = strbuf_value(updatelist);
-		const char *end = start + strbuf_getlen(updatelist);
-		const char *p;
-
-		for (p = start; p < end; p += strlen(p) + 1) {
-			updatetags(dbpath, root, p, 0);
-			if (exitflag)
-				exit(1);
-		}
-		updated = 1;
-	}
-	if (strbuf_getlen(addlist) > 0) {
-		const char *start = strbuf_value(addlist);
-		const char *end = start + strbuf_getlen(addlist);
-		const char *p;
-
-		for (p = start; p < end; p += strlen(p) + 1) {
-			updatetags(dbpath, root, p, 1);
-			if (exitflag)
-				exit(1);
-		}
-		updated = 1;
-	}
-	if (strbuf_getlen(deletelist) > 0) {
-		const char *start = strbuf_value(deletelist);
-		const char *end = start + strbuf_getlen(deletelist);
-		const char *p;
-
-		for (p = start; p < end; p += strlen(p) + 1) {
-			updatetags(dbpath, root, p, 2);
-			if (exitflag)
-				exit(1);
-		}
-
-		gpath_open(dbpath, 2);
-		for (p = start; p < end; p += strlen(p) + 1) {
-			if (exitflag)
-				break;
-			gpath_delete(p);
-		}
-		gpath_close();
-		updated = 1;
-	}
-	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);
-	strbuf_close(updatelist);
-	return updated;
-}
-/*
- * updatetags: update tag file.
- *
- *	i)	dbpath	directory in which tag file exist
- *	i)	root	root directory of source tree
- *	i)	path	path which should be updated
- *	i)	type	0:update, 1:add, 2:delete
- */
-void
-updatetags(dbpath, root, path, type)
-	const char *dbpath;
-	const char *root;
-	const char *path;
-	int type;
-{
-	GTOP *gtop;
-	STRBUF *sb = strbuf_open(0);
-	int db;
-	const char *msg = NULL;
-
-	switch (type) {
-	case 0:	msg = "Updating"; break;
-	case 1: msg = "Adding"; break;
-	case 2:	msg = "Deleting"; break;
-	}
-	if (vflag)
-		fprintf(stderr, " %s tags of %s ...", msg, path + 2);
-	for (db = GTAGS; db < GTAGLIM; db++) {
-		int gflags = 0;
-
-		if (exitflag)
-			break;
-		/*
-		 * GTAGS needed at least.
-		 */
-		if ((db == GRTAGS || db == GSYMS) && !test("f", makepath(dbpath, dbname(db), NULL)))
-			continue;
-		/*
-		 * GTAGS needed to make GRTAGS.
-		 */
-		if (db == GRTAGS && !test("f", makepath(dbpath, dbname(GTAGS), NULL)))
-			die("GTAGS needed to create GRTAGS.");
-		if (vflag)
-			fprintf(stderr, "%s", dbname(db));
-		/*
-		 * get tag command.
-		 */
-		strbuf_reset(sb);
-		if (!getconfs(dbname(db), sb))
-			die("cannot get tag command. (%s)", dbname(db));
-		gtop = gtags_open(dbpath, root, db, GTAGS_MODIFY, 0);
-		if (type != 1)
-			gtags_delete(gtop, path);
-		if (vflag)
-			fprintf(stderr, "..");
-		if (type != 2) {
-			if (extractmethod)
-				gflags |= GTAGS_EXTRACTMETHOD;
-			if (debug)
-				gflags |= GTAGS_DEBUG;
-			gtags_add(gtop, strbuf_value(sb), path, gflags);
-		}
-		gtags_close(gtop);
-	}
-	strbuf_close(sb);
-	if (exitflag)
-		return;
-	if (vflag)
-		fprintf(stderr, " Done.\n");
-}
-/*
- * incremental_optimized_for_speed: incremental update
- *
- *	i)	dbpath	dbpath directory
- *	i)	root	root directory of source tree
- *	r)		0: not updated, 1: updated
- */
-int
-incremental_optimized_for_speed(dbpath, root)
-	const char *dbpath;
-	const char *root;
-{
-	struct stat statp;
-	time_t gtags_mtime;
-	STRBUF *extractlist = strbuf_open(0);
-	STRBUF *deletelist = strbuf_open(0);
-	unsigned char *fidset;
-	int max_fid = 0;
-	int updated = 0;
-	const char *path;
-
-	/*
-	 * 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.");
 	fidset = (unsigned char *)calloc((gpath_nextkey() + CHAR_BIT - 1) / CHAR_BIT, 1);
 	if (fidset == NULL)
 		die("short of memory.");
@@ -975,7 +768,9 @@
 			if ((db == GRTAGS || db == GSYMS)
 			    && !test("f", makepath(dbpath, dbname(db), NULL)))
 				continue;
-			updatetags_optimized_for_speed(dbpath, root, fidset, max_fid, extractlist, db);
+			if (vflag)
+				fprintf(stderr, "[%s] Updating '%s'.\n", now(), dbname(db));
+			updatetags(dbpath, root, fidset, max_fid, extractlist, db);
 			if (exitflag)
 				exit(1);
 		}
@@ -1008,13 +803,20 @@
 			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(extractlist);
 	strbuf_close(deletelist);
 	free(fidset);
 	return updated;
 }
 /*
- * updatetags_optimized_for_speed: update tag file.
+ * updatetags: update tag file.
  *
  *	i)	dbpath		directory in which tag file exist
  *	i)	root		root directory of source tree
@@ -1024,7 +826,7 @@
  *	i)	db		GTAGS, GRTAGS, GSYMS
  */
 void
-updatetags_optimized_for_speed(dbpath, root, fidset, max_fid, extractlist, db)
+updatetags(dbpath, root, fidset, max_fid, extractlist, db)
 	const char *dbpath;
 	const char *root;
 	const unsigned char *fidset;
@@ -1033,11 +835,14 @@
 	int db;
 {
 	GTOP *gtop;
-	const char *path;
 	const char *comline;
 	const char *end;
 	STRBUF *sb = strbuf_open(0);
 	int gflags;
+	STATIC_STRBUF(path_list);
+	int path_list_max;
+	int savec;
+	int pathlen;
 
 	/*
 	 * GTAGS needed to make GRTAGS.
@@ -1052,8 +857,49 @@
 		die("cannot get tag command. (%s)", dbname(db));
 	comline = strbuf_value(sb);
 
+	/*
+	 * determine the maximum length of the list of paths.
+	 */
+#ifdef ARG_MAX
+	if (noxargs) {
+		/* force processing files individually. */
+		path_list_max = 0;
+	} else {
+		path_list_max = ARG_MAX;
+		path_list_max -= 2048;
+		if (path_list_max > 20 * 1024)
+			path_list_max = 20 * 1024;
+		path_list_max -= env_size();
+		path_list_max -= strbuf_getlen(sb);
+		path_list_max -= 40;
+		if (path_list_max < 0)
+			path_list_max = 0;
+	}
+#else
+	path_list_max = 0;
+#endif
+
 	gtop = gtags_open(dbpath, root, db, GTAGS_MODIFY, 0);
+	if (gtop->format & GTAGS_COMPACT) {
+		/* force processing files individually. */
+		path_list_max = 0;
+	}
+
+	if (vflag) {
+		char fid[32];
+		const char *path;
+		int i;
 
+		for (i = 0; i < max_fid; i++) {
+			if (fidset[i / CHAR_BIT] & (1 << (i % CHAR_BIT))) {
+				snprintf(fid, sizeof(fid), "%d", i);
+				path = gpath_fid2path(fid);
+				if (path == NULL)
+					die("GPATH is corrupted.");
+				fprintf(stderr, " deleting tags of %s\n", path + 2);
+			}
+		}
+	}
 	if (max_fid > 0)
 		gtags_delete_by_fidset(gtop, fidset, max_fid);
 
@@ -1062,14 +908,25 @@
 		gflags |= GTAGS_EXTRACTMETHOD;
 	if (debug)
 		gflags |= GTAGS_DEBUG;
-	path = strbuf_value(extractlist);
-	end = path + strbuf_getlen(extractlist);
-	while (path < end) {
-		gtags_add(gtop, comline, path, gflags);
+	path_list->sbuf = path_list->curp = strbuf_value(extractlist);
+	end = path_list->curp + strbuf_getlen(extractlist);
+	while (path_list->curp < end) {
+		if (vflag)
+			fprintf(stderr, " adding tags of %s\n", path_list->curp + 2);
+		pathlen = strlen(path_list->curp);
+		if (strbuf_getlen(path_list)
+		    && strbuf_getlen(path_list) + pathlen > path_list_max) {
+			savec = *path_list->curp;
+			gtags_add(gtop, comline, path_list, gflags);
+			*path_list->curp = savec;
+			path_list->sbuf = path_list->curp;
+		}
 		if (exitflag)
 			break;
-		path += strlen(path) + 1;
+		path_list->curp += pathlen + 1;
 	}
+	if (strbuf_getlen(path_list))
+		gtags_add(gtop, comline, path_list, gflags);
 
 	gtags_close(gtop);
 	strbuf_close(sb);
@@ -1089,10 +946,12 @@
 {
 	const char *path;
 	GTOP *gtop;
-	int flags;
+	int flags, gflags;
 	const char *comline;
 	STRBUF *sb = strbuf_open(0);
 	int count = 0;
+	STRBUF *path_list = strbuf_open(MAXPATHLEN);
+	int path_list_max;
 
 	/*
 	 * get tag command.
@@ -1105,6 +964,29 @@
 	 */
 	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.
+	 */
+#ifdef ARG_MAX
+	if (noxargs) {
+		/* force processing files individually. */
+		path_list_max = 0;
+	} else {
+		path_list_max = ARG_MAX;
+		path_list_max -= 2048;
+		if (path_list_max > 20 * 1024)
+			path_list_max = 20 * 1024;
+		path_list_max -= env_size();
+		path_list_max -= strbuf_getlen(sb);
+		path_list_max -= 40;
+		if (path_list_max < 0)
+			path_list_max = 0;
+	}
+#else
+	path_list_max = 0;
+#endif
+
 	flags = 0;
 	/*
 	 * Compact format:
@@ -1122,9 +1004,17 @@
 	if (vflag > 1)
 		fprintf(stderr, " using tag command '%s <path>'.\n", comline);
 	gtop = gtags_open(dbpath, root, db, GTAGS_CREATE, flags);
+	if (gtop->format & GTAGS_COMPACT) {
+		/* force processing files individually. */
+		path_list_max = 0;
+	}
+	gflags = 0;
+	if (extractmethod)
+		gflags |= GTAGS_EXTRACTMETHOD;
+	if (debug)
+		gflags |= GTAGS_DEBUG;
 	for (find_open(NULL); (path = find_read()) != NULL; ) {
-		int	gflags = 0;
-		int	skip = 0;
+		int skip = 0;
 
 		/* a blank at the head of path means 'NOT SOURCE'. */
 		if (*path == ' ')
@@ -1152,16 +1042,20 @@
 		}
 		if (skip)
 			continue;
-		if (extractmethod)
-			gflags |= GTAGS_EXTRACTMETHOD;
-		if (debug)
-			gflags |= GTAGS_DEBUG;
-		gtags_add(gtop, comline, path, gflags);
+		if (strbuf_getlen(path_list)
+		    && strbuf_getlen(path_list) + strlen(path) > path_list_max) {
+			gtags_add(gtop, comline, path_list, gflags);
+			strbuf_reset(path_list);
+		}
+		strbuf_puts0(path_list, path);
 	}
+	if (strbuf_getlen(path_list))
+		gtags_add(gtop, comline, path_list, gflags);
 	total = count;				/* save total count */
 	find_close();
 	gtags_close(gtop);
 	strbuf_close(sb);
+	strbuf_close(path_list);
 }
 /*
  * printconf: print configuration data.
Index: libutil/gtagsop.c
===================================================================
RCS file: /cvsroot/global/global/libutil/gtagsop.c,v
retrieving revision 1.66
diff -u -r1.66 gtagsop.c
--- libutil/gtagsop.c	27 Jun 2005 12:39:51 -0000	1.66
+++ libutil/gtagsop.c	4 Jul 2005 14:33:00 -0000
@@ -121,7 +121,7 @@
  * makecommand: make command line to make global tag file
  *
  *	i)	comline	skeleton command line
- *	i)	path	path name
+ *	i)	path_list	\0 separated list of path names
  *	o)	sb	command line
  *
  * command skeleton is like this:
@@ -130,22 +130,32 @@
  *	'gtags-parser -r'
  */
 void
-makecommand(comline, path, sb)
+makecommand(comline, path_list, sb)
 	const char *comline;
-	const char *path;
+	STRBUF *path_list;
 	STRBUF *sb;
 {
 	const char *p = locatestring(comline, "%s", MATCH_FIRST);
+	const char *path, *end;
 
 	if (p) {
 		strbuf_nputs(sb, comline, p - comline);
-		strbuf_puts(sb, path);
-		strbuf_puts(sb, p + 2);
 	} else {
 		strbuf_puts(sb, comline);
 		strbuf_putc(sb, ' ');
+	}
+
+	path = strbuf_value(path_list);
+	end = path + strbuf_getlen(path_list);
+	while (path < end) {
 		strbuf_puts(sb, path);
+		path += strlen(path) + 1;
+		if (path < end)
+			strbuf_putc(sb, ' ');
 	}
+
+	if (p)
+		strbuf_puts(sb, p + 2);
 }
 /*
  * formatcheck: check format of tag command's output
@@ -198,14 +208,13 @@
 	/*
 	 * path name
 	 */
-	if (format == GTAGS_STANDARD) {
+	if ((format & (GTAGS_PATHINDEX | GTAGS_COMPACT)) != (GTAGS_PATHINDEX | GTAGS_COMPACT)) {
 		p = ptable.part[2].start;
 		if (!(*p == '.' && *(p + 1) == '/' && *(p + 2))) {
 			recover(&ptable);
 			die("path name must start with './'.\n'%s'", line);
 		}
-	}
-	if (format & GTAGS_PATHINDEX) {
+	} else {
 		for (p = ptable.part[2].start; *p; p++)
 			if (!isdigit((unsigned char)*p)) {
 				recover(&ptable);
@@ -341,7 +350,8 @@
 			gtop->ib = strbuf_open(MAXBUFLEN);
 		else
 			gtop->sb = strbuf_open(0);
-	}
+	} else if (gtop->format == GTAGS_PATHINDEX && gtop->mode != GTAGS_READ)
+		gtop->sb = strbuf_open(0);
 	return gtop;
 }
 /*
@@ -351,7 +361,8 @@
  *	i)	tag	tag name
  *	i)	record	ctags -x image
  *
- * NOTE: If format is GTAGS_COMPACT then this function is destructive.
+ * NOTE: If format is GTAGS_COMPACT or GTAGS_PATHINDEX
+ *       then this function is destructive.
  */
 void
 gtags_put(gtop, tag, record)
@@ -362,11 +373,35 @@
 	const char *line, *path;
 	SPLIT ptable;
 
-	if (gtop->format == GTAGS_STANDARD || gtop->format == GTAGS_PATHINDEX) {
+	if (gtop->format == GTAGS_STANDARD) {
 		/* entab(record); */
 		dbop_put(gtop->dbop, tag, record);
 		return;
 	}
+	if (gtop->format == GTAGS_PATHINDEX) {
+		const char *fid;
+		char *p = locatestring(record, "./", MATCH_FIRST);
+		int savec;
+
+		if (p == NULL)
+			die("path name not found.");
+		path = p;
+		p += 2;
+		while (*p && !isspace((unsigned char)*p))
+			p++;
+		savec = *p;
+		*p = '\0';
+		fid = gpath_path2fid(path);
+		if (fid == NULL)
+			die("GPATH is corrupted.('%s' not found)", path);
+		*p = savec;
+		strbuf_reset(gtop->sb);
+		strbuf_nputs(gtop->sb, record, path - record);
+		strbuf_puts(gtop->sb, fid);
+		strbuf_puts(gtop->sb, p);
+		dbop_put(gtop->dbop, tag, strbuf_value(gtop->sb));
+		return;
+	}
 	/*
 	 * gtop->format & GTAGS_COMPACT
 	 */
@@ -403,18 +438,18 @@
 	recover(&ptable);
 }
 /*
- * gtags_add: add tags belonging to the path into tag file.
+ * gtags_add: add tags belonging to the path list into tag file.
  *
  *	i)	gtop	descripter of GTOP
  *	i)	comline	tag command line
- *	i)	path	source file
+ *	i)	path_list	\0 separated list of source files
  *	i)	flags	GTAGS_UNIQUE, GTAGS_EXTRACTMETHOD, GTAGS_DEBUG
  */
 void
-gtags_add(gtop, comline, path, flags)
+gtags_add(gtop, comline, path_list, flags)
 	GTOP *gtop;
 	const char *comline;
-	const char *path;
+	STRBUF *path_list;
 	int flags;
 {
 	const char *ctags_x;
@@ -422,35 +457,41 @@
 	STRBUF *sb = strbuf_open(0);
 	STRBUF *ib = strbuf_open(MAXBUFLEN);
 	const char *fid;
+	const char *path, *end;
 
 	/*
 	 * add path index if not yet.
 	 */
-	gpath_put(path);
+	path = strbuf_value(path_list);
+	end = path + strbuf_getlen(path_list);
+	while (path < end) {
+		gpath_put(path);
+		path += strlen(path) + 1;
+	}
 	/*
 	 * make command line.
 	 */
-	makecommand(comline, path, sb);
-	/*
-	 * get file id.
-	 */
-	if (gtop->format & GTAGS_PATHINDEX) {
-		if (!(fid = gpath_path2fid(path)))
-			die("GPATH is corrupted.('%s' not found)", path);
-	} else
-		fid = "0";
+	makecommand(comline, path_list, sb);
 	/*
 	 * Compact format.
 	 */
-	if (gtop->format & GTAGS_PATHINDEX) {
-		strbuf_puts(sb, "| gtags --sed");
-		strbuf_putc(sb, ' ');
-		strbuf_puts(sb, fid);
-	}
-	if (gtop->format & GTAGS_COMPACT)
+	if (gtop->format & GTAGS_COMPACT) {
+		if (gtop->format & GTAGS_PATHINDEX) {
+			/*
+			 * get file id.
+			 */
+			path = strbuf_value(path_list);
+			if (!(fid = gpath_path2fid(path)))
+				die("GPATH is corrupted.('%s' not found)", path);
+			strbuf_puts(sb, "| gtags --sed");
+			strbuf_putc(sb, ' ');
+			strbuf_puts(sb, fid);
+		}
+
 		strbuf_puts(sb, "| gnusort -k 1,1 -k 2,2n");
-	if (flags & GTAGS_UNIQUE)
-		strbuf_puts(sb, " -u");
+		if (flags & GTAGS_UNIQUE)
+			strbuf_puts(sb, " -u");
+	}
 #ifdef DEBUG
 	if (flags & GTAGS_DEBUG)
 		fprintf(stderr, "gtags_add() executing '%s'\n", strbuf_value(sb));
Index: libutil/gtagsop.h
===================================================================
RCS file: /cvsroot/global/global/libutil/gtagsop.h,v
retrieving revision 1.21
diff -u -r1.21 gtagsop.h
--- libutil/gtagsop.h	27 Jun 2005 12:39:51 -0000	1.21
+++ libutil/gtagsop.h	4 Jul 2005 14:33:00 -0000
@@ -84,11 +84,11 @@
 } GTOP;
 
 const char *dbname(int);
-void makecommand(const char *, const char *, STRBUF *);
+void makecommand(const char *, STRBUF *, STRBUF *);
 void formatcheck(const char *, int);
 GTOP *gtags_open(const char *, const char *, int, int, int);
 void gtags_put(GTOP *, const char *, const char *);
-void gtags_add(GTOP *, const char *, const char *, int);
+void gtags_add(GTOP *, const char *, STRBUF *, int);
 void gtags_delete(GTOP *, const char *);
 void gtags_delete_by_fidset(GTOP *, const unsigned char *, int);
 const char *gtags_first(GTOP *, const char *, int);
