diff mbox series

sindex: Add option to search by location

Message ID 20200318183924.343365-1-gladkov.alexey@gmail.com (mailing list archive)
State Mainlined, archived
Headers show
Series sindex: Add option to search by location | expand

Commit Message

Alexey Gladkov March 18, 2020, 6:39 p.m. UTC
To create plugin for text editor, it may be useful to be able to search
by position in a file.

$ sindex search -l include/uapi/linux/msdos_fs.h:91:8
(---) fs/fat/dir.c 759 1 fat_ioctl_filldir FAT_IOCTL_FILLDIR_FUNC(fat_ioctl_filldir, __fat_dirent)
(r--) fs/fat/dir.c 759 1 fat_ioctl_filldir FAT_IOCTL_FILLDIR_FUNC(fat_ioctl_filldir, __fat_dirent)
(m--) fs/fat/dir.c 759 1 fat_ioctl_filldir FAT_IOCTL_FILLDIR_FUNC(fat_ioctl_filldir, __fat_dirent)
(def) include/uapi/linux/msdos_fs.h 91 8   long  d_ino;

$ sindex search -l -m w include/uapi/linux/msdos_fs.h:91:8
(m--) fs/fat/dir.c 759 1 fat_ioctl_filldir FAT_IOCTL_FILLDIR_FUNC(fat_ioctl_filldir, __fat_dirent)

Another use is to get the full name of symbol in case of a high level
of nesting:

$ sindex search -e fs/dcache.c:567
(--r) fs/dcache.c 567 9 __dentry_kill   dentry->d_op->d_prune(dentry);
(--r) fs/dcache.c 567 15 __dentry_kill   dentry->d_op->d_prune(dentry);

$ sindex search -e --format='%n' fs/dcache.c:567
dentry.d_op
dentry_operations.d_prune

$ sindex search -e --format='%n' fs/dcache.c:567:9
dentry.d_op

Signed-off-by: Alexey Gladkov <gladkov.alexey@gmail.com>
---
 sindex.1 |  8 ++++++
 sindex.c | 74 ++++++++++++++++++++++++++++++++++++++++++++++++++++++--
 2 files changed, 80 insertions(+), 2 deletions(-)

Comments

Luc Van Oostenryck March 18, 2020, 10:51 p.m. UTC | #1
On Wed, Mar 18, 2020 at 07:39:24PM +0100, Alexey Gladkov wrote:
> To create plugin for text editor, it may be useful to be able to search
> by position in a file.

Look Good. Thanks.
Applied and pushed.

-- Luc
diff mbox series

Patch

diff --git a/sindex.1 b/sindex.1
index ef39f0f9..e3e14ca3 100644
--- a/sindex.1
+++ b/sindex.1
@@ -17,6 +17,8 @@  sindex \- Semantic Indexer for C
 .B sindex
 [\fIoptions\fR] \fIsearch\fR [\fIcommand options\fR] [\fIpattern\fR]
 .br
+.B sindex [\fIoptions\fR] \fIsearch\fR [\fIcommand options\fR] (\fI-e\fR|\fI-l\fR) \fIfilename\fR:\fIlinenr\fR:\fIcolumn\fR
+.br
 .SH DESCRIPTION
 .P
 sindex is the simple to use cscope-like tool based on sparse/dissect.  Unlike
@@ -75,6 +77,12 @@  specify a kind of symbol (see
 .BR KIND
 below).
 .TP
+\fB-e\fR, \fB--explain\fR
+Show what happens in the specified file position;
+.TP
+\fB-l\fR, \fB--location\fR
+Show usage of symbols from a specific file position;
+.TP
 \fB-v\fR, \fB--verbose\fR
 show information about what is being done;
 .TP
diff --git a/sindex.c b/sindex.c
index c950254b..ea092a4a 100644
--- a/sindex.c
+++ b/sindex.c
@@ -53,6 +53,13 @@  static char *sindex_search_path = NULL;
 static char *sindex_search_symbol = NULL;
 static const char *sindex_search_format = "(%m) %f\t%l\t%c\t%C\t%s";
 
+#define EXPLAIN_LOCATION 1
+#define USAGE_BY_LOCATION 2
+static int sindex_search_by_location;
+static char *sindex_search_filename;
+static int sindex_search_line;
+static int sindex_search_column;
+
 static sqlite3 *sindex_db = NULL;
 static sqlite3_stmt *lock_stmt = NULL;
 static sqlite3_stmt *unlock_stmt = NULL;
@@ -150,6 +157,7 @@  static void show_help_search(int ret)
 {
 	printf(
 	    "Usage: %1$s search [options] [pattern]\n"
+	    "   or: %1$s search [options] (-e|-l) filename[:linenr[:column]]\n"
 	    "\n"
 	    "Utility searches information about symbol by pattern.\n"
 	    "The pattern is a glob(7) wildcard pattern.\n"
@@ -159,6 +167,8 @@  static void show_help_search(int ret)
 	    "  -p, --path=PATTERN     Search symbols only in specified directories;\n"
 	    "  -m, --mode=MODE        Search only the specified type of access;\n"
 	    "  -k, --kind=KIND        Specify a kind of symbol;\n"
+	    "  -e, --explain          Show what happens in the specified file position;\n"
+	    "  -l, --location         Show usage of symbols from a specific file position;\n"
 	    "  -v, --verbose          Show information about what is being done;\n"
 	    "  -h, --help             Show this text and exit.\n"
 	    "\n"
@@ -339,8 +349,10 @@  static void parse_cmdline_rm(int argc, char **argv)
 static void parse_cmdline_search(int argc, char **argv)
 {
 	static const struct option long_options[] = {
+		{ "explain", no_argument, NULL, 'e' },
 		{ "format", required_argument, NULL, 'f' },
 		{ "path", required_argument, NULL, 'p' },
+		{ "location", no_argument, NULL, 'l' },
 		{ "mode", required_argument, NULL, 'm' },
 		{ "kind", required_argument, NULL, 'k' },
 		{ "verbose", no_argument, NULL, 'v' },
@@ -349,8 +361,14 @@  static void parse_cmdline_search(int argc, char **argv)
 	};
 	int c;
 
-	while ((c = getopt_long(argc, argv, "+f:m:k:p:vh", long_options, NULL)) != -1) {
+	while ((c = getopt_long(argc, argv, "+ef:m:k:p:lvh", long_options, NULL)) != -1) {
 		switch (c) {
+			case 'e':
+				sindex_search_by_location = EXPLAIN_LOCATION;
+				break;
+			case 'l':
+				sindex_search_by_location = USAGE_BY_LOCATION;
+				break;
 			case 'f':
 				sindex_search_format = optarg;
 				break;
@@ -371,7 +389,32 @@  static void parse_cmdline_search(int argc, char **argv)
 		}
 	}
 
-	if (optind < argc)
+	if (sindex_search_by_location) {
+		char *str;
+
+		if (optind == argc)
+			sindex_error(1, 0, "one argument required");
+
+		str = argv[optind];
+
+		while (str) {
+			char *ptr;
+
+			if ((ptr = strchr(str, ':')) != NULL)
+				*ptr++ = '\0';
+
+			if (*str != '\0') {
+				if (!sindex_search_filename) {
+					sindex_search_filename = str;
+				} else if (!sindex_search_line) {
+					sindex_search_line = atoi(str);
+				} else if (!sindex_search_column) {
+					sindex_search_column = atoi(str);
+				}
+			}
+			str = ptr;
+		}
+	} else if (optind < argc)
 		sindex_search_symbol = argv[optind++];
 }
 
@@ -1016,6 +1059,33 @@  static void command_search(int argc, char **argv)
 			goto fail;
 	}
 
+	if (sindex_search_by_location == EXPLAIN_LOCATION) {
+		if (query_appendf(query, " AND file.name == %Q", sindex_search_filename) < 0)
+			goto fail;
+		if (sindex_search_line &&
+		    query_appendf(query, " AND sindex.line == %d", sindex_search_line) < 0)
+			goto fail;
+		if (sindex_search_column &&
+		    query_appendf(query, " AND sindex.column == %d", sindex_search_column) < 0)
+			goto fail;
+	} else if (sindex_search_by_location == USAGE_BY_LOCATION) {
+		if (query_appendf(query, " AND sindex.symbol IN (") < 0)
+			goto fail;
+		if (query_appendf(query,
+		                 "SELECT sindex.symbol FROM sindex, file WHERE"
+				 " sindex.file == file.id AND"
+		                 " file.name == %Q", sindex_search_filename) < 0)
+			goto fail;
+		if (sindex_search_line &&
+		    query_appendf(query, " AND sindex.line == %d", sindex_search_line) < 0)
+			goto fail;
+		if (sindex_search_column &&
+		    query_appendf(query, " AND sindex.column == %d", sindex_search_column) < 0)
+			goto fail;
+		if (query_appendf(query, ")") < 0)
+			goto fail;
+	}
+
 	if (query_appendf(query, " ORDER BY file.name, sindex.line, sindex.column ASC", sindex_search_path) < 0)
 		goto fail;