$NetBSD: patch-global,v 1.1 2000/05/08 11:52:12 sakamoto Exp $

diff -NrU2 ../build/Makefile.in ../../nvi-1.79/build/Makefile.in
--- ../build/Makefile.in	Mon May  8 16:05:17 2000
+++ ../../nvi-1.79/build/Makefile.in	Mon May  8 16:06:15 2000
@@ -4,5 +4,5 @@
 CC=	@CC@
 OPTFLAG=@OPTFLAG@
-CFLAGS=	-c $(OPTFLAG) @CFLAGS@ -I. -I$(srcdir)/include @CPPFLAGS@
+CFLAGS=	-c $(OPTFLAG) @CFLAGS@ -I. -I$(srcdir)/include @CPPFLAGS@ -DGTAGS
 LDFLAGS=@LDFLAGS@
 PERL=	@vi_cv_path_perl@
diff -NrU2 ../common/main.c ../../nvi-1.79/common/main.c
--- ../common/main.c	Sat Oct 12 07:28:28 1996
+++ ../../nvi-1.79/common/main.c	Mon May  8 16:06:15 2000
@@ -65,4 +65,7 @@
 	u_int flags;
 	int ch, flagchk, lflag, secure, startup, readonly, rval, silent;
+#ifdef GTAGS
+	int gtags = 0;
+#endif
 	char *tag_f, *wsizearg, path[256];
 
@@ -114,4 +117,11 @@
 	F_SET(gp, G_SNAPSHOT);
 
+#ifdef GTAGS
+#ifdef DEBUG
+	while ((ch = getopt(argc, argv, "c:D:eFGlRrSsT:t:vw:")) != EOF)
+#else
+	while ((ch = getopt(argc, argv, "c:eFGlRrSst:vw:")) != EOF)
+#endif
+#else
 #ifdef DEBUG
 	while ((ch = getopt(argc, argv, "c:D:eFlRrSsT:t:vw:")) != EOF)
@@ -119,4 +129,5 @@
 	while ((ch = getopt(argc, argv, "c:eFlRrSst:vw:")) != EOF)
 #endif
+#endif
 		switch (ch) {
 		case 'c':		/* Run the command. */
@@ -155,4 +166,9 @@
 			F_CLR(gp, G_SNAPSHOT);
 			break;
+#ifdef GTAGS
+		case 'G':		/* gtags mode. */
+			gtags = 1;
+			break;
+#endif
 		case 'l':		/* Set lisp, showmatch options. */
 			lflag = 1;
@@ -253,4 +269,8 @@
 	if (readonly)
 		*oargp++ = O_READONLY;
+#ifdef GTAGS
+	if (gtags)
+		*oargp++ = O_GTAGSMODE;
+#endif
 	if (secure)
 		*oargp++ = O_SECURE;
diff -NrU2 ../common/options.c ../../nvi-1.79/common/options.c
--- ../common/options.c	Mon May  8 16:05:18 2000
+++ ../../nvi-1.79/common/options.c	Mon May  8 16:20:26 2000
@@ -129,4 +129,8 @@
 /* O_FLASH	    HPUX */
 	{"flash",	NULL,		OPT_1BOOL,	0},
+#ifdef GTAGS
+/* O_GTAGSMODE      FreeBSD2.2 */
+	{"gtagsmode",	NULL,		OPT_0BOOL,	0},
+#endif
 /* O_HARDTABS	    4BSD */
 	{"hardtabs",	NULL,		OPT_NUM,	0},
@@ -313,4 +317,7 @@
 #ifdef MULTIBYTE
 	{"fe",		O_FILEENCODING},	/* MULTIBYTE */
+#endif
+#ifdef GTAGS
+	{"gt",		O_GTAGSMODE},		/*    GTAGS */
 #endif
 	{"ht",		O_HARDTABS},		/*     4BSD */
diff -NrU2 ../docs/USD.doc/vi.man/vi.1 ../../nvi-1.79/docs/USD.doc/vi.man/vi.1
--- ../docs/USD.doc/vi.man/vi.1	Fri Oct 11 10:34:05 1996
+++ ../../nvi-1.79/docs/USD.doc/vi.man/vi.1	Mon May  8 16:06:15 2000
@@ -18,5 +18,5 @@
 .B ex
 [\c
-.B -eFRrSsv\c
+.B -eFGRrSsv\c
 ] [\c
 .BI -c " cmd"\c
@@ -29,5 +29,5 @@
 .B vi
 [\c
-.B -eFlRrSv\c
+.B -eFGlRrSv\c
 ] [\c
 .BI -c " cmd"\c
@@ -40,5 +40,5 @@
 .B view
 [\c
-.B -eFRrSv\c
+.B -eFGRrSv\c
 ] [\c
 .BI -c " cmd"\c
@@ -122,4 +122,7 @@
 Start editing with the lisp and showmatch options set.
 .TP
+.B \-G
+Start editing in gtags mode, as if the gtagsmode option was set.
+.TP
 .B \-R
 Start editing in read-only mode, as if the command name was
@@ -430,4 +433,6 @@
 .B "<control-]>"
 Push a tag reference onto the tag stack.
+In gtagsmode, if at the first column of line,
+locate function references otherwise function definitions.
 .TP
 .B "<control-^>"
@@ -941,4 +946,7 @@
 Rewind the argument list.
 .TP
+.B "rta[g][!] tagstring"
+Edit the file refering the specified tag. (Only in gtagsmode)
+.TP
 .B "se[t] [option[=[value]] ...] [nooption ...] [option? ...] [all]"
 Display or set editor options.
@@ -1110,4 +1118,7 @@
 .B "flash [on]"
 Flash the screen instead of beeping the keyboard on error.
+.TP
+.B "gtagsmode, gt [off]"
+Use GTAGS and GRTAGS instead of tags.
 .TP
 .B "hardtabs, ht [8]"
diff -NrU2 ../ex/ex.h ../../nvi-1.79/ex/ex.h
--- ../ex/ex.h	Mon May  8 16:05:18 2000
+++ ../../nvi-1.79/ex/ex.h	Mon May  8 16:06:15 2000
@@ -165,4 +165,7 @@
 #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 -NrU2 ../ex/ex_cmd.c ../../nvi-1.79/ex/ex_cmd.c
--- ../ex/ex_cmd.c	Wed Oct 23 22:31:01 1996
+++ ../../nvi-1.79/ex/ex_cmd.c	Mon May  8 16:06:15 2000
@@ -303,4 +303,11 @@
 	    "rew[ind][!]",
 	    "re-edit all the files in the file argument list"},
+#ifdef GTAGS
+/* C_RTAG */
+	{"rtag",	ex_rtag_push,	E_NEWSCREEN,
+	    "!w1o",
+	    "rta[g][!] [string]",
+	    "edit the file containing the tag"},
+#endif
 /*
  * !!!
diff -NrU2 ../ex/ex_tag.c ../../nvi-1.79/ex/ex_tag.c
--- ../ex/ex_tag.c	Mon Sep 16 05:02:43 1996
+++ ../../nvi-1.79/ex/ex_tag.c	Mon May  8 16:06:15 2000
@@ -47,4 +47,8 @@
 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 *));
@@ -90,4 +94,23 @@
 }
 
+#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 -- ^]
@@ -139,4 +162,10 @@
 
 	/* 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);
@@ -970,4 +999,127 @@
 }
 
+#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 = buf;
+
+	for (*tag = p; *p && !isspace(*p); p++)		/* tag name */
+		;
+	if (*p == 0)
+		goto err;
+	*p++ = 0;
+	for (; *p && isspace(*p); p++)			/* (skip blanks) */
+		;
+	if (*p == 0)
+		goto err;
+	*line = p;					/* line no */
+	for (*line = p; *p && !isspace(*p); p++)
+		;
+	if (*p == 0)
+		goto err;
+	*p++ = 0;
+	for (; *p && isspace(*p); p++)			/* (skip blanks) */
+		;
+	if (*p == 0)
+		goto err;
+	*file = p;					/* file name */
+	for (*file = p; *p && !isspace(*p); p++)
+		;
+	if (*p == 0)
+		goto err;
+	*p = 0;
+
+	/* value check */
+	if (strlen(*tag) && strlen(*line) && strlen(*file) && atoi(*line) > 0)
+		return 1;	/* OK */
+err:
+	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;
+	char *name, *file, *line;
+	char command[BUFSIZ];
+	char buf[BUFSIZ];
+	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.
+	 */
+	snprintf(command, sizeof(command), "global -%s '%s' 2>/dev/null", 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 --
diff -NrU2 ../include/ex_def.h ../../nvi-1.79/include/ex_def.h
--- ../include/ex_def.h	Wed Oct 23 22:53:09 1996
+++ ../../nvi-1.79/include/ex_def.h	Mon May  8 16:06:15 2000
@@ -48,31 +48,32 @@
 #define C_RESIZE 47
 #define C_REWIND 48
-#define C_SUBSTITUTE 49
-#define C_SCRIPT 50
-#define C_SET 51
-#define C_SHELL 52
-#define C_SOURCE 53
-#define C_STOP 54
-#define C_SUSPEND 55
-#define C_T 56
-#define C_TAG 57
-#define C_TAGNEXT 58
-#define C_TAGPOP 59
-#define C_TAGPREV 60
-#define C_TAGTOP 61
-#define C_TCLCMD 62
-#define C_UNDO 63
-#define C_UNABBREVIATE 64
-#define C_UNMAP 65
-#define C_V 66
-#define C_VERSION 67
-#define C_VISUAL_EX 68
-#define C_VISUAL_VI 69
-#define C_VIUSAGE 70
-#define C_WRITE 71
-#define C_WN 72
-#define C_WQ 73
-#define C_XIT 74
-#define C_YANK 75
-#define C_Z 76
-#define C_SUBTILDE 77
+#define C_RTAG 49
+#define C_SUBSTITUTE 50
+#define C_SCRIPT 51
+#define C_SET 52
+#define C_SHELL 53
+#define C_SOURCE 54
+#define C_STOP 55
+#define C_SUSPEND 56
+#define C_T 57
+#define C_TAG 58
+#define C_TAGNEXT 59
+#define C_TAGPOP 60
+#define C_TAGPREV 61
+#define C_TAGTOP 62
+#define C_TCLCMD 63
+#define C_UNDO 64
+#define C_UNABBREVIATE 65
+#define C_UNMAP 66
+#define C_V 67
+#define C_VERSION 68
+#define C_VISUAL_EX 69
+#define C_VISUAL_VI 70
+#define C_VIUSAGE 71
+#define C_WRITE 72
+#define C_WN 73
+#define C_WQ 74
+#define C_XIT 75
+#define C_YANK 76
+#define C_Z 77
+#define C_SUBTILDE 78
diff -NrU2 ../include/ex_extern.h ../../nvi-1.79/include/ex_extern.h
--- ../include/ex_extern.h	Wed Oct 23 22:53:10 1996
+++ ../../nvi-1.79/include/ex_extern.h	Mon May  8 16:06:15 2000
@@ -90,4 +90,5 @@
 void re_error __P((SCR *, int, regex_t *));
 int ex_tag_first __P((SCR *, char *));
+int ex_rtag_push __P((SCR *, EXCMD *));
 int ex_tag_push __P((SCR *, EXCMD *));
 int ex_tag_next __P((SCR *, EXCMD *));
diff -NrU2 ../include/options_def.h ../../nvi-1.79/include/options_def.h
--- ../include/options_def.h	Mon May  8 16:05:18 2000
+++ ../../nvi-1.79/include/options_def.h	Mon May  8 16:24:38 2000
@@ -25,65 +25,66 @@
 #define O_FILEENCODING 24
 #define O_FLASH 25
-#define O_HARDTABS 26
-#define O_ICLOWER 27
-#define O_IGNORECASE 28
-#define O_INPUTENCODING 29
-#define O_KEYTIME 30
-#define O_LEFTRIGHT 31
-#define O_LINES 32
-#define O_LISP 33
-#define O_LIST 34
-#define O_LOCKFILES 35
-#define O_MAGIC 36
-#define O_MATCHTIME 37
-#define O_MESG 38
-#define O_MODELINE 39
-#define O_MSGCAT 40
-#define O_NOPRINT 41
-#define O_NUMBER 42
-#define O_OCTAL 43
-#define O_OPEN 44
-#define O_OPTIMIZE 45
-#define O_PARAGRAPHS 46
-#define O_PATH 47
-#define O_PRINT 48
-#define O_PROMPT 49
-#define O_READONLY 50
-#define O_RECDIR 51
-#define O_REDRAW 52
-#define O_REMAP 53
-#define O_REPORT 54
-#define O_RULER 55
-#define O_SCROLL 56
-#define O_SEARCHINCR 57
-#define O_SECTIONS 58
-#define O_SECURE 59
-#define O_SHELL 60
-#define O_SHELLMETA 61
-#define O_SHIFTWIDTH 62
-#define O_SHOWMATCH 63
-#define O_SHOWMODE 64
-#define O_SIDESCROLL 65
-#define O_SKIPDISPLAY 66
-#define O_SLOWOPEN 67
-#define O_SOURCEANY 68
-#define O_TABSTOP 69
-#define O_TAGLENGTH 70
-#define O_TAGS 71
-#define O_TERM 72
-#define O_TERSE 73
-#define O_TILDEOP 74
-#define O_TIMEOUT 75
-#define O_TTYWERASE 76
-#define O_VERBOSE 77
-#define O_W1200 78
-#define O_W300 79
-#define O_W9600 80
-#define O_WARN 81
-#define O_WINDOW 82
-#define O_WINDOWNAME 83
-#define O_WRAPLEN 84
-#define O_WRAPMARGIN 85
-#define O_WRAPSCAN 86
-#define O_WRITEANY 87
-#define O_OPTIONCOUNT 88
+#define O_GTAGSMODE 26
+#define O_HARDTABS 27
+#define O_ICLOWER 28
+#define O_IGNORECASE 29
+#define O_INPUTENCODING 30
+#define O_KEYTIME 31
+#define O_LEFTRIGHT 32
+#define O_LINES 33
+#define O_LISP 34
+#define O_LIST 35
+#define O_LOCKFILES 36
+#define O_MAGIC 37
+#define O_MATCHTIME 38
+#define O_MESG 39
+#define O_MODELINE 40
+#define O_MSGCAT 41
+#define O_NOPRINT 42
+#define O_NUMBER 43
+#define O_OCTAL 44
+#define O_OPEN 45
+#define O_OPTIMIZE 46
+#define O_PARAGRAPHS 47
+#define O_PATH 48
+#define O_PRINT 49
+#define O_PROMPT 50
+#define O_READONLY 51
+#define O_RECDIR 52
+#define O_REDRAW 53
+#define O_REMAP 54
+#define O_REPORT 55
+#define O_RULER 56
+#define O_SCROLL 57
+#define O_SEARCHINCR 58
+#define O_SECTIONS 59
+#define O_SECURE 60
+#define O_SHELL 61
+#define O_SHELLMETA 62
+#define O_SHIFTWIDTH 63
+#define O_SHOWMATCH 64
+#define O_SHOWMODE 65
+#define O_SIDESCROLL 66
+#define O_SKIPDISPLAY 67
+#define O_SLOWOPEN 68
+#define O_SOURCEANY 69
+#define O_TABSTOP 70
+#define O_TAGLENGTH 71
+#define O_TAGS 72
+#define O_TERM 73
+#define O_TERSE 74
+#define O_TILDEOP 75
+#define O_TIMEOUT 76
+#define O_TTYWERASE 77
+#define O_VERBOSE 78
+#define O_W1200 79
+#define O_W300 80
+#define O_W9600 81
+#define O_WARN 82
+#define O_WINDOW 83
+#define O_WINDOWNAME 84
+#define O_WRAPLEN 85
+#define O_WRAPMARGIN 86
+#define O_WRAPSCAN 87
+#define O_WRITEANY 88
+#define O_OPTIONCOUNT 89
diff -NrU2 ../vi/v_ex.c ../../nvi-1.79/vi/v_ex.c
--- ../vi/v_ex.c	Mon May  8 16:05:18 2000
+++ ../../nvi-1.79/vi/v_ex.c	Mon May  8 16:06:15 2000
@@ -227,4 +227,9 @@
 	EXCMD cmd;
 
+#ifdef GTAGS
+	if (O_ISSET(sp, O_GTAGSMODE) && vp->m_start.cno == 0)
+		ex_cinit(&cmd, C_RTAG, 0, OOBLNO, 0, 0, ap);
+	else
+#endif
 	ex_cinit(&cmd, C_TAG, 0, OOBLNO, 0, 0, ap);
 	ex_cadd(&cmd, &a, VIP(sp)->keyw, strlen(VIP(sp)->keyw));
