Index: usr.bin/ctags/ctags.h =================================================================== --- usr.bin/ctags/ctags.h +++ usr.bin/ctags/ctags.h @@ -76,6 +76,7 @@ extern long lineftell; /* ftell after getc( inf ) == '\n' */ extern int lineno; /* line number of current line */ extern int dflag; /* -d: non-macro defines */ +extern int rflag; /* -R: recursive search */ extern int tflag; /* -t: create tags for typedefs */ extern int vflag; /* -v: vgrind style index output */ extern int wflag; /* -w: suppress warnings */ Index: usr.bin/ctags/ctags.1 =================================================================== --- usr.bin/ctags/ctags.1 +++ usr.bin/ctags/ctags.1 @@ -38,7 +38,7 @@ file .Sh SYNOPSIS .Nm -.Op Fl BFTaduwvx +.Op Fl BFRTaduwvx .Op Fl f Ar tagsfile .Ar .Sh DESCRIPTION @@ -76,6 +76,8 @@ Use forward searching patterns .Pq Li /.../ (the default). +.It Fl R +Recurse subdirectories. .It Fl T Do not create tags for typedefs, structs, unions, and enums. .It Fl a Index: usr.bin/ctags/ctags.c =================================================================== --- usr.bin/ctags/ctags.c +++ usr.bin/ctags/ctags.c @@ -47,6 +47,7 @@ __FBSDID("$FreeBSD$"); #include +#include #include #include #include @@ -73,6 +74,7 @@ int lineno; /* line number of current line */ int dflag; /* -d: non-macro defines */ +int rflag; /* -R: recursive search */ int tflag; /* -t: create tags for typedefs */ int vflag; /* -v: vgrind style index output */ int wflag; /* -w: suppress warnings */ @@ -83,9 +85,44 @@ char lbuf[LINE_MAX]; void init(void); -void find_entries(char *); +void find_entries(const char *); +static int ftw_callback(const char *path, const struct stat *f_stat, int flags); +static int process_file(const char *file); static void usage(void); +static int +process_file(const char *file) +{ + + if ((inf = fopen(file, "r")) == NULL) { + warn("%s", file); + return (1); + } else { + find_entries(file); + fclose(inf); + } + + return (0); +} + +static int +ftw_callback(const char *path, __attribute__((unused)) const struct stat *f_stat, int flags) +{ + int ret = 0; + + /* + * This will be freed in tree.c:free_tree. See node->file in that + * function. + */ + curfile = strdup(path); + + if (flags == FTW_F) { + ret = process_file(path); + } + + return (ret); +} + int main(int argc, char **argv) { @@ -100,7 +137,7 @@ aflag = uflag = NO; tflag = YES; - while ((ch = getopt(argc, argv, "BFTadf:tuwvx")) != -1) + while ((ch = getopt(argc, argv, "BFRTadf:tuwvx")) != -1) switch(ch) { case 'B': searchar = '?'; @@ -108,6 +145,9 @@ case 'F': searchar = '/'; break; + case 'R': + rflag = YES; + break; case 'T': tflag = NO; break; @@ -148,16 +188,15 @@ init(); - for (exit_val = step = 0; step < argc; ++step) - if (!(inf = fopen(argv[step], "r"))) { - warn("%s", argv[step]); - exit_val = 1; - } + for (exit_val = step = 0; step < argc; ++step) { + curfile = argv[step]; + if (rflag) + exit_val = ftw(curfile, ftw_callback, /* UNUSED */ 1); else { - curfile = argv[step]; - find_entries(argv[step]); - (void)fclose(inf); + exit_val = process_file(curfile); } + } + if (head) { if (xflag) @@ -224,7 +263,7 @@ static void usage(void) { - (void)fprintf(stderr, "usage: ctags [-BFTaduwvx] [-f tagsfile] file ...\n"); + (void)fprintf(stderr, "usage: ctags [-BFRTaduwvx] [-f tagsfile] file ...\n"); exit(1); } @@ -271,7 +310,7 @@ * which searches the file. */ void -find_entries(char *file) +find_entries(const char *file) { char *cp; Index: usr.bin/ctags/tree.c =================================================================== --- usr.bin/ctags/tree.c +++ usr.bin/ctags/tree.c @@ -100,17 +100,15 @@ dif = strcoll(node->entry, cur_node->entry); if (!dif) { - if (node->file == cur_node->file) { + if (node->file == cur_node->file) if (!wflag) - fprintf(stderr, "Duplicate entry in file %s, line %d: %s\nSecond entry ignored\n", node->file, lineno, node->entry); - return; - } + fprintf(stderr, "Duplicate entry in file %s, line %d: %s\n", node->file, lineno, node->entry); if (!cur_node->been_warned) if (!wflag) fprintf(stderr, "Duplicate entry in files %s and %s: %s (Warning only)\n", node->file, cur_node->file, node->entry); cur_node->been_warned = YES; } - else if (dif < 0) + if (dif < 0) if (cur_node->left) add_node(node, cur_node->left); else @@ -129,6 +127,7 @@ if (node->right) free_tree(node->right); node_next = node->left; + free(node->file); free(node); node = node_next; }