diff options
-rw-r--r-- | usr.bin/mg/Makefile | 4 | ||||
-rw-r--r-- | usr.bin/mg/README | 6 | ||||
-rw-r--r-- | usr.bin/mg/cscope.c | 617 | ||||
-rw-r--r-- | usr.bin/mg/def.h | 20 | ||||
-rw-r--r-- | usr.bin/mg/funmap.c | 15 | ||||
-rw-r--r-- | usr.bin/mg/keymap.c | 44 | ||||
-rw-r--r-- | usr.bin/mg/mg.1 | 56 | ||||
-rw-r--r-- | usr.bin/mg/tags.c | 2 |
8 files changed, 753 insertions, 11 deletions
diff --git a/usr.bin/mg/Makefile b/usr.bin/mg/Makefile index 4f65776b5eb..7ef7a7c5864 100644 --- a/usr.bin/mg/Makefile +++ b/usr.bin/mg/Makefile @@ -1,4 +1,4 @@ -# $OpenBSD: Makefile,v 1.25 2011/11/28 04:41:39 lum Exp $ +# $OpenBSD: Makefile,v 1.26 2012/06/07 15:15:04 lum Exp $ PROG= mg @@ -24,7 +24,7 @@ SRCS= autoexec.c basic.c buffer.c cinfo.c dir.c display.c \ # # More or less standalone extensions. # -SRCS+= cmode.c dired.c grep.c tags.c theo.c +SRCS+= cmode.c cscope.c dired.c grep.c tags.c theo.c afterinstall: ${INSTALL} -d ${DESTDIR}${DOCDIR}/mg diff --git a/usr.bin/mg/README b/usr.bin/mg/README index c1c6a7a846a..ce73b220843 100644 --- a/usr.bin/mg/README +++ b/usr.bin/mg/README @@ -73,6 +73,12 @@ Unlike GNU Emacs, Mg's minibuffer isn't multi-line aware and hence some commands like "shell-command-on-region" always pop up a buffer to display output irrespective of output's size. +While navigating source code using Mg's cscope commands, the cursor +is always at the match location rather than in *cscope* buffer. Mg uses +the same keybindings of GNU Emacs's xcscope package for it's cscope commands. +As Mg's keybindings are case-insensitive some of the commands don't have a +default keybinding. + New implementation oddities: insert and define-key are new commands corresponding to the mocklisp diff --git a/usr.bin/mg/cscope.c b/usr.bin/mg/cscope.c new file mode 100644 index 00000000000..d741637c2ce --- /dev/null +++ b/usr.bin/mg/cscope.c @@ -0,0 +1,617 @@ +/* + * Copyright (c) 2012 Sunil Nimmagadda <sunil@sunilnimmagadda.com> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <sys/types.h> +#include <sys/stat.h> +#include <sys/queue.h> + +#include <ctype.h> +#include <fcntl.h> +#include <fnmatch.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "def.h" + +#define CSSYMBOL 0 +#define CSDEFINITION 1 +#define CSCALLEDFUNCS 2 +#define CSCALLERFUNCS 3 +#define CSTEXT 4 +#define CSEGREP 6 +#define CSFINDFILE 7 +#define CSINCLUDES 8 + +struct cstokens { + const char *fname; + const char *function; + const char *lineno; + const char *pattern; +}; + +struct csmatch { + TAILQ_ENTRY(csmatch) entry; + int lineno; +}; + +struct csrecord { + TAILQ_ENTRY(csrecord) entry; + char *filename; + TAILQ_HEAD(matches, csmatch) matches; +}; + +static TAILQ_HEAD(csrecords, csrecord) csrecords = TAILQ_HEAD_INITIALIZER(csrecords); +static struct csrecord *addentryr; +static struct csrecord *currecord; +static struct csmatch *curmatch; +static const char *addentryfn; +static const char *csprompt[] = { + "Find this symbol: ", + "Find this global definition: ", + "Find functions called by this function: ", + "Find functions calling this function: ", + "Find this text string: ", + "Change this text string: ", + "Find this egrep pattern: ", + "Find this file: ", + "Find files #including this file: " +}; + +static int addentry(struct buffer *, char *); +static void csflush(void); +static int do_cscope(int); +static int csexists(const char *); +static int getattr(char *, struct cstokens *); +static int jumptomatch(void); +static void prettyprint(struct buffer *, struct cstokens *); +static const char *ltrim(const char *); + +/* + * Find this symbol. Bound to C-c s s + */ +/* ARGSUSED */ +int +cssymbol(int f, int n) +{ + return (do_cscope(CSSYMBOL)); +} + +/* + * Find this global definition. Bound to C-c s d + */ +/* ARGSUSED */int +csdefinition(int f, int n) +{ + return (do_cscope(CSDEFINITION)); +} + +/* + * Find functions called by this function. Bound to C-c s l + */ +/* ARGSUSED */ +int +csfuncalled(int f, int n) +{ + return (do_cscope(CSCALLEDFUNCS)); +} + +/* + * Find functions calling this function. Bound to C-c s c + */ +/* ARGSUSED */ +int +cscallerfuncs(int f, int n) +{ + return (do_cscope(CSCALLERFUNCS)); +} + +/* + * Find this text. Bound to C-c s t + */ +/* ARGSUSED */ +int +csfindtext(int f, int n) +{ + return (do_cscope(CSTEXT)); +} + +/* + * Find this egrep pattern. Bound to C-c s e + */ +/* ARGSUSED */ +int +csegrep(int f, int n) +{ + return (do_cscope(CSEGREP)); +} + +/* + * Find this file. Bound to C-c s f + */ +/* ARGSUSED */ +int +csfindfile(int f, int n) +{ + return (do_cscope(CSFINDFILE)); +} + +/* + * Find files #including this file. Bound to C-c s i + */ +/* ARGSUSED */ +int +csfindinc(int f, int n) +{ + return (do_cscope(CSINCLUDES)); +} + +/* + * Create list of files to index in the given directory + * using cscope-indexer. + */ +/* ARGSUSED */ +int +cscreatelist(int f, int n) +{ + struct buffer *bp; + struct stat sb; + FILE *fpipe; + char dir[NFILEN], cmd[BUFSIZ], title[BUFSIZ], *line, *bufp; + size_t len; + int clen; + + if (getbufcwd(dir, sizeof(dir)) == FALSE) + dir[0] = '\0'; + + bufp = eread("Index files in directory: ", dir, + sizeof(dir), EFCR | EFDEF | EFNEW | EFNUL); + + if (bufp == NULL) + return (ABORT); + else if (bufp[0] == '\0') + return (FALSE); + + if (stat(dir, &sb) == -1) { + ewprintf("stat: %s", strerror(errno)); + return (FALSE); + } else if (S_ISDIR(sb.st_mode) == 0) { + ewprintf("%s: Not a directory", dir); + return (FALSE); + } + + if (csexists("cscope-indexer") == FALSE) { + ewprintf("no such file or directory, cscope-indexer"); + return (FALSE); + } + + clen = snprintf(cmd, sizeof(cmd), "cscope-indexer -v %s", dir); + if (clen < 0 || clen >= sizeof(cmd)) + return (FALSE); + + if ((fpipe = popen(cmd, "r")) == NULL) { + ewprintf("problem opening pipe"); + return (FALSE); + } + + bp = bfind("*cscope*", TRUE); + if (bclear(bp) != TRUE) + return (FALSE); + bp->b_flag |= BFREADONLY; + + clen = snprintf(title, sizeof(title), "%s%s", + "Creating cscope file list 'cscope.files' in: ", dir); + if (clen < 0 || clen >= sizeof(title)) + return (FALSE); + addline(bp, title); + addline(bp, ""); + /* All lines are NUL terminated */ + while ((line = fgetln(fpipe, &len)) != NULL) { + line[len - 1] = '\0'; + addline(bp, line); + } + pclose(fpipe); + return (popbuftop(bp, WNONE)); +} + +/* + * Next Symbol. Bound to C-c s n + */ +/* ARGSUSED */ +int +csnextmatch(int f, int n) +{ + struct csrecord *r; + struct csmatch *m; + + if (curmatch == NULL) { + if ((r = TAILQ_FIRST(&csrecords)) == NULL) { + ewprintf("The *cscope* buffer does not exist yet"); + return (FALSE); + } + currecord = r; + curmatch = TAILQ_FIRST(&r->matches); + } else { + m = TAILQ_NEXT(curmatch, entry); + if (m == NULL) { + r = TAILQ_NEXT(currecord, entry); + if (r == NULL) { + ewprintf("The end of *cscope* buffer has been" + " reached"); + return (FALSE); + } else { + currecord = r; + curmatch = TAILQ_FIRST(&currecord->matches); + } + } else + curmatch = m; + } + return (jumptomatch()); +} + +/* + * Previous Symbol. Bound to C-c s p + */ +/* ARGSUSED */ +int +csprevmatch(int f, int n) +{ + struct csmatch *m; + struct csrecord *r; + + if (curmatch == NULL) + return (FALSE); + else { + m = TAILQ_PREV(curmatch, matches, entry); + if (m) + curmatch = m; + else { + r = TAILQ_PREV(currecord, csrecords, entry); + if (r == NULL) { + ewprintf("The beginning of *cscope* buffer has" + " been reached"); + return (FALSE); + } else { + currecord = r; + curmatch = TAILQ_LAST(&currecord->matches, + matches); + } + } + } + return (jumptomatch()); +} + +/* + * Next file. + */ +int +csnextfile(int f, int n) +{ + struct csrecord *r; + + if (curmatch == NULL) { + if ((r = TAILQ_FIRST(&csrecords)) == NULL) { + ewprintf("The *cscope* buffer does not exist yet"); + return (FALSE); + } + + } else { + if ((r = TAILQ_NEXT(currecord, entry)) == NULL) { + ewprintf("The end of *cscope* buffer has been reached"); + return (FALSE); + } + } + currecord = r; + curmatch = TAILQ_FIRST(&currecord->matches); + return (jumptomatch()); +} + +/* + * Previous file. + */ +int +csprevfile(int f, int n) +{ + struct csrecord *r; + + if (curmatch == NULL) { + if ((r = TAILQ_FIRST(&csrecords)) == NULL) { + ewprintf("The *cscope* buffer does not exist yet"); + return (FALSE); + } + + } else { + if ((r = TAILQ_PREV(currecord, csrecords, entry)) == NULL) { + ewprintf("The beginning of *cscope* buffer has been" + " reached"); + return (FALSE); + } + } + currecord = r; + curmatch = TAILQ_FIRST(&currecord->matches); + return (jumptomatch()); +} + +/* + * The current symbol location is extracted from currecord->filename and + * curmatch->lineno. Load the file similar to filevisit and goto the + * lineno recorded. + */ +int +jumptomatch(void) +{ + struct buffer *bp; + char *adjf; + + if (curmatch == NULL || currecord == NULL) + return (FALSE); + adjf = adjustname(currecord->filename, TRUE); + if (adjf == NULL) + return (FALSE); + if ((bp = findbuffer(adjf)) == NULL) + return (FALSE); + curbp = bp; + if (showbuffer(bp, curwp, WFFULL) != TRUE) + return (FALSE); + if (bp->b_fname[0] == '\0') { + if (readin(adjf) != TRUE) + killbuffer(bp); + } + gotoline(FFARG, curmatch->lineno); + return (TRUE); + +} + +/* + * Ask for the symbol, construct cscope commandline with the symbol + * and passed in index. Popen cscope, read the output into *cscope* + * buffer and pop it. + */ +int +do_cscope(int i) +{ + struct buffer *bp; + FILE *fpipe; + char pattern[MAX_TOKEN], cmd[BUFSIZ], title[BUFSIZ]; + char *p, *buf; + int clen, nores = 0; + size_t len; + + /* If current buffer isn't a source file just return */ + if (fnmatch("*.[chy]", curbp->b_fname, 0) != 0) { + ewprintf("C-c s not defined"); + return (FALSE); + } + + if (curtoken(0, 1, pattern) == FALSE) + return (FALSE); + p = eread(csprompt[i], pattern, MAX_TOKEN, EFNEW | EFCR | EFDEF); + if (p == NULL) + return (ABORT); + else if (p[0] == '\0') + return (FALSE); + + if (csexists("cscope") == FALSE) { + ewprintf("no such file or directory, cscope"); + return (FALSE); + } + + csflush(); + clen = snprintf(cmd, sizeof(cmd), "cscope -L -%d %s 2>/dev/null", + i, pattern); + if (clen < 0 || clen >= sizeof(cmd)) + return (FALSE); + + if ((fpipe = popen(cmd, "r")) == NULL) { + ewprintf("problem opening pipe"); + return (FALSE); + } + + bp = bfind("*cscope*", TRUE); + if (bclear(bp) != TRUE) + return (FALSE); + bp->b_flag |= BFREADONLY; + + clen = snprintf(title, sizeof(title), "%s%s", csprompt[i], pattern); + if (clen < 0 || clen >= sizeof(title)) + return (FALSE); + addline(bp, title); + addline(bp, ""); + addline(bp, "-------------------------------------------------------------------------------"); + /* All lines are NUL terminated */ + while ((buf = fgetln(fpipe, &len)) != NULL) { + buf[len - 1] = '\0'; + if (addentry(bp, buf) != TRUE) + return (FALSE); + nores = 1; + }; + pclose(fpipe); + addline(bp, "-------------------------------------------------------------------------------"); + if (nores == 0) + ewprintf("No matches were found."); + return (popbuftop(bp, WNONE)); +} + +/* + * For each line read from cscope output, extract the tokens, + * add them to list and pretty print a line in *cscope* buffer. + */ +int +addentry(struct buffer *bp, char *csline) +{ + struct csrecord *r; + struct csmatch *m; + struct cstokens t; + int lineno; + char buf[BUFSIZ]; + const char *errstr; + + r = NULL; + if (getattr(csline, &t) == FALSE) + return (FALSE); + + lineno = strtonum(t.lineno, INT_MIN, INT_MAX, &errstr); + if (errstr) + return (FALSE); + + if (addentryfn == NULL || strcmp(addentryfn, t.fname) != 0) { + if ((r = malloc(sizeof(struct csrecord))) == NULL) + return (FALSE); + addentryr = r; + if ((r->filename = strndup(t.fname, NFILEN)) == NULL) + goto cleanup; + addentryfn = r->filename; + TAILQ_INIT(&r->matches); + if ((m = malloc(sizeof(struct csmatch))) == NULL) + goto cleanup; + m->lineno = lineno; + TAILQ_INSERT_TAIL(&r->matches, m, entry); + TAILQ_INSERT_TAIL(&csrecords, r, entry); + addline(bp, ""); + if (snprintf(buf, sizeof(buf), "*** %s", t.fname) < 0) + goto cleanup; + addline(bp, buf); + } else { + if ((m = malloc(sizeof(struct csmatch))) == NULL) + goto cleanup; + m->lineno = lineno; + TAILQ_INSERT_TAIL(&addentryr->matches, m, entry); + } + prettyprint(bp, &t); + return (TRUE); +cleanup: + free(r); + return (FALSE); +} + +/* + * Cscope line: <filename> <function> <lineno> <pattern> + */ +int +getattr(char *line, struct cstokens *t) +{ + char *p; + + if ((p = strchr(line, ' ')) == NULL) + return (FALSE); + *p++ = '\0'; + t->fname = line; + line = p; + + if ((p = strchr(line, ' ')) == NULL) + return (FALSE); + *p++ = '\0'; + t->function = line; + line = p; + + if ((p = strchr(line, ' ')) == NULL) + return (FALSE); + *p++ = '\0'; + t->lineno = line; + + if (*p == '\0') + return (FALSE); + t->pattern = p; + + return (TRUE); +} + +void +prettyprint(struct buffer *bp, struct cstokens *t) +{ + char buf[BUFSIZ]; + + if (snprintf(buf, sizeof(buf), "%s[%s]\t\t%s", + t->function, t->lineno, ltrim(t->pattern)) < 0) + return; + addline(bp, buf); +} + +const char * +ltrim(const char *s) +{ + while (isblank(*s)) + s++; + return s; +} + +void +csflush(void) +{ + struct csrecord *r; + struct csmatch *m; + + while ((r = TAILQ_FIRST(&csrecords)) != NULL) { + free(r->filename); + while ((m = TAILQ_FIRST(&r->matches)) != NULL) { + TAILQ_REMOVE(&r->matches, m, entry); + free(m); + } + TAILQ_REMOVE(&csrecords, r, entry); + free(r); + } + addentryr = NULL; + addentryfn = NULL; + currecord = NULL; + curmatch = NULL; +} + +/* + * Check if the cmd exists in $PATH. Split on ":" and iterate through + * all paths in $PATH. + */ +int +csexists(const char *cmd) +{ + char fname[NFILEN], *dir, *path, *pathc, *tmp; + int cmdlen, dlen; + + /* Special case if prog contains '/' */ + if (strchr(cmd, '/')) { + if (access(cmd, F_OK) == -1) + return (FALSE); + else + return (TRUE); + } + if ((tmp = getenv("PATH")) == NULL) + return (FALSE); + if ((pathc = path = strndup(tmp, NFILEN)) == NULL) { + ewprintf("out of memory"); + return (FALSE); + } + cmdlen = strlen(cmd); + while ((dir = strsep(&path, ":")) != NULL) { + if (*dir == '\0') + *dir = '.'; + + dlen = strlen(dir); + while (dir[dlen-1] == '/') + dir[--dlen] = '\0'; /* strip trailing '/' */ + + if (dlen + 1 + cmdlen >= sizeof(fname)) { + ewprintf("path too long"); + goto cleanup; + } + snprintf(fname, sizeof(fname), "%s/%s", dir, cmd); + if(access(fname, F_OK) == 0) { + free(pathc); + return (TRUE); + } + } +cleanup: + free(pathc); + return (FALSE); +} diff --git a/usr.bin/mg/def.h b/usr.bin/mg/def.h index e7b59c525a5..d334caa75c1 100644 --- a/usr.bin/mg/def.h +++ b/usr.bin/mg/def.h @@ -1,4 +1,4 @@ -/* $OpenBSD: def.h,v 1.122 2012/05/29 05:40:36 lum Exp $ */ +/* $OpenBSD: def.h,v 1.123 2012/06/07 15:15:04 lum Exp $ */ /* This file is in the public domain. */ @@ -103,6 +103,8 @@ typedef int (*PF)(int, int); /* generally useful type */ #define KBACK 0x02 /* Backwards insert into kill ring */ #define KREG 0x04 /* This is a region-based kill */ +#define MAX_TOKEN 64 + /* * This structure holds the starting position * (as a line/offset pair) and the number of characters in a @@ -513,6 +515,22 @@ int joinline(int, int); int findtag(int, int); int poptag(int, int); int tagsvisit(int, int); +int curtoken(int, int, char *); + +/* cscope.c */ +int cssymbol(int, int); +int csdefinition(int, int); +int csfuncalled(int, int); +int cscallerfuncs(int, int); +int csfindtext(int, int); +int csegrep(int, int); +int csfindfile(int, int); +int csfindinc(int, int); +int csnextfile(int, int); +int csnextmatch(int, int); +int csprevfile(int, int); +int csprevmatch(int, int); +int cscreatelist(int, int); /* extend.c X */ int insert(int, int); diff --git a/usr.bin/mg/funmap.c b/usr.bin/mg/funmap.c index 696be91130b..01275541f22 100644 --- a/usr.bin/mg/funmap.c +++ b/usr.bin/mg/funmap.c @@ -1,4 +1,4 @@ -/* $OpenBSD: funmap.c,v 1.38 2012/04/12 04:47:59 lum Exp $ */ +/* $OpenBSD: funmap.c,v 1.39 2012/06/07 15:15:04 lum Exp $ */ /* This file is in the public domain */ @@ -182,6 +182,19 @@ static struct funmap functnames[] = { {showcpos, "what-cursor-position",}, {filewrite, "write-file",}, {yank, "yank",}, + {cssymbol, "cscope-find-this-symbol",}, + {csdefinition, "cscope-find-global-definition",}, + {csfuncalled, "cscope-find-called-functions",}, + {cscallerfuncs, "cscope-find-functions-calling-this-function",}, + {csfindtext, "cscope-find-this-text-string",}, + {csegrep, "cscope-find-egrep-pattern",}, + {csfindfile, "cscope-find-this-file",}, + {csfindinc, "cscope-find-files-including-file",}, + {csnextmatch, "cscope-next-symbol",}, + {csprevmatch, "cscope-prev-symbol",}, + {csnextfile, "cscope-next-file",}, + {csprevfile, "cscope-prev-file",}, + {cscreatelist, "cscope-create-list-of-files-to-index"}, {NULL, NULL,} }; diff --git a/usr.bin/mg/keymap.c b/usr.bin/mg/keymap.c index 54134242a23..94aead6560e 100644 --- a/usr.bin/mg/keymap.c +++ b/usr.bin/mg/keymap.c @@ -1,4 +1,4 @@ -/* $OpenBSD: keymap.c,v 1.49 2012/04/12 04:47:59 lum Exp $ */ +/* $OpenBSD: keymap.c,v 1.50 2012/06/07 15:15:04 lum Exp $ */ /* This file is in the public domain. */ @@ -39,17 +39,55 @@ struct KEYMAPE (2 + IMAPEXT) helpmap = { } }; -struct KEYMAPE (1 + IMAPEXT) ccmap = { +static PF cCsc[] = { + cscallerfuncs, /* c */ + csdefinition, /* d */ + csegrep, /* e */ + csfindfile, /* f */ + rescan, /* g */ + rescan, /* h */ + csfindinc, /* i */ + rescan, /* j */ + rescan, /* k */ + rescan, /* l */ + rescan, /* m */ + csnextmatch, /* n */ + rescan, /* o */ + csprevmatch, /* p */ + rescan, /* q */ + rescan, /* r */ + cssymbol, /* s */ + csfindtext /* t */ +}; + +static struct KEYMAPE (1 + IMAPEXT) cCsmap = { 1, 1 + IMAPEXT, rescan, { { - CCHR('@'), CCHR('@'), (PF[]){ rescan }, NULL + 'c', 't', cCsc, NULL } } }; +static PF cCs[] = { + NULL /* s */ +}; + +struct KEYMAPE (2 + IMAPEXT) ccmap = { + 2, + 2 + IMAPEXT, + rescan, + { + { + CCHR('@'), CCHR('@'), (PF[]){ rescan }, NULL + }, + { + 's', 's', cCs, (KEYMAP *) & cCsmap + } + } +}; static PF cX4cF[] = { poptofile, /* ^f */ diff --git a/usr.bin/mg/mg.1 b/usr.bin/mg/mg.1 index 3de7feeee71..83e7c9131ae 100644 --- a/usr.bin/mg/mg.1 +++ b/usr.bin/mg/mg.1 @@ -1,7 +1,7 @@ -.\" $OpenBSD: mg.1,v 1.60 2012/05/25 15:41:09 lum Exp $ +.\" $OpenBSD: mg.1,v 1.61 2012/06/07 15:15:04 lum Exp $ .\" This file is in the public domain. .\" -.Dd $Mdocdate: May 25 2012 $ +.Dd $Mdocdate: June 7 2012 $ .Dt MG 1 .Os .Sh NAME @@ -79,6 +79,14 @@ supports tag files created by .Xr ctags 1 , allowing the user to quickly locate various object definitions. Note though that emacs uses etags, not ctags. +.Sh CSCOPE +.Nm +supports navigating source code using cscope. +However, +.Nm +requires cscope and cscope-indexer executables to be present in +.Ev PATH +for it to work. .Sh DEFAULT KEY BINDINGS Normal editing commands are very similar to GNU Emacs. In the following examples, C-x means Control-x, and M-x means Meta-x, @@ -92,6 +100,24 @@ set-mark-command beginning-of-line .It C-b backward-char +.It C-c s c +cscope-find-functions-calling-this-function +.It C-c s d +cscope-find-global-definition +.It C-c s e +cscope-find-egrep-pattern +.It C-c s f +cscope-find-this-file +.It C-c s i +cscope-find-files-including-file +.It C-c s n +cscope-next-symbol +.It C-c s p +cscope-prev-symbol +.It C-c s s +cscope-find-this-symbol +.It C-c s t +cscope-find-this-text-string .It C-d delete-char .It C-e @@ -369,6 +395,32 @@ This is a bit like a kill-region followed by a yank. Count the number of lines matching the supplied regular expression. .It count-non-matches Count the number of lines not matching the supplied regular expression. +.It cscope-find-this-symbol +List the matches for the given symbol. +.It cscope-find-global-definition +List global definitions for the given literal. +.It cscope-find-called-functions +List functions called from the given function. +.It cscope-find-functions-calling-this-function +List functions calling the given function. +.It cscope-find-this-text-string +List locations matching the given text string. +.It cscope-find-egrep-pattern +List locations matching the given extended regular expression pattern. +.It cscope-find-this-file +List filenames matching the given filename. +.It cscope-find-files-including-file +List files that #include the given filename. +.It cscope-next-symbol +Navigate to the next match. +.It cscope-prev-symbol +Navigate to the previous match. +.It cscope-next-file +Nagivate to the next file. +.It cscope-prev-file +Navigate to the previous file. +.It cscope-create-list-of-files-to-index +Create cscope's List and Index in the given directory. .It define-key Prompts the user for a named keymap (mode), a key, and an diff --git a/usr.bin/mg/tags.c b/usr.bin/mg/tags.c index 5ee9a9965bf..55574dd3779 100644 --- a/usr.bin/mg/tags.c +++ b/usr.bin/mg/tags.c @@ -33,7 +33,6 @@ static int addctag(char *); static int atbow(void); void closetags(void); static int ctagcmp(struct ctag *, struct ctag *); -static int curtoken(int, int, char *); static int loadbuffer(char *); static int loadtags(const char *); static int pushtag(char *); @@ -42,7 +41,6 @@ static struct ctag *searchtag(char *); static char *strip(char *, size_t); static void unloadtags(void); -#define MAX_TOKEN 64 #define DEFAULTFN "tags" char *tagsfn = NULL; |