>Number:         176361
>Category:       bin
>Synopsis:       [PATCH] Add recursive option to ctags
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          change-request
>Submitter-Id:   current-users
>Arrival-Date:   Fri Feb 22 20:20:00 UTC 2013
>Closed-Date:
>Last-Modified:
>Originator:     Fernando
>Release:        9.0-RELEASE
>Organization:
OpenSistemas
>Environment:
FreeBSD beastie 9.0-RELEASE FreeBSD 9.0-RELEASE #0: Tue Jan  3 07:46:30 UTC 
2012     r...@farrell.cse.buffalo.edu:/usr/obj/usr/src/sys/GENERIC  amd64

>Description:
The ctags version shipped with FreeBSD lacks the -R (recursive) option that is 
extremely useful.

The patch I propose implements this feature by simply using ftw(3). It is a non 
intrusive patch as it changes nothing regarding the text analysis itself. I 
tested it with several pieces of C source code and filesystem links and seems 
to work fine.

The patch also updates the manual page.
>How-To-Repeat:
Just try ctags -R :)
>Fix:
Apply the attached patch.

It applies cleanly to FreeBSD 9.0-RELEASE sources.

Patch attached with submission follows:

diff -ruN /usr/src/usr.bin/ctags/ctags.1 ctags/ctags.1
--- /usr/src/usr.bin/ctags/ctags.1      2012-01-03 04:23:52.000000000 +0100
+++ ctags/ctags.1       2013-02-01 20:33:23.000000000 +0100
@@ -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
diff -ruN /usr/src/usr.bin/ctags/ctags.c ctags/ctags.c
--- /usr/src/usr.bin/ctags/ctags.c      2012-01-03 04:23:52.000000000 +0100
+++ ctags/ctags.c       2012-11-09 14:13:19.000000000 +0100
@@ -45,6 +45,7 @@
 __FBSDID("$FreeBSD: release/9.0.0/usr.bin/ctags/ctags.c 216370 2010-12-11 
08:32:16Z joel $");
 
 #include <err.h>
+#include <ftw.h>
 #include <limits.h>
 #include <locale.h>
 #include <regex.h>
@@ -71,6 +72,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 */
@@ -85,6 +87,24 @@
 static void usage(void);
 
 int
+ftw_callback(const char *path, const struct stat *f_stat, int flags)
+{
+       curfile = strdup(path);
+
+       if (flags == FTW_F) {
+               if (!(inf = fopen(curfile, "r"))) {
+                       warn("%s", curfile);
+                       return (1);
+               } else {
+                       find_entries(curfile);
+                       fclose(inf);
+               }
+       }
+
+       return (0); 
+}
+
+int
 main(int argc, char **argv)
 {
        static const char       *outfile = "tags";      /* output file */
@@ -98,7 +118,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 = '?';
@@ -106,6 +126,9 @@
                case 'F':
                        searchar = '/';
                        break;
+               case 'R':
+                       rflag = YES;
+                       break;
                case 'T':
                        tflag = NO;
                        break;
@@ -146,16 +169,23 @@
 
        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);
+                       if (!(inf = fopen(argv[step], "r"))) {
+                               warn("%s", argv[step]);
+                               exit_val = 1;
+                       }
+                       else {
+                               find_entries(argv[step]);
+                               (void)fclose(inf);
+                       }
+
                }
+       }
+
 
        if (head) {
                if (xflag)
diff -ruN /usr/src/usr.bin/ctags/tree.c ctags/tree.c
--- /usr/src/usr.bin/ctags/tree.c       2012-01-03 04:23:52.000000000 +0100
+++ ctags/tree.c        2012-11-07 18:36:29.000000000 +0100
@@ -127,6 +127,7 @@
                if (node->right)
                        free_tree(node->right);
                node_next = node->left;
+               free(node->file);
                free(node);
                node = node_next;
        }


>Release-Note:
>Audit-Trail:
>Unformatted:
_______________________________________________
freebsd-bugs@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-bugs
To unsubscribe, send any mail to "freebsd-bugs-unsubscr...@freebsd.org"

Reply via email to