bin/176361: [PATCH] Add recursive option to ctags

Fernando fernando.apesteguia at gmail.com
Fri Feb 22 20:20:01 UTC 2013


>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     root at 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:


More information about the freebsd-bugs mailing list