On Wed, 19 Aug 2015 20:21:08 +0200, Sebastien Marie wrote:
Some minor comments inline.
- todd
> 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 19 Aug 2015 18:15:04 -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)
> + 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' OTA
> GS >%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 (ferror(fp))
> + err(1, "preload_entries: fgets");
The ferror() call above will never return true. If there was an
error, fgets() would have returned NULL. You already have an
ferror() after the loop which is sufficient.
> +
> + 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';
> +
> + /* next is pattern */
> + pattern++;
> +
> + /* don't keep "/^" and "/" around pattern */
> + if (pattern[0] == '/' && pattern[1] == '^') {
> + pattern += 2;
> + i = strlen(pattern);
> + if (pattern[i-1] == '/')
> + pattern[i-1] = '\0';
> + else
> + errx(1, "preload_entries: couldn't parse "
> + "pattern: %s", tagsfile);
> + }
> +
> + /* skip this file ? */
> + for(i = 0; i < argc; i++)
> + if (strcmp(file, argv[i]) == 0)
> + goto next;
> +
> + /* 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");
> +
> + if (fclose(fp) == EOF)
> + err(1, "preload_entries: fclose");
There's no need to check the fclose() return value on a read-only
fd since there is nothing to flush.
> +
> + 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 19 Aug 2015 18:15:04 -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 19 Aug 2015 18:15:04 -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);
> }
> }
>