summaryrefslogtreecommitdiffstats
path: root/contrib/nvi/ex
diff options
context:
space:
mode:
authorjkh <jkh@FreeBSD.org>1997-04-18 23:36:52 +0000
committerjkh <jkh@FreeBSD.org>1997-04-18 23:36:52 +0000
commitc87043915bcfdce2b8ed90750a5f5ed2ee987535 (patch)
tree39809647dfb0188b77313938742b106bf2b0d919 /contrib/nvi/ex
parent385cd60e059598672473eaed82f6c2bc41774df1 (diff)
downloadFreeBSD-src-c87043915bcfdce2b8ed90750a5f5ed2ee987535.zip
FreeBSD-src-c87043915bcfdce2b8ed90750a5f5ed2ee987535.tar.gz
Enable GLOBAL tags support for nvi.
Submitted-By: Shigio Yamaguchi <shigio@wafu.netgate.net>
Diffstat (limited to 'contrib/nvi/ex')
-rw-r--r--contrib/nvi/ex/ex.h3
-rw-r--r--contrib/nvi/ex/ex_cmd.c7
-rw-r--r--contrib/nvi/ex/ex_tag.c142
3 files changed, 152 insertions, 0 deletions
diff --git a/contrib/nvi/ex/ex.h b/contrib/nvi/ex/ex.h
index 5870990..f40be8a 100644
--- a/contrib/nvi/ex/ex.h
+++ b/contrib/nvi/ex/ex.h
@@ -152,6 +152,9 @@ struct _excmd {
#define E_SEARCH_WMSG 0x01000000 /* Display search-wrapped message. */
#define E_USELASTCMD 0x02000000 /* Use the last command. */
#define E_VISEARCH 0x04000000 /* It's really a vi search command. */
+#ifdef GTAGS
+#define E_REFERENCE 0x08000000 /* locate function references */
+#endif
u_int32_t flags; /* Current flags. */
};
diff --git a/contrib/nvi/ex/ex_cmd.c b/contrib/nvi/ex/ex_cmd.c
index 8f7fc8d..8c9801d 100644
--- a/contrib/nvi/ex/ex_cmd.c
+++ b/contrib/nvi/ex/ex_cmd.c
@@ -302,6 +302,13 @@ EXCMDLIST const cmds[] = {
"!",
"rew[ind][!]",
"re-edit all the files in the file argument list"},
+#ifdef GTAGS
+/* C_RTAG */
+ {"rtag", ex_rtag_push, E_NEWSCREEN,
+ "!w1o",
+ "[Rr]ta[g][!] [string]",
+ "edit the file containing the tag"},
+#endif
/*
* !!!
* Adding new commands starting with 's' may break the substitute command code
diff --git a/contrib/nvi/ex/ex_tag.c b/contrib/nvi/ex/ex_tag.c
index 461b152..7396b7a 100644
--- a/contrib/nvi/ex/ex_tag.c
+++ b/contrib/nvi/ex/ex_tag.c
@@ -46,6 +46,10 @@ static char *binary_search __P((char *, char *, char *));
static int compare __P((char *, char *, char *));
static void ctag_file __P((SCR *, TAGF *, char *, char **, size_t *));
static int ctag_search __P((SCR *, char *, size_t, char *));
+#ifdef GTAGS
+static int getentry __P((char *, char *, char *, char *));
+static TAGQ *gtag_slist __P((SCR *, char *, int));
+#endif
static int ctag_sfile __P((SCR *, TAGF *, TAGQ *, char *));
static TAGQ *ctag_slist __P((SCR *, char *));
static char *linear_search __P((char *, char *, char *));
@@ -89,6 +93,25 @@ ex_tag_first(sp, tagarg)
return (0);
}
+#ifdef GTAGS
+/*
+ * ex_rtag_push -- ^]
+ * :rtag[!] [string]
+ *
+ * Enter a new TAGQ context based on a ctag string.
+ *
+ * PUBLIC: int ex_rtag_push __P((SCR *, EXCMD *));
+ */
+int
+ex_rtag_push(sp, cmdp)
+ SCR *sp;
+ EXCMD *cmdp;
+{
+ F_SET(cmdp, E_REFERENCE);
+ return ex_tag_push(sp, cmdp);
+}
+#endif
+
/*
* ex_tag_push -- ^]
* :tag[!] [string]
@@ -138,6 +161,12 @@ ex_tag_push(sp, cmdp)
}
/* Get the tag information. */
+#ifdef GTAGS
+ if (O_ISSET(sp, O_GTAGSMODE)) {
+ if ((tqp = gtag_slist(sp, exp->tag_last, F_ISSET(cmdp, E_REFERENCE))) == NULL)
+ return (1);
+ } else
+#endif
if ((tqp = ctag_slist(sp, exp->tag_last)) == NULL)
return (1);
@@ -969,6 +998,119 @@ notfound: tag_msg(sp, TAG_SEARCH, tag);
return (0);
}
+#ifdef GTAGS
+/*
+ * getentry --
+ * get tag information from current line.
+ *
+ * gtags temporary file format.
+ * <tag> <lineno> <file> <image>
+ *
+ * sample.
+ * +------------------------------------------------
+ * |main 30 main.c main(argc, argv)
+ * |func 21 subr.c func(arg)
+ */
+static int
+getentry(buf, tag, file, line)
+ char *buf, *tag, *file, *line;
+{
+ char *p;
+
+ p = tag;
+ while (*buf && !isspace(*buf)) /* tag name */
+ *p++ = *buf++;
+ *p = 0;
+ while (*buf && isspace(*buf)) /* skip blanks */
+ buf++;
+ p = line;
+ while (*buf && !isspace(*buf)) /* line no */
+ *p++ = *buf++;
+ *p = 0;
+ while (*buf && isspace(*buf)) /* skip blanks */
+ buf++;
+ p = file;
+ while (*buf && !isspace(*buf)) /* file name */
+ *p++ = *buf++;
+ *p = 0;
+
+ /* value check */
+ if (strlen(tag) && strlen(line) && strlen(file) && atoi(line) > 0)
+ return 1; /* OK */
+ return 0; /* ERROR */
+}
+
+/*
+ * gtag_slist --
+ * Search the list of tags files for a tag, and return tag queue.
+ */
+static TAGQ *
+gtag_slist(sp, tag, ref)
+ SCR *sp;
+ char *tag;
+ int ref;
+{
+ EX_PRIVATE *exp;
+ TAGF *tfp;
+ TAGQ *tqp;
+ size_t len;
+ int echk;
+ TAG *tp;
+ static char name[80], file[200], line[10];
+ char command[200];
+ char buf[BUFSIZ+1];
+ FILE *fp;
+
+ /* Allocate and initialize the tag queue structure. */
+ len = strlen(tag);
+ CALLOC_GOTO(sp, tqp, TAGQ *, 1, sizeof(TAGQ) + len + 1);
+ CIRCLEQ_INIT(&tqp->tagq);
+ tqp->tag = tqp->buf;
+ memcpy(tqp->tag, tag, (tqp->tlen = len) + 1);
+
+ /*
+ * Find the tag, only display missing file messages once, and
+ * then only if we didn't find the tag.
+ */
+ sprintf(command, "global -%s '%s'", ref ? "rx" : "x", tag);
+ if (fp = popen(command, "r")) {
+ while (fgets(buf, sizeof(buf), fp)) {
+ if (buf[strlen(buf)-1] == '\n') /* chop(buf) */
+ buf[strlen(buf)-1] = 0;
+ else
+ while (fgetc(fp) != '\n')
+ ;
+ if (getentry(buf, name, file, line) == 0) {
+ echk = 1;
+ F_SET(tfp, TAGF_ERR);
+ break;
+ }
+ CALLOC_GOTO(sp, tp,
+ TAG *, 1, sizeof(TAG) + strlen(file) + 1 + strlen(line) + 1);
+ tp->fname = tp->buf;
+ strcpy(tp->fname, file);
+ tp->fnlen = strlen(file);
+ tp->search = tp->fname + tp->fnlen + 1;
+ strcpy(tp->search, line);
+ CIRCLEQ_INSERT_TAIL(&tqp->tagq, tp, q);
+ }
+ pclose(fp);
+ }
+
+ /* Check to see if we found anything. */
+ if (tqp->tagq.cqh_first == (void *)&tqp->tagq) {
+ msgq_str(sp, M_ERR, tag, "162|%s: tag not found");
+ free(tqp);
+ return (NULL);
+ }
+
+ tqp->current = tqp->tagq.cqh_first;
+ return (tqp);
+
+alloc_err:
+ return (NULL);
+}
+#endif
/*
* ctag_slist --
* Search the list of tags files for a tag, and return tag queue.
OpenPOWER on IntegriCloud