Recently I have done some modification - added option --update-file to
gtags. It updates tags for single file. I have seen that someone on
the list, also requested this feature. Possibility of considering
single file during tags update, is essential for me. I am using file
system mounted via network, with source files spread among the other
files. Tags creation sometimes takes hours - traversing through the
filesystem is very slow. Now I can do tags update after single file
edit.
Its a clean pleasure to use emacs with gnu global :-)
Attached diff, contains this feature, together with changes I did
before (IGNORE_ERROR flag and fixed root dir recognition on win32).
Regards
Mikolaj Sitarz
diff -ru global-5.7.5/gtags/const.h global-5.7.5c/gtags/const.h
--- global-5.7.5/gtags/const.h 2009-03-14 01:30:38.000000000 +0100
+++ global-5.7.5c/gtags/const.h 2009-08-06 19:09:33.000000000 +0200
@@ -26,6 +26,9 @@
-i, --incremental\n\
Update tag files incrementally. You had better use\n\
global(1) with the -u option.\n\
+--update-file file\n\
+ Update tag files for single file. Can not be used\n\
+ together with -i option.\n\
-n, --max-args number\n\
Maximum number of arguments for gtags-parser(1).\n\
By default, gtags invokes gtags-parser with arguments\n\
diff -ru global-5.7.5/gtags/gtags.c global-5.7.5c/gtags/gtags.c
--- global-5.7.5/gtags/gtags.c 2009-03-14 01:30:37.000000000 +0100
+++ global-5.7.5c/gtags/gtags.c 2009-08-06 21:46:33.000000000 +0200
@@ -79,6 +79,7 @@
int debug;
const char *config_name;
const char *file_list;
+const char *update_file;
/*
* Path filter
@@ -136,10 +137,12 @@
#define OPT_GTAGSCONF 129
#define OPT_GTAGSLABEL 130
#define OPT_PATH 131
+#define OPT_UPDATE_FILE 132
{"config", optional_argument, NULL, OPT_CONFIG},
{"gtagsconf", required_argument, NULL, OPT_GTAGSCONF},
{"gtagslabel", required_argument, NULL, OPT_GTAGSLABEL},
{"path", required_argument, NULL, OPT_PATH},
+ {"update-file",required_argument, NULL, OPT_UPDATE_FILE},
{ 0 }
};
@@ -189,6 +192,9 @@
else
die("Unknown path type.");
break;
+ case OPT_UPDATE_FILE:
+ update_file = optarg;
+ break;
case 'c':
cflag++;
break;
@@ -230,6 +236,11 @@
break;
}
}
+
+ if (iflag && update_file) {
+ die("options: -i and --update-file can not be used together");
+ }
+
if (gtagsconf) {
char path[MAXPATHLEN+1];
@@ -306,6 +317,19 @@
else if (!test("r", file_list))
die("'%s' is not readable.", file_list);
}
+
+ /*
+ * the same checking for update_file
+ */
+ if(update_file) {
+ if (test("d", update_file))
+ die("'%s' is a directory.", update_file);
+ else if (!test("f", update_file))
+ die("'%s' not found.", update_file);
+ else if (!test("r", update_file))
+ die("'%s' is not readable.", update_file);
+ }
+
if (!getcwd(cwd, MAXPATHLEN))
die("cannot get current directory.");
canonpath(cwd);
@@ -318,7 +342,7 @@
* at one of the candedite directories then gtags use existing
* tag files.
*/
- if (iflag) {
+ if (iflag || update_file) {
if (argc > 0)
realpath(*argv, dbpath);
else if (!gtagsexist(cwd, dbpath, MAXPATHLEN, vflag))
@@ -341,6 +365,12 @@
warning("GTAGS or GPATH not found. -i option ignored.");
iflag = 0;
}
+ if (update_file && (!test("f", makepath(dbpath, dbname(GTAGS), NULL)) ||
+ !test("f", makepath(dbpath, dbname(GPATH), NULL)))) {
+ if (wflag)
+ warning("GTAGS or GPATH not found. --update-file option ignored.");
+ update_file = 0;
+ }
if (!test("d", dbpath))
die("directory '%s' not found.", dbpath);
if (vflag)
@@ -368,9 +398,9 @@
if (wflag)
set_env("GTAGSWARNING", "1");
/*
- * incremental update.
+ * incremental or single file update.
*/
- if (iflag) {
+ if (iflag || update_file) {
/*
* Version check. If existing tag files are old enough
* gtagsopen() abort with error message.
@@ -501,6 +531,8 @@
*/
if (file_list)
find_open_filelist(file_list, root);
+ else if (update_file)
+ find_open_single_file(update_file,root);
else
find_open(NULL);
total = 0;
@@ -540,8 +572,9 @@
/*
* make delete list.
*/
+
limit = gpath_nextkey();
- for (id = 1; id < limit; id++) {
+ for (id = 1; id < limit && !update_file; id++) {
char fid[32];
int type;
diff -ru global-5.7.5/libutil/find.c global-5.7.5c/libutil/find.c
--- global-5.7.5/libutil/find.c 2009-03-14 01:30:37.000000000 +0100
+++ global-5.7.5c/libutil/find.c 2009-08-06 19:09:33.000000000 +0200
@@ -81,12 +81,14 @@
static char **listarray; /* list for skipping full path */
static FILE *ip;
static FILE *temp;
+static const char *update_file;
static char rootdir[MAXPATHLEN+1];
static char cwddir[MAXPATHLEN+1];
static int find_mode;
static int find_eof;
#define FIND_OPEN 1
#define FILELIST_OPEN 2
+#define SINGLE_FILE_OPEN 3
static void trim(char *);
static char *find_read_traverse(void);
@@ -475,7 +477,11 @@
/*
* rootdir always ends with '/'.
*/
+#if defined(_WIN32) || defined(__DJGPP__)
+ if (!strcmp(root+2, "/"))
+#else
if (!strcmp(root, "/"))
+#endif
strlimcpy(rootdir, root, sizeof(rootdir));
else
snprintf(rootdir, sizeof(rootdir), "%s/", root);
@@ -486,6 +492,27 @@
prepare_skip();
prepare_source();
}
+
+void find_open_single_file(const char *filename, const char *root) {
+ assert(find_mode == 0);
+ find_mode = SINGLE_FILE_OPEN;
+
+ update_file = filename;
+
+ /*
+ * rootdir always ends with '/'.
+ */
+#if defined(_WIN32) || defined(__DJGPP__)
+ if (!strcmp(root+2, "/"))
+#else
+ if (!strcmp(root, "/"))
+#endif
+ strlimcpy(rootdir, root, sizeof(rootdir));
+ else
+ snprintf(rootdir, sizeof(rootdir), "%s/", root);
+ strlimcpy(cwddir, root, sizeof(cwddir));
+}
+
/*
* find_read: read path without GPATH.
*
@@ -503,6 +530,8 @@
path = find_read_filelist();
else if (find_mode == FIND_OPEN)
path = find_read_traverse();
+ else if (find_mode == SINGLE_FILE_OPEN)
+ path = find_read_filelist();
else
die("find_read: internal error.");
return path;
@@ -621,7 +650,12 @@
strbuf_clear(ib);
for (;;) {
- path = strbuf_fgets(ib, ip, STRBUF_NOCRLF);
+ if(find_mode != SINGLE_FILE_OPEN)
+ path = strbuf_fgets(ib, ip, STRBUF_NOCRLF);
+ else {
+ path = (char *) update_file;
+ update_file = 0;
+ }
if (path == NULL) {
/* EOF */
find_eof = 1;
@@ -674,6 +708,7 @@
return path;
}
}
+
/*
* find_close: close iterator.
*/
@@ -691,9 +726,11 @@
*/
if (ip != temp)
fclose(ip);
- } else {
+ } else if (find_mode == SINGLE_FILE_OPEN) {
+ /* nothing to close now */ }
+ else
die("find_close: internal error.");
- }
+
regfree(suff);
if (skip)
regfree(skip);
diff -ru global-5.7.5/libutil/getdbpath.c global-5.7.5c/libutil/getdbpath.c
--- global-5.7.5/libutil/getdbpath.c 2009-03-14 01:30:37.000000000 +0100
+++ global-5.7.5c/libutil/getdbpath.c 2009-08-06 19:09:13.000000000 +0200
@@ -305,7 +305,11 @@
break;
} while (0);
}
+#if defined(_WIN32) || defined(__DJGPP__)
+ if (!strcmp(root+2, "/"))
+#else
if (!strcmp(root, "/"))
+#endif
strlimcpy(root_with_slash, root, sizeof(root_with_slash));
else
snprintf(root_with_slash, sizeof(root_with_slash), "%s/", root);
diff -ru global-5.7.5/libutil/xargs.c global-5.7.5c/libutil/xargs.c
--- global-5.7.5/libutil/xargs.c 2009-03-14 01:30:37.000000000 +0100
+++ global-5.7.5c/libutil/xargs.c 2009-08-06 19:09:13.000000000 +0200
@@ -283,7 +283,12 @@
* was not found. If you would like to use such command, set the
* flag to 1.
*/
+#ifdef IGNORE_ERROR
+ xp->ignore_error = 1;
+#else
xp->ignore_error = 0;
+#endif
+
/*
* By default, we doesn't put the path to GPATH.
* This option is prepared for createtags() and updatetags().
_______________________________________________
Bug-global mailing list
[email protected]
http://lists.gnu.org/mailman/listinfo/bug-global