From owner-freebsd-hackers Sat May 4 17:55:46 1996 Return-Path: owner-hackers Received: (from root@localhost) by freefall.freebsd.org (8.7.3/8.7.3) id RAA22843 for hackers-outgoing; Sat, 4 May 1996 17:55:46 -0700 (PDT) Received: from mail.ca2.so-net.or.jp (mail.ca2.so-net.or.jp [202.238.95.34]) by freefall.freebsd.org (8.7.3/8.7.3) with ESMTP id RAA22837 for ; Sat, 4 May 1996 17:55:42 -0700 (PDT) Received: from chiota (ppp6812.sng2.ap.so-net.or.jp [202.238.104.18]) by mail.ca2.so-net.or.jp (8.7.5/3.4W396011914) with SMTP id JAA22670; Sun, 5 May 1996 09:55:33 +0900 Received: from localhost (localhost [127.0.0.1]) by chiota (8.6.12/) with SMTP id JAA00258; Sun, 5 May 1996 09:54:31 +0900 Message-Id: <199605050054.JAA00258@chiota> To: hackers@freebsd.org Cc: shigio@ca2.so-net.or.jp Subject: Private patch for VI using GLOBAL [FreeBSD 2.1R] Date: Sun, 05 May 1996 09:54:29 +0900 From: Shigio Yamaguchi Sender: owner-hackers@freebsd.org X-Loop: FreeBSD.org Precedence: bulk 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 | 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 command is available. X X In gtagsmode, if you are on the first column of line, it is identical to X ":rtag [RETURN]", otherwise ":tag [RETURN]". X X o Other tag commands are available too. X X 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, select current line as a tag. X .It Sy "[count] " 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 "" X! Push a tag reference onto the tag stack. X .It Sy "" X Switch to the most recently edited file. X .It Sy "[count] " X--- 405,412 ---- X .Nm \&ex X commands or cancel partial commands. X .It Sy "" 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 "" X Switch to the most recently edited file. X .It Sy "[count] " 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+ * 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, >agselect, 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), >agselect, 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