From a987b491ab56daeb05cf3bb9001e629214d58582 Mon Sep 17 00:00:00 2001 From: christos Date: Wed, 29 Oct 2008 17:50:49 +0000 Subject: [PATCH] put back gtagsmode (untested) apb should test. --- dist/nvi/common/main.c | 24 +++++- dist/nvi/common/options.c | 9 ++- dist/nvi/docs/vi.man/vi.1 | 17 ++++- dist/nvi/ex/ex.h | 5 +- dist/nvi/ex/ex_cmd.c | 9 ++- dist/nvi/ex/ex_def.h | 63 +++++++-------- dist/nvi/ex/ex_tag.c | 156 +++++++++++++++++++++++++++++++++++++- dist/nvi/ex/extern.h | 3 +- dist/nvi/vi/v_ex.c | 7 +- 9 files changed, 249 insertions(+), 44 deletions(-) diff --git a/dist/nvi/common/main.c b/dist/nvi/common/main.c index c95b0ac6d648..d41470c5b1b3 100644 --- a/dist/nvi/common/main.c +++ b/dist/nvi/common/main.c @@ -1,4 +1,4 @@ -/* $NetBSD: main.c,v 1.1.1.2 2008/05/18 14:29:47 aymeric Exp $ */ +/* $NetBSD: main.c,v 1.2 2008/10/29 17:50:49 christos Exp $ */ /*- * Copyright (c) 1992, 1993, 1994 @@ -64,6 +64,9 @@ editor(WIN *wp, int argc, char **argv) size_t len; u_int flags; int ch, flagchk, lflag, secure, startup, readonly, rval, silent; +#ifdef GTAGS + int gtags = 0; +#endif char *tag_f, *wsizearg, path[256]; CHAR_T *w; size_t wlen; @@ -104,11 +107,15 @@ editor(WIN *wp, int argc, char **argv) /* Set the file snapshot flag. */ F_SET(gp, G_SNAPSHOT); + while ((ch = getopt(argc, argv, "c:" #ifdef DEBUG - while ((ch = getopt(argc, argv, "c:D:eFlRrSsT:t:vw:")) != EOF) -#else - while ((ch = getopt(argc, argv, "c:eFlRrSst:vw:")) != EOF) + "D:" #endif + "eF" +#ifdef GTAGS + "G" +#endif + "lRrSsT:t:vw:")) != EOF) switch (ch) { case 'c': /* Run the command. */ /* @@ -149,6 +156,11 @@ editor(WIN *wp, int argc, char **argv) case 'l': /* Set lisp, showmatch options. */ lflag = 1; break; +#ifdef GTAGS + case 'G': /* gtags mode. */ + gtags = 1; + break; +#endif case 'R': /* Readonly. */ readonly = 1; break; @@ -242,6 +254,10 @@ editor(WIN *wp, int argc, char **argv) } if (readonly) *oargp++ = O_READONLY; +#ifdef GTAGS + if (gtags) + *oargp++ = O_GTAGSMODE; +#endif if (secure) *oargp++ = O_SECURE; *oargp = -1; /* Options initialization. */ diff --git a/dist/nvi/common/options.c b/dist/nvi/common/options.c index bb641ce6d482..54c521624b1d 100644 --- a/dist/nvi/common/options.c +++ b/dist/nvi/common/options.c @@ -1,4 +1,4 @@ -/* $NetBSD: options.c,v 1.2 2008/10/01 21:20:09 christos Exp $ */ +/* $NetBSD: options.c,v 1.3 2008/10/29 17:50:49 christos Exp $ */ /*- * Copyright (c) 1991, 1993, 1994 @@ -94,6 +94,10 @@ OPTLIST const optlist[] = { {L("fileencoding"),f_encoding, OPT_STR, OPT_WC}, /* O_FLASH HPUX */ {L("flash"), NULL, OPT_1BOOL, 0}, +#ifdef GTAGS +/* O_GTAGSMODE FreeBSD/NetBSD */ + {L("gtagsmode"),NULL, OPT_1BOOL, 0}, +#endif /* O_HARDTABS 4BSD */ {L("hardtabs"), NULL, OPT_NUM, 0}, /* O_ICLOWER 4.4BSD */ @@ -262,6 +266,9 @@ static OABBREV const abbrev[] = { {L("eb"), O_ERRORBELLS}, /* 4BSD */ {L("ed"), O_EDCOMPATIBLE}, /* 4BSD */ {L("ex"), O_EXRC}, /* System V (undocumented) */ +#ifdef GTAGS + {L("gt"), O_GTAGSMODE}, /* FreeBSD, NetBSD */ +#endif {L("fe"), O_FILEENCODING}, {L("ht"), O_HARDTABS}, /* 4BSD */ {L("ic"), O_IGNORECASE}, /* 4BSD */ diff --git a/dist/nvi/docs/vi.man/vi.1 b/dist/nvi/docs/vi.man/vi.1 index a6a29b9d6b1e..69445a209760 100644 --- a/dist/nvi/docs/vi.man/vi.1 +++ b/dist/nvi/docs/vi.man/vi.1 @@ -1,4 +1,4 @@ -.\" $NetBSD: vi.1,v 1.2 2008/10/01 21:20:09 christos Exp $ +.\" $NetBSD: vi.1,v 1.3 2008/10/29 17:50:49 christos Exp $ .\" .\" Copyright (c) 1994 .\" The Regents of the University of California. All rights reserved. @@ -19,7 +19,7 @@ ex, vi, view \- text editors .SH SYNOPSIS .B ex [\c -.B -eFRrSsv\c +.B -eFGRrSsv\c ] [\c .BI -c " cmd"\c ] [\c @@ -41,7 +41,7 @@ ex, vi, view \- text editors .br .B view [\c -.B -eFRrSv\c +.B -eFGRrSv\c ] [\c .BI -c " cmd"\c ] [\c @@ -120,6 +120,9 @@ Don't copy the entire file when first starting to edit. (The default is to make a copy in case someone else modifies the file during your edit session.) .TP +.B \-G +Start editing in gtags mode, as if the gtagsmode option was set. +.TP .B \-l Start editing with the lisp and showmatch options set. .TP @@ -431,6 +434,8 @@ commands or cancel partial commands. .TP .B "" 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 "" Switch to the most recently edited file. @@ -942,6 +947,9 @@ Grow or shrink the current screen. .B "rew[ind][!]" 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. .TP @@ -1112,6 +1120,9 @@ command line. .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]" Set the spacing between hardware tab settings. .TP diff --git a/dist/nvi/ex/ex.h b/dist/nvi/ex/ex.h index e5454f1bbbb6..5a4aceae56c1 100644 --- a/dist/nvi/ex/ex.h +++ b/dist/nvi/ex/ex.h @@ -1,4 +1,4 @@ -/* $NetBSD: ex.h,v 1.1.1.2 2008/05/18 14:31:11 aymeric Exp $ */ +/* $NetBSD: ex.h,v 1.2 2008/10/29 17:50:49 christos Exp $ */ /*- * Copyright (c) 1992, 1993, 1994 @@ -154,6 +154,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/dist/nvi/ex/ex_cmd.c b/dist/nvi/ex/ex_cmd.c index 4c49cf696083..b909a0f045b5 100644 --- a/dist/nvi/ex/ex_cmd.c +++ b/dist/nvi/ex/ex_cmd.c @@ -1,4 +1,4 @@ -/* $NetBSD: ex_cmd.c,v 1.1.1.2 2008/05/18 14:31:13 aymeric Exp $ */ +/* $NetBSD: ex_cmd.c,v 1.2 2008/10/29 17:50:49 christos Exp $ */ /*- * Copyright (c) 1992, 1993, 1994 @@ -304,6 +304,13 @@ EXCMDLIST const cmds[] = { "!", "rew[ind][!]", "re-edit all the files in the file argument list"}, +#ifdef GTAGS +/* C_RTAG */ + {L("rtag"), ex_rtag_push, E_NEWSCREEN, + "!w1o", + "rta[g][!] [string]", + "edit the file containing the tag"}, +#endif /* * !!! * Adding new commands starting with 's' may break the substitute command code diff --git a/dist/nvi/ex/ex_def.h b/dist/nvi/ex/ex_def.h index edb295464e30..8854f4b7dc54 100644 --- a/dist/nvi/ex/ex_def.h +++ b/dist/nvi/ex/ex_def.h @@ -1,4 +1,4 @@ -/* $NetBSD: ex_def.h,v 1.1.1.1 2008/05/18 14:31:21 aymeric Exp $ */ +/* $NetBSD: ex_def.h,v 1.2 2008/10/29 17:50:49 christos Exp $ */ /* Do not edit: automatically built by build/distrib. */ #define C_SCROLL 0 @@ -50,33 +50,34 @@ #define C_RECOVER 46 #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_VSPLIT 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 +#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_VSPLIT 72 +#define C_WRITE 73 +#define C_WN 74 +#define C_WQ 75 +#define C_XIT 76 +#define C_YANK 77 +#define C_Z 78 +#define C_SUBTILDE 79 diff --git a/dist/nvi/ex/ex_tag.c b/dist/nvi/ex/ex_tag.c index b39ca5cf0555..16766305c3a4 100644 --- a/dist/nvi/ex/ex_tag.c +++ b/dist/nvi/ex/ex_tag.c @@ -1,4 +1,4 @@ -/* $NetBSD: ex_tag.c,v 1.1.1.2 2008/05/18 14:31:20 aymeric Exp $ */ +/* $NetBSD: ex_tag.c,v 1.2 2008/10/29 17:50:49 christos Exp $ */ /*- * Copyright (c) 1992, 1993, 1994 @@ -48,6 +48,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_T *, size_t, char *)); +#ifdef GTAGS +static int getentry __P((char *, char **, char **, char **)); +static TAGQ *gtag_slist __P((SCR *, CHAR_T *, int)); +#endif static int ctag_sfile __P((SCR *, TAGF *, TAGQ *, char *)); static TAGQ *ctag_slist __P((SCR *, CHAR_T *)); static char *linear_search __P((char *, char *, char *, long)); @@ -88,6 +92,23 @@ ex_tag_first(SCR *sp, CHAR_T *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(SCR *sp, EXCMD *cmdp) +{ + F_SET(cmdp, E_REFERENCE); + return ex_tag_push(sp, cmdp); +} +#endif + /* * ex_tag_push -- ^] * :tag[!] [string] @@ -131,6 +152,13 @@ ex_tag_push(SCR *sp, EXCMD *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); @@ -981,6 +1009,132 @@ notfound: tag_msg(sp, TAG_SEARCH, tag); return (0); } +#ifdef GTAGS +/* + * getentry -- + * get tag information from current line. + * + * gtags temporary file format. + * + * + * sample. + * +------------------------------------------------ + * |main 30 main.c main(argc, argv) + * |func 21 subr.c func(arg) + */ +static int +getentry(char *buf, char **tag, char **file, char **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(SCR *sp, CHAR_T *tag, int ref) +{ + EX_PRIVATE *exp; + TAGF *tfp; + TAGQ *tqp; + size_t len, nlen, slen, wlen; + int echk; + TAG *tp; + char *np; + char *name, *file, *line, *search; + char command[BUFSIZ]; + char buf[BUFSIZ]; + CHAR_T *wp; + FILE *fp; + + /* Allocate and initialize the tag queue structure. */ + INT2CHAR(sp, tag, STRLEN(tag) + 1, np, nlen); + len = nlen - 1; + CALLOC_GOTO(sp, tqp, TAGQ *, 1, sizeof(TAGQ) + len + 1); + CIRCLEQ_INIT(&tqp->tagq); + tqp->tag = tqp->buf; + memcpy(tqp->tag, np, (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'", ref ? "rx" : "x", + np); + 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 = (char *)tp->buf; + strcpy(tp->fname, file); + tp->fnlen = strlen(file); + tp->search = (CHAR_T *)(tp->fname + tp->fnlen + 1); + CHAR2INT(sp, search, slen + 1, wp, wlen); + MEMCPYW(tp->search, wp, (tp->slen = slen) + 1); + 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, np, "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. diff --git a/dist/nvi/ex/extern.h b/dist/nvi/ex/extern.h index cb807c6a31ba..ebc618311d83 100644 --- a/dist/nvi/ex/extern.h +++ b/dist/nvi/ex/extern.h @@ -1,4 +1,4 @@ -/* $NetBSD: extern.h,v 1.1.1.1 2008/05/18 14:31:21 aymeric Exp $ */ +/* $NetBSD: extern.h,v 1.2 2008/10/29 17:50:49 christos Exp $ */ /* Do not edit: automatically built by build/distrib. */ int ex __P((SCR **)); @@ -93,6 +93,7 @@ int re_compile __P((SCR *, CHAR_T *, size_t, CHAR_T **, size_t *, regex_t *, u_int)); void re_error __P((SCR *, int, regex_t *)); int ex_tag_first __P((SCR *, CHAR_T *)); +int ex_rtag_push __P((SCR *, EXCMD *)); int ex_tag_push __P((SCR *, EXCMD *)); int ex_tag_next __P((SCR *, EXCMD *)); int ex_tag_prev __P((SCR *, EXCMD *)); diff --git a/dist/nvi/vi/v_ex.c b/dist/nvi/vi/v_ex.c index df7f726e333d..f6ec4cab5e01 100644 --- a/dist/nvi/vi/v_ex.c +++ b/dist/nvi/vi/v_ex.c @@ -1,4 +1,4 @@ -/* $NetBSD: v_ex.c,v 1.1.1.2 2008/05/18 14:31:42 aymeric Exp $ */ +/* $NetBSD: v_ex.c,v 1.2 2008/10/29 17:50:49 christos Exp $ */ /*- * Copyright (c) 1992, 1993, 1994 @@ -211,6 +211,11 @@ v_tagpush(SCR *sp, VICMD *vp) { EXCMD cmd; +#ifdef GTAGS + if (O_ISSET(sp, O_GTAGSMODE) && vp->m_start.cno == 0) + ex_cinit(sp, &cmd, C_RTAG, 0, OOBLNO, 0, 0); + else +#endif ex_cinit(sp, &cmd, C_TAG, 0, OOBLNO, 0, 0); argv_exp0(sp, &cmd, VIP(sp)->keyw, STRLEN(VIP(sp)->keyw) + 1); return (v_exec_ex(sp, vp, &cmd));