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);
        }
 }

Reply via email to