Index: gtags/gtags.c
===================================================================
RCS file: /cvsroot/global/global/gtags/gtags.c,v
retrieving revision 1.123
diff -u -r1.123 gtags.c
--- gtags/gtags.c	25 Jul 2005 02:40:25 -0000	1.123
+++ gtags/gtags.c	25 Jul 2005 13:51:09 -0000
@@ -101,6 +101,7 @@
 int noxargs;
 const char *extra_options;
 const char *info_string;
+const char *file_list;
 
 int extractmethod;
 int total;
@@ -135,6 +136,7 @@
 	{"convert", no_argument, &do_convert, 1},
 	{"debug", no_argument, &debug, 1},
 	{"expand", required_argument, &do_expand, 1},
+	{"file", required_argument, NULL, 0},
 	{"find", no_argument, &do_find, 1},
 	{"gtagsconf", required_argument, &gtagsconf, 1},
 	{"gtagslabel", required_argument, &gtagslabel, 1},
@@ -227,6 +229,8 @@
 				}
 				set_env(name, value);
 				gtagsconf = gtagslabel = 0;
+			} else if (!strcmp(p, "file")) {
+				file_list = optarg;
 			}
 			break;
 		case 'c':
@@ -682,7 +686,11 @@
 	/*
 	 * make add list and update list.
 	 */
-	for (find_open(NULL); (path = find_read()) != NULL; ) {
+	if (file_list)
+		filelist_open(file_list, root);
+	else
+		find_open(NULL);
+	while ((path = file_list ? filelist_read() : find_read()) != NULL) {
 		const char *fid;
 
 		/* a blank at the head of path means 'NOT SOURCE'. */
@@ -697,7 +705,10 @@
 			idset_add(deleteset, atoi(fid));
 		}
 	}
-	find_close();
+	if (file_list)
+		filelist_close();
+	else
+		find_close();
 	/*
 	 * make delete list.
 	 */
@@ -921,6 +932,7 @@
 	int count = 0;
 	STRBUF *path_list = strbuf_open(MAXPATHLEN);
 	int path_list_max;
+	static int gpath_created;
 
 	/*
 	 * get tag command.
@@ -982,7 +994,14 @@
 	 * the source file as a lot as possible to decrease the invoking
 	 * frequency of the parser.
 	 */
-	for (find_open(NULL); (path = find_read()) != NULL; ) {
+	if (gpath_created)
+		gfind_open(dbpath, NULL);
+	else if (file_list)
+		filelist_open(file_list, root);
+	else
+		find_open(NULL);
+	while ((path = gpath_created ? gfind_read() :
+			file_list ? filelist_read() : find_read()) != NULL) {
 		int skip = 0;
 
 		/* a blank at the head of path means 'NOT SOURCE'. */
@@ -1032,7 +1051,13 @@
 	if (strbuf_getlen(path_list))
 		gtags_add(gtop, strbuf_value(comline), path_list, gflags);
 	total = count;				/* save total count */
-	find_close();
+	if (gpath_created)
+		gfind_close();
+	else if (file_list)
+		filelist_close();
+	else
+		find_close();
+	gpath_created = 1;
 	gtags_close(gtop);
 	strbuf_close(comline);
 	strbuf_close(path_list);
Index: libutil/Makefile.am
===================================================================
RCS file: /cvsroot/global/global/libutil/Makefile.am,v
retrieving revision 1.20
diff -u -r1.20 Makefile.am
--- libutil/Makefile.am	5 Jul 2005 22:31:20 -0000	1.20
+++ libutil/Makefile.am	25 Jul 2005 13:51:09 -0000
@@ -23,7 +23,7 @@
 conf.c dbop.c defined.c die.c find.c getdbpath.c gtagsop.c locatestring.c \
 makepath.c path.c gpathop.c strbuf.c strmake.c tab.c test.c \
 token.c usable.c version.c is_unixy.c abs2rel.c split.c strlimcpy.c linetable.c \
-env.c char.c vfind.c date.c langmap.c varray.c idset.c
+env.c char.c vfind.c date.c langmap.c varray.c idset.c filelist.c
 
 AM_CFLAGS = -DBINDIR='"$(bindir)"' -DDATADIR='"$(datadir)"'
 
Index: libutil/filelist.c
===================================================================
RCS file: libutil/filelist.c
diff -N libutil/filelist.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ libutil/filelist.c	25 Jul 2005 13:51:09 -0000
@@ -0,0 +1,146 @@
+/*
+ * Copyright (c) 2005 Tama Communications Corporation
+ *
+ * This file is part of GNU GLOBAL.
+ *
+ * GNU GLOBAL is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU GLOBAL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <assert.h>
+#include <ctype.h>
+#ifdef HAVE_LIMITS_H
+#include <limits.h>
+#endif
+#include <stdio.h>
+#ifdef STDC_HEADERS
+#include <stdlib.h>
+#endif
+#ifdef HAVE_STRING_H
+#include <string.h>
+#else
+#include <strings.h>
+#endif
+
+#include "die.h"
+#include "gparam.h"
+#include "gpathop.h"
+#include "path.h"
+#include "strbuf.h"
+#include "strlimcpy.h"
+#include "test.h"
+#include "filelist.h"
+
+extern int qflag;
+
+static int opened;
+static FILE *ip;
+static STRBUF *ib;
+static char root[MAXPATHLEN + 1];
+static size_t rootlen;
+static char *line;
+static char buf[MAXPATHLEN + 1];
+
+/*
+ * filelist_open: find_open like interface for handling output of find(1).
+ *
+ *	i)	filename	file including list of file names.
+ *				When "-" is specified, read from standard input.
+ *	i)	rootdir		root directory of source tree
+ */
+void
+filelist_open(filename, rootdir)
+	const char *filename;
+	const char *rootdir;
+{
+	assert(opened == 0);
+	ib = strbuf_open(MAXBUFLEN);
+	if (filename[0] == '-' && filename[1] == '\0') {
+		ip = stdin;
+	} else {
+		if (test("d", filename))
+			die("'%s' is a directory.", filename);
+		if (!test("f", filename))
+			die("'%s' not found.", filename);
+		if (!test("r", filename))
+			die("'%s' is not readable.", filename);
+		ip = fopen(filename, "r");
+		if (ip == NULL)
+			die("cannot open '%s'.", filename);
+	}
+	strlimcpy(root, rootdir, sizeof(root));
+	rootlen = strlen(root);
+	line = NULL;
+	opened = 1;
+}
+/*
+ * filelist_read: read path from file
+ *
+ *	r)		path
+ */
+const char *
+filelist_read()
+{
+	int c;
+	char *p, *path;
+
+	assert(opened != 0);
+	for (;;) {
+		if (line == NULL || *line == '\0') {
+			line = strbuf_fgets(ib, ip, STRBUF_NOCRLF);
+			if (line == NULL)
+				return NULL;
+		}
+		while (isspace((unsigned char)*line))
+			line++;
+		if (*line == '\0')
+			continue;
+		path = line;
+		p = path + 1;
+		while ((c = (unsigned char)*p) != '\0' && !isspace(c))
+			p++;
+		*p = '\0';
+		if (c == '\0')
+			line = NULL;
+		else
+			line = p + 1;
+		if (realpath(path, buf) == NULL)
+			die("realpath(%s, buf) failed.", path);
+		if (!isabspath(buf))
+			die("realpath(3) is not compatible with BSD version.");
+		if (strncmp(buf, root, rootlen)) {
+			if (!qflag)
+				fprintf(stderr, "'%s' is out of source tree.\n", buf);
+			continue;
+		}
+		path = buf + rootlen - 1;
+		*path = '.';
+		return path;
+	}
+}
+/*
+ * filelist_close: close iterator.
+ */
+void
+filelist_close()
+{
+	assert(opened != 0);
+	if (ip != stdin)
+		fclose(ip);
+	strbuf_close(ib);
+	opened = 0;
+}
Index: libutil/filelist.h
===================================================================
RCS file: libutil/filelist.h
diff -N libutil/filelist.h
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ libutil/filelist.h	25 Jul 2005 13:51:09 -0000
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2005 Tama Communications Corporation
+ *
+ * This file is part of GNU GLOBAL.
+ *
+ * GNU GLOBAL is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU GLOBAL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA.
+ */
+#ifndef _FILELIST_H_
+#define _FILELIST_H_
+
+void filelist_open(const char *, const char *);
+const char *filelist_read(void);
+void filelist_close(void);
+
+#endif /* ! _FILELIST_H_ */
Index: libutil/global.h
===================================================================
RCS file: /cvsroot/global/global/libutil/global.h,v
retrieving revision 1.19
diff -u -r1.19 global.h
--- libutil/global.h	5 Jul 2005 22:31:20 -0000	1.19
+++ libutil/global.h	25 Jul 2005 13:51:09 -0000
@@ -31,6 +31,7 @@
 #include "defined.h"
 #include "die.h"
 #include "env.h"
+#include "filelist.h"
 #include "find.h"
 #include "getdbpath.h"
 #include "gtagsop.h"
