Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 05 May 1996 09:54:29 +0900
From:      Shigio Yamaguchi <shigio@ca2.so-net.or.jp>
To:        hackers@freebsd.org
Cc:        shigio@ca2.so-net.or.jp
Subject:   Private patch for VI using GLOBAL [FreeBSD 2.1R]
Message-ID:  <199605050054.JAA00258@chiota>

next in thread | raw e-mail | index | archive | help
Hello this is Yamaguchi.

This is a patch for vi(1) to use global(1) within the editor.

Global(1) is a command which find the locations of specified function
in C source files. With this patch, vi's tag function is extended to
use global. You need global-1.0 or 1.1.

Thank you.
------------------ C U T     H E R E ------------------------
# This is a shell archive.  Save it in a file, remove anything before
# this line, and then unpack it by entering "sh file".  Note, it may
# create directories; files and directories will be owned by you and
# have default permissions.
#
# This archive contains:
#
#	README
#	vi.diff
#
echo x - README
sed 's/^X//' >README << 'END-of-README'
X
XThis is a patch for vi(1) to use global(1) within the editor.
X
X	!!!CAUTION!!!		|
X   This is a private patch,	|
X      not a public one.		|
X				|
X  ######                        |  ###
X     #       ####               | #   #
X      #       #   ####          | #      #    ##  ###     # #
X       #     #     #            | #      #   #  # # #  version 1.0 or 1.1
X        #   #     #   u s i n g | #  ### #   #  # ###   # # #
X         # #     #              | #   #  #   #  # #  # #### #
X          #    ####             |  ###   #### ##  ### ## ## ###
X				|
X                  For FreeBSD2.1 or 2.0.5
X				|
X				| Copyright  Shigio Yamaguchi
X				|		<shigio@ca2.so-net.or.jp>
X				|
X				|			5/3/96
X
XGlobal(1) is a command which find the locations of specified function
Xin C source files. With this patch, vi's tag function is extended to
Xuse global.
X
X1. Features
X
X   o Tag function of patched vi can locate not only function definitions
X     but also function references.
X   o Patched vi allow duplicate tag entries. When selection needed,
X     vi go into 'GTAGS SELECT MODE' which display tags list and you
X     can select a tag from it.
X   o Patched vi can understand perl's regular expression as a tag name
X     for search.
X   o Patched vi is upper compatible with original vi. Above functions
X     are available only in 'gtags mode'.
X
X   I think these features are useful for a large project containing many
X   subdirectories, many '#ifdef' and many main() functions like MH.
X
X2. Installation
X
X   Patched vi require global command.
X
X   (1) Install global version1.0 or 1.1 if not yet.
X
X	Please read the README file of global package.
X	I recommend to use 1.1 that is bugfix version.
X
X   (2) Patch vi
X
X	% cd /usr/src/usr.bin/vi
X	% patch -p < vi.diff
X	% make
X	# make install
X
X3. Preparation
X
X   First of all, you must execute gtags(1) at the root of source tree.
X   Gtags traverse subdirectories, find C source files and make two
X   database at the root of source tree.
X   (gtags(1) is included in global package)
X
X	GTAGS	- database for function definition
X	GRTAGS	- database for function reference
X
X
X   To use global from vi, you need to get into 'gtags mode'.
X   There are some ways to do it.
X
X   (a) Start vi with -G option
X
X   	% vi -G file.c
X
X   (b) Start vi and execute "set gtagsmode"
X
X   	% vi file.c
X   	~
X   	~
X   	~
X   	:set gtagsmode
X
X   (c) Previously write the set command to .exrc file and start vi
X
X	$HOME/.exrc
X   	+----------------------------
X   	|set gtagsmode
X
X
X4. Basic usage
X
X   (You must start vi under the source tree described above.)
X
X   o To go to func1, you can say
X
X	:tag func1
X
X     It seemes same with original vi, but patched vi use GTAGS
X     instead of tags.
X
X   o To go to the referenced point of func1, add prefix 'r'
X
X   	:rtag func1
X
X     Patched vi use GRTAGS.
X
X   o If selection needed, vi goes into 'GTAGS SELECT MODE' like this.
X
X	+-------------------------------------------------------------
X	|main             347 i386/isa/ultra14f.c main()
X	|main             128 kern/init_main.c   main(framep)
X	|main             104 netiso/clnp_debug.c main()
X	|main             164 netiso/xebec/main.c main(argc, argv)
X	|~
X	|~
X	|~
X	|~
X	|~
X	|[GTAGS SELECT MODE] 4 lines
X	+-------------------------------------------------------------
X
X     You can select a tag line by any vi command and press [RETURN],
X     and you can go to the tag's point. In ex mode, type "select"
X     instead of [RETURN].
X
X   o <control-]> command is available.
X
X     In gtagsmode, if you are on the first column of line, it is identical to
X     ":rtag <current token>[RETURN]", otherwise ":tag <current token>[RETURN]".
X
X   o Other tag commands are available too.
X
X     <control-T>
X     ":tagpop"
X     ":tagtop"
X     ":display tags"
X
X     Please read online manual.
X
X5. Applied usage
X
X   o In large project which include many main() function like MH,
X     you can start vi like this.
X
X     % vi -G -t main
X
X     Pached vi goes into 'GTAGS SELECT MODE' directly and shows you
X     the list of MH commands.
X
X   o When you want to check functions the name of which start with
X     "set" or "get",
X
X     % vi -G -t '^[sg]et'
X
X     Of cause, following command is available too.
X
X     :tag ^[sg]et
X
X   o If your source files are on a read only device like CDROM, please do
X     the followings.
X
X     % mkdir /var/dbpath		<- directory for tag file
X     % cd /cdrom/src			<- the root of source tree
X     % gtags /var/dbpath		<- make tag files in /var/dbpath
X     % setenv GTAGSROOT `pwd`
X     % setenv GTAGSDBPATH /var/dbpath
X     % vi -G -t main
X
X   o Global doesn't treat the references to the function that is not defined
X     in the source tree. So generally system's library functions and system
X     calls are ignored. If you want to treat them, first buy a disk and
X     second do the followings.
X
X     % cd /usr/src
X     % gtags
X
X     If you examine vi's source,
X
X     % cd /usr/src/usr.bin/vi
X     % vi -G -t main
X
X     You can start from vi and trip the whole unix world as if using
X     hyper-text. It requires about 80MB disk though...
X
XThank you for your reading of my poor english.
END-of-README
echo x - vi.diff
sed 's/^X//' >vi.diff << 'END-of-vi.diff'
Xdiff -c -r /usr/src/usr.bin/vi/USD.doc/vi.man/vi.1 ./USD.doc/vi.man/vi.1
X*** /usr/src/usr.bin/vi/USD.doc/vi.man/vi.1	Mon Apr 22 16:11:45 1996
X--- ./USD.doc/vi.man/vi.1	Sat Apr 27 18:24:04 1996
X***************
X*** 39,59 ****
X  .Nd text editors
X  .Sh SYNOPSIS
X  .Nm \&ex
X! .Op Fl eFRrsv
X  .Op Fl c Ar cmd
X  .Op Fl t Ar tag
X  .Op Fl w Ar size
X  .\".Op Fl X Ar \&aw
X  .Op Ar "file ..."
X  .Nm \&vi
X! .Op Fl eFRrv
X  .Op Fl c Ar cmd
X  .Op Fl t Ar tag
X  .Op Fl w Ar size
X  .\".Op Fl X Ar \&aw
X  .Op Ar "file ..."
X  .Nm view
X! .Op Fl eFRrv
X  .Op Fl c Ar cmd
X  .Op Fl t Ar tag
X  .Op Fl w Ar size
X--- 39,59 ----
X  .Nd text editors
X  .Sh SYNOPSIS
X  .Nm \&ex
X! .Op Fl eFGRrsv
X  .Op Fl c Ar cmd
X  .Op Fl t Ar tag
X  .Op Fl w Ar size
X  .\".Op Fl X Ar \&aw
X  .Op Ar "file ..."
X  .Nm \&vi
X! .Op Fl eFGRrv
X  .Op Fl c Ar cmd
X  .Op Fl t Ar tag
X  .Op Fl w Ar size
X  .\".Op Fl X Ar \&aw
X  .Op Ar "file ..."
X  .Nm view
X! .Op Fl eFGRrv
X  .Op Fl c Ar cmd
X  .Op Fl t Ar tag
X  .Op Fl w Ar size
X***************
X*** 124,129 ****
X--- 124,131 ----
X  Don't copy the entire file when first starting to edit.
X  (The default is to make a copy in case someone else modifies
X  the file during your edit session.)
X+ .It Fl G
X+ Start editing in gtags mode, as if the gtagsmode option was set.
X  .It Fl R
X  Start editing in read-only mode, as if the command name was
X  .Nm view ,
X***************
X*** 377,382 ****
X--- 379,385 ----
X  Move the cursor down
X  .Li count
X  lines to the first nonblank character of that line.
X+ In gtags select mode, <control-M> select current line as a tag.
X  .It Sy "[count] <control-P>"
X  .It Sy "[count] k"
X  Move the cursor up
X***************
X*** 402,408 ****
X  .Nm \&ex
X  commands or cancel partial commands.
X  .It Sy "<control-]>"
X! Push a tag reference onto the tag stack.
X  .It Sy "<control-^>"
X  Switch to the most recently edited file.
X  .It Sy "[count] <space>"
X--- 405,412 ----
X  .Nm \&ex
X  commands or cancel partial commands.
X  .It Sy "<control-]>"
X! Push a tag reference onto the tag stack. In gtagsmode, if at the first column
X! of line, locate function references otherwise function definitions.
X  .It Sy "<control-^>"
X  Switch to the most recently edited file.
X  .It Sy "[count] <space>"
X***************
X*** 780,785 ****
X--- 784,793 ----
X  Grow or shrink the current screen.
X  .It Sy "rew[ind][!]"
X  Rewind the argument list.
X+ .It Sy "rta[g][!] tagstring"
X+ Edit the file refering the specified tag. (Only in gtagsmode)
X+ .It Sy "se[lect]"
X+ Select a tag from gtags list.
X  .It Sy "se[t] [option[=[value]] ...] [nooption ...] [option? ...] [all]"
X  Display or set editor options.
X  .It Sy "sh[ell]"
X***************
X*** 901,906 ****
X--- 909,916 ----
X  style) expressions.
X  .It Sy "flash [on]"
X  Flash the screen instead of beeping the keyboard on error.
X+ .It Sy "gtagsmode, gt [off]"
X+ Use GTAGS and GRTAGS instead of tags.
X  .It Sy "hardtabs, ht [8]"
X  Set the spacing between hardware tab settings.
X  .It Sy "ignorecase, ic [off]"
Xdiff -c -r /usr/src/usr.bin/vi/common/Makefile ./common/Makefile
X*** /usr/src/usr.bin/vi/common/Makefile	Mon Apr 22 16:11:44 1996
X--- ./common/Makefile	Wed May  1 14:56:48 1996
X***************
X*** 9,15 ****
X  LINKS+= ${BINDIR}/${VI} ${BINDIR}/view
X  MAN1=	${.CURDIR}/../USD.doc/vi.man/vi.1
X  
X! CFLAGS+=-I. -I${.CURDIR}
X  DPADD+= ${LIBCURSES} ${LIBTERMCAP} ${LIBUTIL}
X  LDADD+=	-lcurses -ltermcap -lutil
X  
X--- 9,15 ----
X  LINKS+= ${BINDIR}/${VI} ${BINDIR}/view
X  MAN1=	${.CURDIR}/../USD.doc/vi.man/vi.1
X  
X! CFLAGS+=-I. -I${.CURDIR} -DGTAGS
X  DPADD+= ${LIBCURSES} ${LIBTERMCAP} ${LIBUTIL}
X  LDADD+=	-lcurses -ltermcap -lutil
X  
Xdiff -c -r /usr/src/usr.bin/vi/common/exf.c ./common/exf.c
X*** /usr/src/usr.bin/vi/common/exf.c	Mon Apr 22 16:11:43 1996
X--- ./common/exf.c	Tue Apr 30 10:44:10 1996
X***************
X*** 156,162 ****
X--- 156,169 ----
X  	 * Required FRP initialization; the only flag we keep is the
X  	 * cursor information.
X  	 */
X+ #ifdef GTAGS
X+ 	/*
X+ 	 * we must keep gtagstmp information too.
X+ 	 */
X+ 	F_CLR(frp, ~(FR_CURSORSET|FR_GTAGSTMP));
X+ #else
X  	F_CLR(frp, ~FR_CURSORSET);
X+ #endif
X  
X  	/*
X  	 * Required EXF initialization:
X***************
X*** 290,295 ****
X--- 297,305 ----
X  	 * an error.
X  	 */
X  	if (rcv_name == NULL)
X+ #ifdef GTAGS
X+ 	if (!F_ISSET(frp, FR_GTAGSTMP))
X+ #endif
X  		switch (file_lock(oname,
X  		    &ep->fcntl_fd, ep->db->fd(ep->db), 0)) {
X  		case LOCK_FAILED:
Xdiff -c -r /usr/src/usr.bin/vi/common/gs.h ./common/gs.h
X*** /usr/src/usr.bin/vi/common/gs.h	Mon Apr 22 16:11:43 1996
X--- ./common/gs.h	Wed May  1 15:00:49 1996
X***************
X*** 48,53 ****
X--- 48,56 ----
X  
X  	sigset_t blockset;		/* Signal mask. */
X  
X+ #ifdef GTAGS
X+ 	char	*gtagstmp;		/* gtagstmp made by -t option */
X+ #endif
X  #ifdef DEBUG
X  	FILE	*tracefp;		/* Trace file pointer. */
X  #endif
Xdiff -c -r /usr/src/usr.bin/vi/common/main.c ./common/main.c
X*** /usr/src/usr.bin/vi/common/main.c	Mon Apr 22 16:11:43 1996
X--- ./common/main.c	Tue Apr 30 21:45:08 1996
X***************
X*** 98,103 ****
X--- 98,106 ----
X  	SCR *sp;
X  	u_int flags, saved_vi_mode;
X  	int ch, eval, flagchk, readonly, silent, snapshot;
X+ #ifdef GTAGS
X+ 	int gtags = 0;
X+ #endif
X  	char *excmdarg, *myname, *p, *tag_f, *trace_f, *wsizearg;
X  	char path[MAXPATHLEN];
X  
X***************
X*** 134,140 ****
X--- 137,147 ----
X  	excmdarg = tag_f = trace_f = wsizearg = NULL;
X  	silent = 0;
X  	snapshot = 1;
X+ #ifdef GTAGS
X+ 	while ((ch = getopt(argc, argv, "c:eFGRrsT:t:vw:X:")) != EOF)
X+ #else
X  	while ((ch = getopt(argc, argv, "c:eFRrsT:t:vw:X:")) != EOF)
X+ #endif
X  		switch (ch) {
X  		case 'c':		/* Run the command. */
X  			excmdarg = optarg;
X***************
X*** 146,151 ****
X--- 153,163 ----
X  		case 'F':		/* No snapshot. */
X  			snapshot = 0;
X  			break;
X+ #ifdef GTAGS
X+ 		case 'G':		/* gtags mode. */
X+ 			gtags = 1;
X+ 			break;
X+ #endif
X  		case 'R':		/* Readonly. */
X  			readonly = 1;
X  			break;
X***************
X*** 245,250 ****
X--- 257,266 ----
X  		goto err;
X  	if (readonly)			/* Global read-only bit. */
X  		O_SET(sp, O_READONLY);
X+ #ifdef GTAGS
X+ 	if (gtags)			/* Global gtags bit. */
X+ 		O_SET(sp, O_GTAGSMODE);
X+ #endif
X  	if (silent) {			/* Ex batch mode. */
X  		O_CLR(sp, O_AUTOPRINT);
X  		O_CLR(sp, O_PROMPT);
X***************
X*** 515,520 ****
X--- 531,539 ----
X  	LIST_INIT(&gp->cutq);
X  	LIST_INIT(&gp->seqq);
X  
X+ #ifdef GTAGS
X+ 	gp->gtagstmp = NULL;
X+ #endif
X  	/* Set a flag if we're reading from the tty. */
X  	if (isatty(STDIN_FILENO))
X  		F_SET(gp, G_STDIN_TTY);
X***************
X*** 554,559 ****
X--- 573,584 ----
X  	SCR *sp;
X  	char *tty;
X  
X+ #ifdef GTAGS
X+ 	if (gp->gtagstmp) {
X+ 		if (!strncmp(gp->gtagstmp, _PATH_GTAGSTMP, strlen(_PATH_GTAGSTMP)))
X+ 			(void)unlink(gp->gtagstmp);
X+ 	}
X+ #endif
X  	/* Default buffer storage. */
X  	(void)text_lfree(&gp->dcb_store.textq);
X  
Xdiff -c -r /usr/src/usr.bin/vi/common/msg.c ./common/msg.c
X*** /usr/src/usr.bin/vi/common/msg.c	Mon Apr 22 16:11:44 1996
X--- ./common/msg.c	Sat May  4 21:09:48 1996
X***************
X*** 338,343 ****
X--- 338,352 ----
X  #else
X  	pid = "";
X  #endif
X+ #ifdef GTAGS
X+ 	if (F_ISSET(sp->frp, FR_GTAGSTMP)) {
X+ 		if (file_lline(sp, ep, &last)) {
X+ 			return (1);
X+ 		}
X+ 		msgq(sp, M_INFO, "[GTAGS SELECT MODE] %d lines", last);
X+ 		return (0);
X+ 	}
X+ #endif
X  	/*
X  	 * See nvi/exf.c:file_init() for a description of how and
X  	 * when the read-only bit is set.
Xdiff -c -r /usr/src/usr.bin/vi/common/options.c ./common/options.c
X*** /usr/src/usr.bin/vi/common/options.c	Mon Apr 22 16:11:44 1996
X--- ./common/options.c	Sat Apr 27 18:24:01 1996
X***************
X*** 103,108 ****
X--- 103,112 ----
X  	{"extended",	NULL,		OPT_0BOOL,	0},
X  /* O_FLASH	    HPUX */
X  	{"flash",	NULL,		OPT_1BOOL,	0},
X+ #ifdef GTAGS
X+ /* O_GTAGSMODE	    SPECIAL */
X+ 	{"gtagsmode",	NULL,		OPT_0BOOL,	0},
X+ #endif
X  /* O_HARDTABS	    4BSD */
X  	{"hardtabs",	NULL,		OPT_NUM,	0},
X  /* O_IGNORECASE	    4BSD */
X***************
X*** 228,233 ****
X--- 232,240 ----
X  	{"eb",		O_ERRORBELLS},		/*     4BSD */
X  	{"ed",		O_EDCOMPATIBLE},	/*     4BSD */
X  	{"ex",		O_EXRC},		/* System V (undocumented) */
X+ #ifdef GTAGS
X+ 	{"gt",		O_GTAGSMODE},		/* Special  */
X+ #endif
X  	{"ht",		O_HARDTABS},		/*     4BSD */
X  	{"ic",		O_IGNORECASE},		/*     4BSD */
X  	{"li",		O_LINES},		/*   4.4BSD */
Xdiff -c -r /usr/src/usr.bin/vi/common/pathnames.h ./common/pathnames.h
X*** /usr/src/usr.bin/vi/common/pathnames.h	Mon Apr 22 16:11:44 1996
X--- ./common/pathnames.h	Sat Apr 27 18:24:01 1996
X***************
X*** 43,45 ****
X--- 43,48 ----
X  #define	_PATH_TAGS	"tags"
X  #define	_PATH_TMP	"/tmp"
X  #define	_PATH_TTY	"/dev/tty"
X+ #ifdef GTAGS
X+ #define	_PATH_GTAGSTMP	"/var/tmp/gtags"
X+ #endif
Xdiff -c -r /usr/src/usr.bin/vi/common/screen.h ./common/screen.h
X*** /usr/src/usr.bin/vi/common/screen.h	Mon Apr 22 16:11:44 1996
X--- ./common/screen.h	Sat Apr 27 18:24:02 1996
X***************
X*** 87,92 ****
X--- 87,95 ----
X  #define	FR_TMPEXIT	0x100		/* Modified temporary file, no exit. */
X  #define	FR_TMPFILE	0x200		/* If file has no name. */
X  #define	FR_UNLOCKED	0x400		/* File couldn't be locked. */
X+ #ifdef GTAGS
X+ #define	FR_GTAGSTMP	0x800		/* File is gtags temporary file. */
X+ #endif
X  	u_int16_t flags;
X  };
X  
Xdiff -c -r /usr/src/usr.bin/vi/ex/ex_tag.c ./ex/ex_tag.c
X*** /usr/src/usr.bin/vi/ex/ex_tag.c	Mon Apr 22 16:11:49 1996
X--- ./ex/ex_tag.c	Fri May  3 13:34:26 1996
X***************
X*** 64,69 ****
X--- 64,72 ----
X  #include "vi.h"
X  #include "excmd.h"
X  #include "tag.h"
X+ #ifdef GTAGS
X+ #include "pathnames.h"
X+ #endif
X  
X  static char	*binary_search __P((char *, char *, char *));
X  static int	 compare __P((char *, char *, char *));
X***************
X*** 71,76 ****
X--- 74,280 ----
X  static int	 search __P((SCR *, char *, char *, char **));
X  static int	 tag_get __P((SCR *, char *, char **, char **, char **));
X  
X+ #ifdef DEBUG
X+ void
X+ trace(fp)
X+ 	FILE *fp;
X+ {
X+ 	SCR *sp;
X+ 	TAG *tp;
X+ 	FREF *frp;
X+ 	int scr, fref, tag;
X+ 
X+ 	fprintf(fp, "------------------------------------\n");
X+ 	scr = 0;
X+ 	for (sp = __global_list->dq.cqh_first; sp != (void *)&__global_list->dq; sp = sp->q.cqe_next) {
X+ 		fprintf(fp, "screen %d {\n", ++scr);
X+ 		fref = 0;
X+ 		for (frp = sp->frefq.cqh_first;
X+ 			frp != (FREF *)&sp->frefq; frp = frp->q.cqe_next) {
X+ 			fprintf(fp, "    FREF %d ", ++fref);
X+ 			if (F_ISSET(frp, FR_GTAGSTMP))
X+ 				fprintf(fp, "<%s>\n", frp->name);
X+ 			else
X+ 				fprintf(fp, "%s\n", frp->name);
X+ 		}
X+ 		tag = 0;
X+ 		if (!EXP(sp))
X+ 			continue;
X+ 		fprintf(fp, "    ................................\n");
X+ 		for (tp = EXP(sp)->tagq.tqh_first; tp != NULL; tp = tp->q.tqe_next) {
X+ 			fprintf(fp, "    TAG %d ", ++tag);
X+ 			if (F_ISSET(tp->frp, FR_GTAGSTMP))
X+ 				fprintf(fp, "<%s>\n", tp->frp->name);
X+ 			else
X+ 				fprintf(fp, "%s\n", tp->frp->name);
X+ 		}
X+ 		fprintf(fp, "}\n");
X+ 	}
X+ 	fprintf(fp, "------------------------------------\n");
X+ }
X+ #endif
X+ #ifdef GTAGS
X+ /*
X+  * getentry --
X+  *	get tag information from current line.
X+  *
X+  * gtags temporary file format.
X+  * <tag>   <lineno>  <file>         <image>
X+  *
X+  * sample.
X+  * +------------------------------------------------
X+  * |main     30      main.c         main(argc, argv)
X+  * |func     21      subr.c         func(arg)
X+  */
X+ static int
X+ getentry(buf, tag, file, line)
X+ 	char *buf, *tag, *file, *line;
X+ {
X+ 	char *p;
X+ 
X+ 	p = tag;
X+ 	while (*buf && !isspace(*buf))		/* tag name */
X+ 		*p++ = *buf++;
X+ 	*p = 0;
X+ 	while (*buf && isspace(*buf))		/* skip blanks */
X+ 		buf++;
X+ 	p = line;
X+ 	while (*buf && !isspace(*buf))		/* line no */
X+ 		*p++ = *buf++;
X+ 	*p = 0;
X+ 	while (*buf && isspace(*buf))		/* skip blanks */
X+ 		buf++;
X+ 	p = file;
X+ 	while (*buf && !isspace(*buf))		/* file name */
X+ 		*p++ = *buf++;
X+ 	*p = 0;
X+ 
X+ 	/* value check */
X+ 	if (strlen(tag) && strlen(line) && strlen(file) && atoi(line) > 0)
X+ 		return 1;	/* OK */
X+ 	return 0;		/* ERROR */
X+ }
X+ 
X+ /*
X+  * gtag_get --
X+  *	Get a gtag from the GTAGS files.
X+  */
X+ static int
X+ gtag_get(sp, ref, gtagselect, tag, tagp, filep, searchp)
X+ 	SCR *sp;
X+ 	int ref;
X+ 	int *gtagselect;
X+ 	char *tag, **tagp, **filep, **searchp;
X+ {
X+ 	static char name[80], file[200], line[10], gtagstmp[80];
X+ 	char command[200];
X+ 	char buf[BUFSIZ+1];
X+ 	FILE *fp;
X+ 
X+ 	sprintf(gtagstmp, "%s.XXXXXXXX", _PATH_GTAGSTMP);
X+ 	if (mktemp(gtagstmp) == 0) {
X+ 		msgq(sp, M_ERR, "cannot generate temporary file name");
X+ 		return (1);
X+ 	}
X+ 	sprintf(command, "global -%s %s > %s; chmod 600 %s",
X+ 			ref ? "rx" : "x", tag, gtagstmp, gtagstmp);
X+ 	if (system(command)) {
X+ 		msgq(sp, M_ERR, "cannot exec global");
X+ 		goto err;
X+ 	}
X+ 	if (!(fp = fopen(gtagstmp, "r"))) {
X+ 		msgq(sp, M_ERR, "tag file cannot open.");
X+ 		goto err;
X+ 	}
X+ 	if (!(fgets(buf, BUFSIZ, fp))) {
X+ 		msgq(sp, M_ERR, "%s: tag not found", tag);
X+ 		fclose(fp);
X+ 		goto err;
X+ 	}
X+ 
X+ 	if (getentry(buf, name, file, line) == 0) {
X+ 		msgq(sp, M_ERR, "%s: illegal tag entry", tag);
X+ 		fclose(fp);
X+ 		goto err;
X+ 	}
X+ 
X+ 	if (!(fgets(buf, BUFSIZ, fp))) {	/* just one line */
X+ 		fclose(fp);
X+ 		(void)unlink(gtagstmp);
X+ 		*gtagselect  = 0;	/* go to user's file immediately */	
X+ 		*tagp    = name;
X+ 		*filep   = file;
X+ 		*searchp = line;
X+ 		return (0);
X+ 	}
X+ 	fclose(fp);
X+ 	*gtagselect  = 1;		/* go to gtags select mode */
X+ 	*tagp    = name;
X+ 	*filep   = gtagstmp;
X+ 	*searchp = "1";
X+ 	return (0);
X+ err:
X+ 	(void)unlink(gtagstmp);
X+ 	return (1);
X+ }
X+ 
X+ /*
X+  * ex_gtagselect --
X+  *	The tag code can be entered from gtag select mode.
X+  */
X+ int
X+ ex_gtagselect(sp, ep, cmdp)
X+ 	SCR *sp;
X+ 	EXF *ep;
X+ 	EXCMDARG *cmdp;
X+ {
X+ 	if (!F_ISSET(sp->frp, FR_GTAGSTMP)) {
X+ 		msgq(sp, M_ERR, "illegal tag entry");
X+ 		return (1);
X+ 	}
X+ 	cmdp->cmd = &cmds[C_TAG];
X+ 	cmdp->flags |= (E_GTAGSELECT|E_FORCE);
X+ 	return ex_tagpush(sp, ep, cmdp);
X+ }
X+ 
X+ /*
X+  * should_delete --
X+  *	1: should delete, 0: should not delete
X+  */
X+ int
X+ should_delete(gtagstmp)
X+ 	char *gtagstmp;
X+ {
X+ 	SCR *sp;
X+ 	TAG *tp;
X+ 	int tagcnt = 0;
X+ 
X+ 	/* make sure */
X+ 	if (strncmp(gtagstmp, _PATH_GTAGSTMP, strlen(_PATH_GTAGSTMP)))
X+ 		return 0;
X+ 	/* this gtag is generated by -t option. don't delete here */
X+ 	if (__global_list->gtagstmp && !strcmp(gtagstmp, __global_list->gtagstmp))
X+ 		return 0;
X+ 
X+ 	for (sp = __global_list->dq.cqh_first; sp != (void *)&__global_list->dq; sp = sp->q.cqe_next) {
X+ 		if (!EXP(sp))
X+ 			continue;
X+ 		for (tp = EXP(sp)->tagq.tqh_first; tp != NULL; tp = tp->q.tqe_next) {
X+ 			if (!tp->frp || !F_ISSET(tp->frp, FR_GTAGSTMP))
X+ 				continue;
X+ 			if (!strcmp(tp->frp->name, gtagstmp))
X+ 				++tagcnt;
X+ 		}
X+ 	}
X+ 	if (tagcnt == 1)
X+ 		return 1;
X+ 	if (tagcnt > 1)
X+ 		return 0;
X+ 	/* IMPOSSIBLE */
X+ 	return 0;
X+ }
X+ #endif
X+ 
X  /*
X   * ex_tagfirst --
X   *	The tag code can be entered from main, i.e. "vi -t tag".
X***************
X*** 86,96 ****
X--- 290,309 ----
X  	u_int flags;
X  	int sval;
X  	char *p, *tag, *name, *search;
X+ #ifdef GTAGS
X+ 	int gtagselect = 0;
X+ #endif
X  
X  	/* Taglength may limit the number of characters. */
X  	if ((tl = O_VAL(sp, O_TAGLENGTH)) != 0 && strlen(tagarg) > tl)
X  		tagarg[tl] = '\0';
X  
X+ #ifdef GTAGS
X+ 	if (O_ISSET(sp, O_GTAGSMODE)) {
X+ 		if (gtag_get(sp, 0, &gtagselect, tagarg, &tag, &name, &search))
X+ 			return (1);
X+ 	} else 
X+ #endif
X  	/* Get the tag information. */
X  	if (tag_get(sp, tagarg, &tag, &name, &search))
X  		return (1);
X***************
X*** 106,111 ****
X--- 319,328 ----
X  	 * The historic tags file format (from a long, long time ago...)
X  	 * used a line number, not a search string.  I got complaints, so
X  	 * people are still using the format.
X+ #ifdef GTAGS
X+ 	 * Yes, gtags use the old format. Search string is very flexible
X+ 	 * but is not suitable to treat duplicate entries.
X+ #endif
X  	 */
X  	if (isdigit(search[0])) {
X  		m.lno = atoi(search);
X***************
X*** 132,137 ****
X--- 349,363 ----
X  	frp->lno = m.lno;
X  	frp->cno = m.cno;
X  	F_SET(frp, FR_CURSORSET);
X+ #ifdef GTAGS
X+ 	if (gtagselect) {
X+ 		F_SET(frp, FR_GTAGSTMP);
X+ 		if (!(sp->gp->gtagstmp = strdup(name))) {
X+ 			msgq(sp, M_SYSERR, NULL);
X+ 			return (1);
X+ 		}
X+ 	}
X+ #endif
X  
X  	/* Might as well make this the default tag. */
X  	if ((EXP(sp)->tlast = strdup(tagarg)) == NULL) {
X***************
X*** 142,153 ****
X--- 368,391 ----
X  }
X  
X  /* Free a tag or tagf structure from a queue. */
X+ #ifdef GTAGS
X+ #define	FREETAG(tp) {							\
X+ 	if (F_ISSET(tp->frp, FR_GTAGSTMP))				\
X+ 		if (should_delete(tp->frp->name))			\
X+ 			unlink(tp->frp->name);				\
X+ 	TAILQ_REMOVE(&exp->tagq, (tp), q);				\
X+ 	if ((tp)->search != NULL)					\
X+ 		free((tp)->search);					\
X+ 	FREE((tp), sizeof(TAGF));					\
X+ }
X+ #else
X  #define	FREETAG(tp) {							\
X  	TAILQ_REMOVE(&exp->tagq, (tp), q);				\
X  	if ((tp)->search != NULL)					\
X  		free((tp)->search);					\
X  	FREE((tp), sizeof(TAGF));					\
X  }
X+ #endif
X  #define	FREETAGF(tfp) {							\
X  	TAILQ_REMOVE(&exp->tagfq, (tfp), q);				\
X  	free((tfp)->name);						\
X***************
X*** 182,189 ****
X--- 420,453 ----
X  	int sval;
X  	long tl;
X  	char *name, *p, *search, *tag;
X+ #ifdef GTAGS
X+ 	int gtagselect = 0;
X+ 	char *line;
X+ 	size_t len;
X+ 	char tagbuf[80], namebuf[200], linebuf[10];
X+ #endif
X  
X  	exp = EXP(sp);
X+ #ifdef GTAGS
X+ 	/*
X+ 	 * Enter from gtag select mode.
X+ 	 * get tag information from current line.
X+ 	 */
X+ 	if (F_ISSET(cmdp, E_GTAGSELECT)) {
X+ 		if ((line = file_gline(sp, ep, sp->lno, &len)) == NULL) {
X+ 			GETLINE_ERR(sp, sp->lno);
X+ 			return (1);
X+ 		}
X+ 		if (getentry(line, tagbuf, namebuf, linebuf) == 0) {
X+ 			msgq(sp, M_ERR, "illegal tag entry");
X+ 			return (1);
X+ 		}
X+ 		tag = tagbuf;
X+ 		name = namebuf;
X+ 		search = linebuf;
X+ 		goto getfref;
X+ 	}
X+ #endif
X  	switch (cmdp->argc) {
X  	case 1:
X  		if (exp->tlast != NULL)
X***************
X*** 207,216 ****
X--- 471,493 ----
X  	if ((tl = O_VAL(sp, O_TAGLENGTH)) != 0 && strlen(exp->tlast) > tl)
X  		exp->tlast[tl] = '\0';
X  
X+ #ifdef GTAGS
X+ 	if (O_ISSET(sp, O_GTAGSMODE)) {
X+ 		if (gtag_get(sp, F_ISSET(cmdp->cmd, E_REFERENCE), &gtagselect,
X+ 			exp->tlast, &tag, &name, &search))
X+ 			return (1);
X+ 	} else if (F_ISSET(cmdp->cmd, E_REFERENCE)) {
X+ 		msgq(sp, M_ERR, "Please set gtagsmode");
X+ 		return (1);
X+ 	} else
X+ #endif
X  	/* Get the tag information. */
X  	if (tag_get(sp, exp->tlast, &tag, &name, &search))
X  		return (1);
X  
X+ #ifdef GTAGS
X+ getfref:
X+ #endif
X  	/* Get the (possibly new) FREF structure. */
X  	if ((frp = file_add(sp, name)) == NULL)
X  		goto err;
X***************
X*** 305,310 ****
X--- 582,592 ----
X  		sp->cno = m.cno;
X  		break;
X  	}
X+ #ifdef GTAGS
X+ 	if (gtagselect) {
X+ 		F_SET(frp, FR_GTAGSTMP);
X+ 	}
X+ #endif
X  	return (0);
X  }
X  
X***************
X*** 490,495 ****
X--- 772,782 ----
X  	for (cnt = 1, tp = exp->tagq.tqh_first; tp != NULL;
X  	    ++cnt, tp = tp->q.tqe_next) {
X  		len = strlen(name = tp->frp->name);	/* The original name. */
X+ #ifdef GTAGS
X+ 		if (F_ISSET(tp->frp, FR_GTAGSTMP)) {
X+ 			(void)ex_printf(EXCOOKIE, "%2d [GTAGS]\n", cnt);
X+ 		} else
X+ #endif
X  		if (len > maxlen || len + tp->slen > sp->cols)
X  			if (tp == NULL || tp->search == NULL)
X  				(void)ex_printf(EXCOOKIE,
Xdiff -c -r /usr/src/usr.bin/vi/ex/excmd.c ./ex/excmd.c
X*** /usr/src/usr.bin/vi/ex/excmd.c	Mon Apr 22 16:11:49 1996
X--- ./ex/excmd.c	Sat Apr 27 18:24:08 1996
X***************
X*** 319,324 ****
X--- 319,331 ----
X  	    "!",
X  	    "rew[ind][!]",
X  	    "re-edit all the files in the file argument list"},
X+ #ifdef GTAGS
X+ /* C_RTAG */
X+ 	{"rtag",	ex_tagpush,	E_NOGLOBAL|E_REFERENCE,
X+ 	    "!w1o",
X+ 	    "rta[g][!] [string]",
X+ 	    "edit the file containing the tag"},
X+ #endif
X  /* C_SUBSTITUTE */
X  	{"substitute",	ex_substitute,	E_ADDR2|E_NORC,
X  	    "s",
X***************
X*** 329,334 ****
X--- 336,348 ----
X  	    "!f1o",
X  	    "sc[ript][!] [file]",
X  	    "run a shell in a screen"},
X+ #ifdef GTAGS
X+ /* C_GTAGSELECT */
X+ 	{"select",	ex_gtagselect,	E_NOGLOBAL,
X+ 	    "",
X+ 	    "sel[ect]",
X+ 	    "edit the file containing the tag"},
X+ #endif
X  /* C_SET */
X  	{"set",		ex_set,		E_NOGLOBAL,
X  	    "wN",
Xdiff -c -r /usr/src/usr.bin/vi/ex/excmd.h.stub ./ex/excmd.h.stub
X*** /usr/src/usr.bin/vi/ex/excmd.h.stub	Mon Apr 22 16:11:49 1996
X--- ./ex/excmd.h.stub	Sat Apr 27 18:24:09 1996
X***************
X*** 69,74 ****
X--- 69,79 ----
X  #define	E_NORC		0x0800000	/* Not from a .exrc or EXINIT. */
X  #define	E_ZERO		0x1000000	/* 0 is a legal addr1. */
X  #define	E_ZERODEF	0x2000000	/* 0 is default addr1 of empty files. */
X+ 
X+ #ifdef GTAGS
X+ #define E_REFERENCE	0x4000000	/* locate function references */
X+ #define E_GTAGSELECT	0x8000000	/* current line is gtags entry */
X+ #endif
X  	u_int32_t flags;
X  	char	 *syntax;		/* Syntax script. */
X  	char	*usage;			/* Usage line. */
X***************
X*** 234,239 ****
X--- 239,245 ----
X  EXPROTO(ex_fg);
X  EXPROTO(ex_file);
X  EXPROTO(ex_global);
X+ EXPROTO(ex_gtagselect);
X  EXPROTO(ex_help);
X  EXPROTO(ex_insert);
X  EXPROTO(ex_join);
Xdiff -c -r /usr/src/usr.bin/vi/svi/svi_refresh.c ./svi/svi_refresh.c
X*** /usr/src/usr.bin/vi/svi/svi_refresh.c	Mon Apr 22 16:11:44 1996
X--- ./svi/svi_refresh.c	Sat May  4 21:19:37 1996
X***************
X*** 725,731 ****
X--- 725,736 ----
X  	EXF *ep;
X  {
X  	size_t cols, curlen, endpoint, len, midpoint;
X+ #ifdef GTAGS
X+ 	char *p, buf[30];
X+ 	recno_t last;
X+ #else
X  	char *p, buf[20];
X+ #endif
X  
X  	/* Clear the mode line. */
X  	MOVE(sp, INFOLINE(sp), 0);
X***************
X*** 746,751 ****
X--- 751,765 ----
X  
X  	curlen = 0;
X  	if (sp->q.cqe_next != (void *)&sp->gp->dq) {
X+ #ifdef GTAGS
X+ 		if (F_ISSET(sp->frp, FR_GTAGSTMP)) {
X+ 			if (file_lline(sp, ep, &last)) {
X+ 				return (1);
X+ 			}
X+ 			sprintf(buf, "[GTAGS SELECT MODE] %d lines", last);
X+ 			p = buf;
X+ 		} else {
X+ #endif
X  		for (p = sp->frp->name; *p != '\0'; ++p);
X  		while (--p > sp->frp->name) {
X  			if (*p == '/') {
X***************
X*** 758,764 ****
X  				break;
X  			}
X  		}
X! 
X  		MOVE(sp, INFOLINE(sp), 0);
X  		standout();
X  		for (; *p != '\0'; ++p)
X--- 772,780 ----
X  				break;
X  			}
X  		}
X! #ifdef GTAGS
X! 		}
X! #endif
X  		MOVE(sp, INFOLINE(sp), 0);
X  		standout();
X  		for (; *p != '\0'; ++p)
Xdiff -c -r /usr/src/usr.bin/vi/vi/v_ex.c ./vi/v_ex.c
X*** /usr/src/usr.bin/vi/vi/v_ex.c	Mon Apr 22 16:11:42 1996
X--- ./vi/v_ex.c	Sat Apr 27 18:23:59 1996
X***************
X*** 298,303 ****
X--- 298,308 ----
X  	ARGS *ap[2], a;
X  	EXCMDARG cmd;
X  
X+ #ifdef GTAGS
X+ 	if (O_ISSET(sp, O_GTAGSMODE) && vp->m_start.cno == 0)
X+ 		excmd(&cmd, C_RTAG, 0, OOBLNO, 0, 0, ap, &a, vp->keyword);
X+ 	else
X+ #endif
X  	excmd(&cmd, C_TAG, 0, OOBLNO, 0, 0, ap, &a, vp->keyword);
X  	return (sp->s_ex_cmd(sp, ep, &cmd, &vp->m_final));
X  }
Xdiff -c -r /usr/src/usr.bin/vi/vi/v_scroll.c ./vi/v_scroll.c
X*** /usr/src/usr.bin/vi/vi/v_scroll.c	Mon Apr 22 16:11:42 1996
X--- ./vi/v_scroll.c	Wed May  1 13:52:01 1996
X***************
X*** 255,260 ****
X--- 255,269 ----
X  	EXF *ep;
X  	VICMDARG *vp;
X  {
X+ #ifdef GTAGS
X+ 	EXCMDARG cmd;
X+ 
X+ 	if (F_ISSET(sp->frp, FR_GTAGSTMP)) {
X+ 		memset(&cmd, 0, sizeof(EXCMDARG));
X+ 		cmd.cmd = &cmds[C_GTAGSELECT];
X+ 		return (sp->s_ex_cmd(sp, ep, &cmd, &vp->m_final));
X+ 	}
X+ #endif
X  	/*
X  	 * If it's a script window, exec the line,
X  	 * otherwise it's the same as v_down().
END-of-vi.diff
exit
------------------ C U T     H E R E ------------------------
--
Shigio Yamaguchi	E-Mail: shigio@ca2.so-net.or.jp



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199605050054.JAA00258>