On Wed, Aug 19, 2015 at 12:53:15PM -0600, Todd C. Miller wrote:
> On Wed, 19 Aug 2015 20:21:08 +0200, Sebastien Marie wrote:
>
> Some minor comments inline.
>
Thanks for the comments.
Here is a new version, which include your comments, and have the
following additional changes:
- do preloading only if -v or -x are absents (same behaviour as
before)
- manage '/' and '?' as possible search char (-F/-B forward/backward
search)
- check for skipping the preloaded entry more early (instead of
parsing pattern and discard it after)
- reflects logic change in ctags.1
One behaviour change remains: if your 'tags' file was previously
generated with '-F' and you update with '-B', the previous behaviour was
to mix /^xxx/ and ?^xxx? in 'tags' file. Here, as the file is
completely regenerated (with preloaded old entries), all the updated
'tags' will be in ?^xxx? format (backward search).
Thanks.
--
Sebastien Marie
Index: ctags.1
===================================================================
RCS file: /cvs/src/usr.bin/ctags/ctags.1,v
retrieving revision 1.28
diff -u -p -r1.28 ctags.1
--- ctags.1 13 Mar 2015 19:58:41 -0000 1.28
+++ ctags.1 20 Aug 2015 10:36:40 -0000
@@ -89,12 +89,8 @@ The default behaviour is to place them i
Update the specified files in the
.Ar tags
file, that is, all
-references to them are deleted, and the new values are appended to the
+references to them are regenerated, keeping only the others values in the
file.
-(Beware: this option is implemented in a way which is rather
-slow; it is usually faster to simply rebuild the
-.Ar tags
-file.)
.It Fl v
An index of the form expected by vgrind
is produced on the standard output.
Index: ctags.c
===================================================================
RCS file: /cvs/src/usr.bin/ctags/ctags.c,v
retrieving revision 1.15
diff -u -p -r1.15 ctags.c
--- ctags.c 8 Feb 2015 23:40:34 -0000 1.15
+++ ctags.c 20 Aug 2015 10:36:40 -0000
@@ -65,6 +65,7 @@ char lbuf[LINE_MAX];
void init(void);
void find_entries(char *);
+void preload_entries(char *, int, char *[]);
int
main(int argc, char *argv[])
@@ -75,7 +76,6 @@ main(int argc, char *argv[])
int exit_val; /* exit value */
int step; /* step through args */
int ch; /* getopts char */
- char *cmd;
aflag = uflag = NO;
while ((ch = getopt(argc, argv, "BFadf:tuwvx")) != -1)
@@ -122,6 +122,8 @@ usage: (void)fprintf(stderr,
}
init();
+ if (uflag && !vflag && !xflag)
+ preload_entries(outfile, argc, argv);
for (exit_val = step = 0; step < argc; ++step)
if (!(inf = fopen(argv[step], "r"))) {
@@ -138,30 +140,10 @@ usage: (void)fprintf(stderr,
if (xflag)
put_entries(head);
else {
- if (uflag) {
- for (step = 0; step < argc; step++) {
- if (asprintf(&cmd,
- "mv %s OTAGS; fgrep -v '\t%s\t'
OTAGS >%s; rm OTAGS",
- outfile, argv[step], outfile) == -1)
- err(1, "out of space");
- system(cmd);
- free(cmd);
- cmd = NULL;
- }
- aflag = 1;
- }
if (!(outf = fopen(outfile, aflag ? "a" : "w")))
err(exit_val, "%s", outfile);
put_entries(head);
(void)fclose(outf);
- if (uflag) {
- if (asprintf(&cmd, "sort -o %s %s",
- outfile, outfile) == -1)
- err(1, "out of space");
- system(cmd);
- free(cmd);
- cmd = NULL;
- }
}
}
exit(exit_val);
@@ -252,4 +234,80 @@ find_entries(char *file)
}
}
/* C */ c_entries();
+}
+
+void
+preload_entries(char *tagsfile, int argc, char *argv[])
+{
+ FILE *fp;
+ char line[LINE_MAX];
+ char *entry = NULL;
+ char *file = NULL;
+ char *pattern = NULL;
+ char *eol;
+ int i;
+
+ in_preload = YES;
+
+ if ((fp = fopen(tagsfile, "r")) == NULL)
+ err(1, "preload_entries: %s", tagsfile);
+
+ while (1) {
+next:
+ if (fgets(line, sizeof(line), fp) == NULL)
+ break;
+
+ if ((eol = strchr(line, '\n')) == NULL)
+ errx(1, "preload_entries: line too long");
+ *eol = '\0';
+
+ /* extract entry */
+ entry = line;
+ if ((file = strchr(line, '\t')) == NULL)
+ errx(1, "preload_entries: couldn't parse entry: %s",
+ tagsfile);
+ *file = '\0';
+
+ /* extract file */
+ file++;
+ if ((pattern = strchr(file, '\t')) == NULL)
+ errx(1, "preload_entries: couldn't parse filename: %s",
+ tagsfile);
+ *pattern = '\0';
+
+ /* skip this file ? */
+ for(i = 0; i < argc; i++)
+ if (strcmp(file, argv[i]) == 0)
+ goto next;
+
+ /* rest of string is pattern */
+ pattern++;
+
+ /* grab searchar, and don't keep it around the pattern */
+ if ((pattern[0] == '/' || pattern[0] == '?')
+ && pattern[1] == '^') {
+
+ i = strlen(pattern);
+ if (pattern[i-1] == pattern[0])
+ /* remove searchar at end */
+ pattern[i-1] = '\0';
+ else
+ errx(1, "preload_entries: couldn't parse "
+ "pattern: %s", tagsfile);
+
+ /* remove searchar at begin */
+ pattern += 2;
+ }
+
+ /* add entry */
+ if ((curfile = strdup(file)) == NULL)
+ err(1, "preload_entries: strdup");
+ (void)strlcpy(lbuf, pattern, sizeof(lbuf));
+ pfnote(entry, 0);
+ }
+ if (ferror(fp))
+ err(1, "preload_entries: fgets");
+
+ (void)fclose(fp);
+ in_preload = NO;
}
Index: ctags.h
===================================================================
RCS file: /cvs/src/usr.bin/ctags/ctags.h,v
retrieving revision 1.8
diff -u -p -r1.8 ctags.h
--- ctags.h 10 Dec 2014 19:44:21 -0000 1.8
+++ ctags.h 20 Aug 2015 10:36:40 -0000
@@ -56,6 +56,7 @@ typedef struct nd_st { /* sorting stru
*pat; /* search pattern */
int lno; /* for -x option */
bool been_warned; /* set if noticed dup */
+ bool dynfile; /* set if file will need freed */
} NODE;
extern char *curfile; /* current input file name */
@@ -72,6 +73,7 @@ extern bool _wht[], _itk[], _btk[];
extern char lbuf[LINE_MAX];
extern char *lbp;
extern char searchar; /* ex search character */
+extern bool in_preload;
extern int cicmp(char *);
extern void get_line(void);
Index: tree.c
===================================================================
RCS file: /cvs/src/usr.bin/ctags/tree.c,v
retrieving revision 1.10
diff -u -p -r1.10 tree.c
--- tree.c 27 Oct 2009 23:59:37 -0000 1.10
+++ tree.c 20 Aug 2015 10:36:40 -0000
@@ -39,6 +39,8 @@
#include "ctags.h"
+bool in_preload = NO;
+
static void add_node(NODE *, NODE *);
static void free_tree(NODE *);
@@ -79,6 +81,7 @@ pfnote(char *name, int ln)
np->lno = ln;
np->left = np->right = 0;
np->been_warned = NO;
+ np->dynfile = in_preload;
if (!(np->pat = strdup(lbuf)))
err(1, NULL);
if (!head)
@@ -128,6 +131,8 @@ free_tree(NODE *node)
free(node->entry);
free(node->pat);
+ if (node->dynfile == YES)
+ free(node->file);
free(node);
}
}