summaryrefslogtreecommitdiffstats
path: root/contrib/nvi/ex/ex_tag.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/nvi/ex/ex_tag.c')
-rw-r--r--contrib/nvi/ex/ex_tag.c734
1 files changed, 286 insertions, 448 deletions
diff --git a/contrib/nvi/ex/ex_tag.c b/contrib/nvi/ex/ex_tag.c
index 8f5e7b9dc..4ef03fb 100644
--- a/contrib/nvi/ex/ex_tag.c
+++ b/contrib/nvi/ex/ex_tag.c
@@ -13,19 +13,13 @@
#include "config.h"
#ifndef lint
-static const char sccsid[] = "@(#)ex_tag.c 10.36 (Berkeley) 9/15/96";
+static const char sccsid[] = "$Id: ex_tag.c,v 10.54 2012/04/12 07:17:30 zy Exp $";
#endif /* not lint */
-#include <sys/param.h>
-#include <sys/types.h> /* XXX: param.h may not have included types.h */
-
-#ifdef HAVE_SYS_MMAN_H
+#include <sys/types.h>
#include <sys/mman.h>
-#endif
-
#include <sys/queue.h>
#include <sys/stat.h>
-#include <sys/time.h>
#include <bitstring.h>
#include <ctype.h>
@@ -45,14 +39,10 @@ static const char sccsid[] = "@(#)ex_tag.c 10.36 (Berkeley) 9/15/96";
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_search __P((SCR *, CHAR_T *, size_t, char *));
static int ctag_sfile __P((SCR *, TAGF *, TAGQ *, char *));
-static TAGQ *ctag_slist __P((SCR *, char *));
-static char *linear_search __P((char *, char *, char *));
+static TAGQ *ctag_slist __P((SCR *, CHAR_T *));
+static char *linear_search __P((char *, char *, char *, long));
static int tag_copy __P((SCR *, TAG *, TAG **));
static int tag_pop __P((SCR *, TAGQ *, int));
static int tagf_copy __P((SCR *, TAGF *, TAGF **));
@@ -63,19 +53,16 @@ static int tagq_copy __P((SCR *, TAGQ *, TAGQ **));
* ex_tag_first --
* The tag code can be entered from main, e.g., "vi -t tag".
*
- * PUBLIC: int ex_tag_first __P((SCR *, char *));
+ * PUBLIC: int ex_tag_first __P((SCR *, CHAR_T *));
*/
int
-ex_tag_first(sp, tagarg)
- SCR *sp;
- char *tagarg;
+ex_tag_first(SCR *sp, CHAR_T *tagarg)
{
- ARGS *ap[2], a;
EXCMD cmd;
/* Build an argument for the ex :tag command. */
- ex_cinit(&cmd, C_TAG, 0, OOBLNO, OOBLNO, 0, ap);
- ex_cadd(&cmd, &a, tagarg, strlen(tagarg));
+ ex_cinit(sp, &cmd, C_TAG, 0, OOBLNO, OOBLNO, 0);
+ argv_exp0(sp, &cmd, tagarg, STRLEN(tagarg));
/*
* XXX
@@ -93,25 +80,6 @@ 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]
@@ -121,18 +89,11 @@ ex_rtag_push(sp, cmdp)
* PUBLIC: int ex_tag_push __P((SCR *, EXCMD *));
*/
int
-ex_tag_push(sp, cmdp)
- SCR *sp;
- EXCMD *cmdp;
+ex_tag_push(SCR *sp, EXCMD *cmdp)
{
EX_PRIVATE *exp;
- FREF *frp;
- TAG *rtp;
- TAGQ *rtqp, *tqp;
- recno_t lno;
- size_t cno;
+ TAGQ *tqp;
long tl;
- int force, istmp;
exp = EXP(sp);
switch (cmdp->argc) {
@@ -140,14 +101,15 @@ ex_tag_push(sp, cmdp)
if (exp->tag_last != NULL)
free(exp->tag_last);
- if ((exp->tag_last = strdup(cmdp->argv[0]->bp)) == NULL) {
+ if ((exp->tag_last = v_wstrdup(sp, cmdp->argv[0]->bp,
+ cmdp->argv[0]->len)) == NULL) {
msgq(sp, M_SYSERR, NULL);
return (1);
}
/* Taglength may limit the number of characters. */
if ((tl =
- O_VAL(sp, O_TAGLENGTH)) != 0 && strlen(exp->tag_last) > tl)
+ O_VAL(sp, O_TAGLENGTH)) != 0 && STRLEN(exp->tag_last) > tl)
exp->tag_last[tl] = '\0';
break;
case 0:
@@ -161,100 +123,14 @@ 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);
- /*
- * Allocate all necessary memory before swapping screens. Initialize
- * flags so we know what to free.
- */
- rtp = NULL;
- rtqp = NULL;
- if (exp->tq.cqh_first == (void *)&exp->tq) {
- /* Initialize the `local context' tag queue structure. */
- CALLOC_GOTO(sp, rtqp, TAGQ *, 1, sizeof(TAGQ));
- CIRCLEQ_INIT(&rtqp->tagq);
-
- /* Initialize and link in its tag structure. */
- CALLOC_GOTO(sp, rtp, TAG *, 1, sizeof(TAG));
- CIRCLEQ_INSERT_HEAD(&rtqp->tagq, rtp, q);
- rtqp->current = rtp;
- }
-
- /*
- * Stick the current context information in a convenient place, we're
- * about to lose it. Note, if we're called on editor startup, there
- * will be no FREF structure.
- */
- frp = sp->frp;
- lno = sp->lno;
- cno = sp->cno;
- istmp = frp == NULL ||
- F_ISSET(frp, FR_TMPFILE) && !F_ISSET(cmdp, E_NEWSCREEN);
-
- /* Try to switch to the tag. */
- force = FL_ISSET(cmdp->iflags, E_C_FORCE);
- if (F_ISSET(cmdp, E_NEWSCREEN)) {
- if (ex_tag_Nswitch(sp, tqp->tagq.cqh_first, force))
- goto err;
-
- /* Everything else gets done in the new screen. */
- sp = sp->nextdisp;
- exp = EXP(sp);
- } else
- if (ex_tag_nswitch(sp, tqp->tagq.cqh_first, force))
- goto err;
-
- /*
- * If this is the first tag, put a `current location' queue entry
- * in place, so we can pop all the way back to the current mark.
- * Note, it doesn't point to much of anything, it's a placeholder.
- */
- if (exp->tq.cqh_first == (void *)&exp->tq) {
- CIRCLEQ_INSERT_HEAD(&exp->tq, rtqp, q);
- } else
- rtqp = exp->tq.cqh_first;
-
- /* Link the new TAGQ structure into place. */
- CIRCLEQ_INSERT_HEAD(&exp->tq, tqp, q);
-
- (void)ctag_search(sp,
- tqp->current->search, tqp->current->slen, tqp->tag);
-
- /*
- * Move the current context from the temporary save area into the
- * right structure.
- *
- * If we were in a temporary file, we don't have a context to which
- * we can return, so just make it be the same as what we're moving
- * to. It will be a little odd that ^T doesn't change anything, but
- * I don't think it's a big deal.
- */
- if (istmp) {
- rtqp->current->frp = sp->frp;
- rtqp->current->lno = sp->lno;
- rtqp->current->cno = sp->cno;
- } else {
- rtqp->current->frp = frp;
- rtqp->current->lno = lno;
- rtqp->current->cno = cno;
- }
- return (0);
+ if (tagq_push(sp, tqp, F_ISSET(cmdp, E_NEWSCREEN),
+ FL_ISSET(cmdp->iflags, E_C_FORCE)))
+ return 1;
-err:
-alloc_err:
- if (rtqp != NULL)
- free(rtqp);
- if (rtp != NULL)
- free(rtp);
- tagq_free(sp, tqp);
- return (1);
+ return 0;
}
/*
@@ -264,20 +140,20 @@ alloc_err:
* PUBLIC: int ex_tag_next __P((SCR *, EXCMD *));
*/
int
-ex_tag_next(sp, cmdp)
- SCR *sp;
- EXCMD *cmdp;
+ex_tag_next(SCR *sp, EXCMD *cmdp)
{
EX_PRIVATE *exp;
TAG *tp;
TAGQ *tqp;
+ char *np;
+ size_t nlen;
exp = EXP(sp);
- if ((tqp = exp->tq.cqh_first) == (void *)&exp->tq) {
+ if ((tqp = TAILQ_FIRST(exp->tq)) == NULL) {
tag_msg(sp, TAG_EMPTY, NULL);
return (1);
}
- if ((tp = tqp->current->q.cqe_next) == (void *)&tqp->tagq) {
+ if ((tp = TAILQ_NEXT(tqp->current, q)) == NULL) {
msgq(sp, M_ERR, "282|Already at the last tag of this group");
return (1);
}
@@ -289,6 +165,11 @@ ex_tag_next(sp, cmdp)
(void)cscope_search(sp, tqp, tp);
else
(void)ctag_search(sp, tp->search, tp->slen, tqp->tag);
+ if (tqp->current->msg) {
+ INT2CHAR(sp, tqp->current->msg, tqp->current->mlen + 1,
+ np, nlen);
+ msgq(sp, M_INFO, "%s", np);
+ }
return (0);
}
@@ -299,20 +180,20 @@ ex_tag_next(sp, cmdp)
* PUBLIC: int ex_tag_prev __P((SCR *, EXCMD *));
*/
int
-ex_tag_prev(sp, cmdp)
- SCR *sp;
- EXCMD *cmdp;
+ex_tag_prev(SCR *sp, EXCMD *cmdp)
{
EX_PRIVATE *exp;
TAG *tp;
TAGQ *tqp;
+ char *np;
+ size_t nlen;
exp = EXP(sp);
- if ((tqp = exp->tq.cqh_first) == (void *)&exp->tq) {
+ if ((tqp = TAILQ_FIRST(exp->tq)) == NULL) {
tag_msg(sp, TAG_EMPTY, NULL);
return (0);
}
- if ((tp = tqp->current->q.cqe_prev) == (void *)&tqp->tagq) {
+ if ((tp = TAILQ_PREV(tqp->current, _tagqh, q)) == NULL) {
msgq(sp, M_ERR, "255|Already at the first tag of this group");
return (1);
}
@@ -324,6 +205,11 @@ ex_tag_prev(sp, cmdp)
(void)cscope_search(sp, tqp, tp);
else
(void)ctag_search(sp, tp->search, tp->slen, tqp->tag);
+ if (tqp->current->msg) {
+ INT2CHAR(sp, tqp->current->msg, tqp->current->mlen + 1,
+ np, nlen);
+ msgq(sp, M_INFO, "%s", np);
+ }
return (0);
}
@@ -334,10 +220,7 @@ ex_tag_prev(sp, cmdp)
* PUBLIC: int ex_tag_nswitch __P((SCR *, TAG *, int));
*/
int
-ex_tag_nswitch(sp, tp, force)
- SCR *sp;
- TAG *tp;
- int force;
+ex_tag_nswitch(SCR *sp, TAG *tp, int force)
{
/* Get a file structure. */
if (tp->frp == NULL && (tp->frp = file_add(sp, tp->fname)) == NULL)
@@ -371,10 +254,7 @@ ex_tag_nswitch(sp, tp, force)
* PUBLIC: int ex_tag_Nswitch __P((SCR *, TAG *, int));
*/
int
-ex_tag_Nswitch(sp, tp, force)
- SCR *sp;
- TAG *tp;
- int force;
+ex_tag_Nswitch(SCR *sp, TAG *tp, int force)
{
SCR *new;
@@ -428,19 +308,18 @@ ex_tag_Nswitch(sp, tp, force)
* PUBLIC: int ex_tag_pop __P((SCR *, EXCMD *));
*/
int
-ex_tag_pop(sp, cmdp)
- SCR *sp;
- EXCMD *cmdp;
+ex_tag_pop(SCR *sp, EXCMD *cmdp)
{
EX_PRIVATE *exp;
TAGQ *tqp, *dtqp;
size_t arglen;
long off;
char *arg, *p, *t;
+ size_t nlen;
/* Check for an empty stack. */
exp = EXP(sp);
- if (exp->tq.cqh_first == (void *)&exp->tq) {
+ if (TAILQ_EMPTY(exp->tq)) {
tag_msg(sp, TAG_EMPTY, NULL);
return (1);
}
@@ -448,10 +327,11 @@ ex_tag_pop(sp, cmdp)
/* Find the last TAG structure that we're going to DISCARD! */
switch (cmdp->argc) {
case 0: /* Pop one tag. */
- dtqp = exp->tq.cqh_first;
+ dtqp = TAILQ_FIRST(exp->tq);
break;
case 1: /* Name or number. */
- arg = cmdp->argv[0]->bp;
+ INT2CHAR(sp, cmdp->argv[0]->bp, cmdp->argv[0]->len+1,
+ arg, nlen);
off = strtol(arg, &p, 10);
if (*p != '\0')
goto filearg;
@@ -459,10 +339,9 @@ ex_tag_pop(sp, cmdp)
/* Number: pop that many queue entries. */
if (off < 1)
return (0);
- for (tqp = exp->tq.cqh_first;
- tqp != (void *)&exp->tq && --off > 1;
- tqp = tqp->q.cqe_next);
- if (tqp == (void *)&exp->tq) {
+ TAILQ_FOREACH(tqp, exp->tq, q)
+ if (--off <= 1) break;
+ if (tqp == NULL) {
msgq(sp, M_ERR,
"159|Less than %s entries on the tags stack; use :display t[ags]",
arg);
@@ -473,11 +352,10 @@ ex_tag_pop(sp, cmdp)
/* File argument: pop to that queue entry. */
filearg: arglen = strlen(arg);
- for (tqp = exp->tq.cqh_first;
- tqp != (void *)&exp->tq;
- dtqp = tqp, tqp = tqp->q.cqe_next) {
+ for (tqp = TAILQ_FIRST(exp->tq); tqp;
+ dtqp = tqp, tqp = TAILQ_NEXT(tqp, q)) {
/* Don't pop to the current file. */
- if (tqp == exp->tq.cqh_first)
+ if (tqp == TAILQ_FIRST(exp->tq))
continue;
p = tqp->current->frp->name;
if ((t = strrchr(p, '/')) == NULL)
@@ -487,12 +365,12 @@ filearg: arglen = strlen(arg);
if (!strncmp(arg, t, arglen))
break;
}
- if (tqp == (void *)&exp->tq) {
+ if (tqp == NULL) {
msgq_str(sp, M_ERR, arg,
"160|No file %s on the tags stack to return to; use :display t[ags]");
return (1);
}
- if (tqp == exp->tq.cqh_first)
+ if (tqp == TAILQ_FIRST(exp->tq))
return (0);
break;
default:
@@ -509,23 +387,21 @@ filearg: arglen = strlen(arg);
* PUBLIC: int ex_tag_top __P((SCR *, EXCMD *));
*/
int
-ex_tag_top(sp, cmdp)
- SCR *sp;
- EXCMD *cmdp;
+ex_tag_top(SCR *sp, EXCMD *cmdp)
{
EX_PRIVATE *exp;
exp = EXP(sp);
/* Check for an empty stack. */
- if (exp->tq.cqh_first == (void *)&exp->tq) {
+ if (TAILQ_EMPTY(exp->tq)) {
tag_msg(sp, TAG_EMPTY, NULL);
return (1);
}
/* Return to the oldest information. */
- return (tag_pop(sp,
- exp->tq.cqh_last->q.cqe_prev, FL_ISSET(cmdp->iflags, E_C_FORCE)));
+ return (tag_pop(sp, TAILQ_PREV(TAILQ_LAST(exp->tq, _tqh), _tqh, q),
+ FL_ISSET(cmdp->iflags, E_C_FORCE)));
}
/*
@@ -533,10 +409,7 @@ ex_tag_top(sp, cmdp)
* Pop up to and including the specified TAGQ context.
*/
static int
-tag_pop(sp, dtqp, force)
- SCR *sp;
- TAGQ *dtqp;
- int force;
+tag_pop(SCR *sp, TAGQ *dtqp, int force)
{
EX_PRIVATE *exp;
TAG *tp;
@@ -548,7 +421,7 @@ tag_pop(sp, dtqp, force)
* Update the cursor from the saved TAG information of the TAG
* structure we're moving to.
*/
- tp = dtqp->q.cqe_next->current;
+ tp = TAILQ_NEXT(dtqp, q)->current;
if (tp->frp == sp->frp) {
sp->lno = tp->lno;
sp->cno = tp->cno;
@@ -567,7 +440,7 @@ tag_pop(sp, dtqp, force)
/* Pop entries off the queue up to and including dtqp. */
do {
- tqp = exp->tq.cqh_first;
+ tqp = TAILQ_FIRST(exp->tq);
if (tagq_free(sp, tqp))
return (0);
} while (tqp != dtqp);
@@ -576,8 +449,8 @@ tag_pop(sp, dtqp, force)
* If only a single tag left, we've returned to the first tag point,
* and the stack is now empty.
*/
- if (exp->tq.cqh_first->q.cqe_next == (void *)&exp->tq)
- tagq_free(sp, exp->tq.cqh_first);
+ if (TAILQ_NEXT(TAILQ_FIRST(exp->tq), q) == NULL)
+ tagq_free(sp, TAILQ_FIRST(exp->tq));
return (0);
}
@@ -589,18 +462,17 @@ tag_pop(sp, dtqp, force)
* PUBLIC: int ex_tag_display __P((SCR *));
*/
int
-ex_tag_display(sp)
- SCR *sp;
+ex_tag_display(SCR *sp)
{
EX_PRIVATE *exp;
TAG *tp;
TAGQ *tqp;
int cnt;
size_t len;
- char *p, *sep;
+ char *p;
exp = EXP(sp);
- if ((tqp = exp->tq.cqh_first) == (void *)&exp->tq) {
+ if (TAILQ_EMPTY(exp->tq)) {
tag_msg(sp, TAG_EMPTY, NULL);
return (0);
}
@@ -628,11 +500,10 @@ ex_tag_display(sp)
* Display the list of tags for each queue entry. The first entry
* is numbered, and the current tag entry has an asterisk appended.
*/
- for (cnt = 1, tqp = exp->tq.cqh_first; !INTERRUPTED(sp) &&
- tqp != (void *)&exp->tq; ++cnt, tqp = tqp->q.cqe_next)
- for (tp = tqp->tagq.cqh_first;
- tp != (void *)&tqp->tagq; tp = tp->q.cqe_next) {
- if (tp == tqp->tagq.cqh_first)
+ for (cnt = 1, tqp = TAILQ_FIRST(exp->tq); !INTERRUPTED(sp) &&
+ tqp != NULL; ++cnt, tqp = TAILQ_NEXT(tqp, q))
+ TAILQ_FOREACH(tp, tqp->tagq, q) {
+ if (tp == TAILQ_FIRST(tqp->tagq))
(void)ex_printf(sp, "%2d ", cnt);
else
(void)ex_printf(sp, " ");
@@ -647,7 +518,7 @@ ex_tag_display(sp)
if (tqp->current == tp)
(void)ex_printf(sp, "*");
- if (tp == tqp->tagq.cqh_first && tqp->tag != NULL &&
+ if (tp == TAILQ_FIRST(tqp->tagq) && tqp->tag != NULL &&
(sp->cols - L_NAME) >= L_TAG + L_SPACE) {
len = strlen(tqp->tag);
if (len > sp->cols - (L_NAME + L_SPACE))
@@ -668,8 +539,7 @@ ex_tag_display(sp)
* PUBLIC: int ex_tag_copy __P((SCR *, SCR *));
*/
int
-ex_tag_copy(orig, sp)
- SCR *orig, *sp;
+ex_tag_copy(SCR *orig, SCR *sp)
{
EX_PRIVATE *oexp, *nexp;
TAGQ *aqp, *tqp;
@@ -680,33 +550,31 @@ ex_tag_copy(orig, sp)
nexp = EXP(sp);
/* Copy tag queue and tags stack. */
- for (aqp = oexp->tq.cqh_first;
- aqp != (void *)&oexp->tq; aqp = aqp->q.cqe_next) {
+ TAILQ_FOREACH(aqp, oexp->tq, q) {
if (tagq_copy(sp, aqp, &tqp))
return (1);
- for (ap = aqp->tagq.cqh_first;
- ap != (void *)&aqp->tagq; ap = ap->q.cqe_next) {
+ TAILQ_FOREACH(ap, aqp->tagq, q) {
if (tag_copy(sp, ap, &tp))
return (1);
/* Set the current pointer. */
if (aqp->current == ap)
tqp->current = tp;
- CIRCLEQ_INSERT_TAIL(&tqp->tagq, tp, q);
+ TAILQ_INSERT_TAIL(tqp->tagq, tp, q);
}
- CIRCLEQ_INSERT_TAIL(&nexp->tq, tqp, q);
+ TAILQ_INSERT_TAIL(nexp->tq, tqp, q);
}
/* Copy list of tag files. */
- for (atfp = oexp->tagfq.tqh_first;
- atfp != NULL; atfp = atfp->q.tqe_next) {
+ TAILQ_FOREACH(atfp, oexp->tagfq, q) {
if (tagf_copy(sp, atfp, &tfp))
return (1);
- TAILQ_INSERT_TAIL(&nexp->tagfq, tfp, q);
+ TAILQ_INSERT_TAIL(nexp->tagfq, tfp, q);
}
/* Copy the last tag. */
if (oexp->tag_last != NULL &&
- (nexp->tag_last = strdup(oexp->tag_last)) == NULL) {
+ (nexp->tag_last = v_wstrdup(sp, oexp->tag_last,
+ STRLEN(oexp->tag_last))) == NULL) {
msgq(sp, M_SYSERR, NULL);
return (1);
}
@@ -718,9 +586,7 @@ ex_tag_copy(orig, sp)
* Copy a TAGF structure and return it in new memory.
*/
static int
-tagf_copy(sp, otfp, tfpp)
- SCR *sp;
- TAGF *otfp, **tfpp;
+tagf_copy(SCR *sp, TAGF *otfp, TAGF **tfpp)
{
TAGF *tfp;
@@ -740,9 +606,7 @@ tagf_copy(sp, otfp, tfpp)
* Copy a TAGQ structure and return it in new memory.
*/
static int
-tagq_copy(sp, otqp, tqpp)
- SCR *sp;
- TAGQ *otqp, **tqpp;
+tagq_copy(SCR *sp, TAGQ *otqp, TAGQ **tqpp)
{
TAGQ *tqp;
size_t len;
@@ -753,7 +617,7 @@ tagq_copy(sp, otqp, tqpp)
MALLOC_RET(sp, tqp, TAGQ *, len);
memcpy(tqp, otqp, len);
- CIRCLEQ_INIT(&tqp->tagq);
+ TAILQ_INIT(tqp->tagq);
tqp->current = NULL;
if (otqp->tag != NULL)
tqp->tag = tqp->buf;
@@ -767,9 +631,7 @@ tagq_copy(sp, otqp, tqpp)
* Copy a TAG structure and return it in new memory.
*/
static int
-tag_copy(sp, otp, tpp)
- SCR *sp;
- TAG *otp, **tpp;
+tag_copy(SCR *sp, TAG *otp, TAG **tpp)
{
TAG *tp;
size_t len;
@@ -779,13 +641,17 @@ tag_copy(sp, otp, tpp)
len += otp->fnlen + 1;
if (otp->search != NULL)
len += otp->slen + 1;
+ if (otp->msg != NULL)
+ len += otp->mlen + 1;
MALLOC_RET(sp, tp, TAG *, len);
memcpy(tp, otp, len);
if (otp->fname != NULL)
- tp->fname = tp->buf;
+ tp->fname = (char *)tp->buf;
if (otp->search != NULL)
- tp->search = tp->fname + otp->fnlen + 1;
+ tp->search = tp->buf + (otp->search - otp->buf);
+ if (otp->msg != NULL)
+ tp->msg = tp->buf + (otp->msg - otp->buf);
*tpp = tp;
return (0);
@@ -796,14 +662,12 @@ tag_copy(sp, otp, tpp)
* Free a TAGF structure.
*/
static int
-tagf_free(sp, tfp)
- SCR *sp;
- TAGF *tfp;
+tagf_free(SCR *sp, TAGF *tfp)
{
EX_PRIVATE *exp;
exp = EXP(sp);
- TAILQ_REMOVE(&exp->tagfq, tfp, q);
+ TAILQ_REMOVE(exp->tagfq, tfp, q);
free(tfp->name);
free(tfp);
return (0);
@@ -816,16 +680,14 @@ tagf_free(sp, tfp)
* PUBLIC: int tagq_free __P((SCR *, TAGQ *));
*/
int
-tagq_free(sp, tqp)
- SCR *sp;
- TAGQ *tqp;
+tagq_free(SCR *sp, TAGQ *tqp)
{
EX_PRIVATE *exp;
TAG *tp;
exp = EXP(sp);
- while ((tp = tqp->tagq.cqh_first) != (void *)&tqp->tagq) {
- CIRCLEQ_REMOVE(&tqp->tagq, tp, q);
+ while ((tp = TAILQ_FIRST(tqp->tagq)) != NULL) {
+ TAILQ_REMOVE(tqp->tagq, tp, q);
free(tp);
}
/*
@@ -833,23 +695,129 @@ tagq_free(sp, tqp)
* If allocated and then the user failed to switch files, the TAGQ
* structure was never attached to any list.
*/
- if (tqp->q.cqe_next != NULL)
- CIRCLEQ_REMOVE(&exp->tq, tqp, q);
+ if (TAILQ_ENTRY_ISVALID(tqp, q))
+ TAILQ_REMOVE(exp->tq, tqp, q);
free(tqp);
return (0);
}
/*
+ * PUBLIC: int tagq_push __P((SCR*, TAGQ*, int, int ));
+ */
+int
+tagq_push(SCR *sp, TAGQ *tqp, int new_screen, int force)
+{
+ EX_PRIVATE *exp;
+ FREF *frp;
+ TAG *rtp;
+ TAGQ *rtqp;
+ recno_t lno;
+ size_t cno;
+ int istmp;
+ char *np;
+ size_t nlen;
+
+ exp = EXP(sp);
+
+ /*
+ * Allocate all necessary memory before swapping screens. Initialize
+ * flags so we know what to free.
+ */
+ rtp = NULL;
+ rtqp = NULL;
+ if (TAILQ_EMPTY(exp->tq)) {
+ /* Initialize the `local context' tag queue structure. */
+ CALLOC_GOTO(sp, rtqp, TAGQ *, 1, sizeof(TAGQ));
+ TAILQ_INIT(rtqp->tagq);
+
+ /* Initialize and link in its tag structure. */
+ CALLOC_GOTO(sp, rtp, TAG *, 1, sizeof(TAG));
+ TAILQ_INSERT_HEAD(rtqp->tagq, rtp, q);
+ rtqp->current = rtp;
+ }
+
+ /*
+ * Stick the current context information in a convenient place, we're
+ * about to lose it. Note, if we're called on editor startup, there
+ * will be no FREF structure.
+ */
+ frp = sp->frp;
+ lno = sp->lno;
+ cno = sp->cno;
+ istmp = frp == NULL ||
+ (F_ISSET(frp, FR_TMPFILE) && !new_screen);
+
+ /* Try to switch to the preset tag. */
+ if (new_screen) {
+ if (ex_tag_Nswitch(sp, tqp->current, force))
+ goto err;
+
+ /* Everything else gets done in the new screen. */
+ sp = sp->nextdisp;
+ exp = EXP(sp);
+ } else
+ if (ex_tag_nswitch(sp, tqp->current, force))
+ goto err;
+
+ /*
+ * If this is the first tag, put a `current location' queue entry
+ * in place, so we can pop all the way back to the current mark.
+ * Note, it doesn't point to much of anything, it's a placeholder.
+ */
+ if (TAILQ_EMPTY(exp->tq)) {
+ TAILQ_INSERT_HEAD(exp->tq, rtqp, q);
+ } else
+ rtqp = TAILQ_FIRST(exp->tq);
+
+ /* Link the new TAGQ structure into place. */
+ TAILQ_INSERT_HEAD(exp->tq, tqp, q);
+
+ (void)ctag_search(sp,
+ tqp->current->search, tqp->current->slen, tqp->tag);
+ if (tqp->current->msg) {
+ INT2CHAR(sp, tqp->current->msg, tqp->current->mlen + 1,
+ np, nlen);
+ msgq(sp, M_INFO, "%s", np);
+ }
+
+ /*
+ * Move the current context from the temporary save area into the
+ * right structure.
+ *
+ * If we were in a temporary file, we don't have a context to which
+ * we can return, so just make it be the same as what we're moving
+ * to. It will be a little odd that ^T doesn't change anything, but
+ * I don't think it's a big deal.
+ */
+ if (istmp) {
+ rtqp->current->frp = sp->frp;
+ rtqp->current->lno = sp->lno;
+ rtqp->current->cno = sp->cno;
+ } else {
+ rtqp->current->frp = frp;
+ rtqp->current->lno = lno;
+ rtqp->current->cno = cno;
+ }
+ return (0);
+
+err:
+alloc_err:
+ if (rtqp != NULL)
+ free(rtqp);
+ if (rtp != NULL)
+ free(rtp);
+ tagq_free(sp, tqp);
+ return (1);
+}
+
+/*
* tag_msg
* A few common messages.
*
* PUBLIC: void tag_msg __P((SCR *, tagmsg_t, char *));
*/
void
-tag_msg(sp, msg, tag)
- SCR *sp;
- tagmsg_t msg;
- char *tag;
+tag_msg(SCR *sp, tagmsg_t msg, char *tag)
{
switch (msg) {
case TAG_BADLNO:
@@ -874,9 +842,7 @@ tag_msg(sp, msg, tag)
* PUBLIC: int ex_tagf_alloc __P((SCR *, char *));
*/
int
-ex_tagf_alloc(sp, str)
- SCR *sp;
- char *str;
+ex_tagf_alloc(SCR *sp, char *str)
{
EX_PRIVATE *exp;
TAGF *tfp;
@@ -885,13 +851,13 @@ ex_tagf_alloc(sp, str)
/* Free current queue. */
exp = EXP(sp);
- while ((tfp = exp->tagfq.tqh_first) != NULL)
+ while ((tfp = TAILQ_FIRST(exp->tagfq)) != NULL)
tagf_free(sp, tfp);
/* Create new queue. */
for (p = t = str;; ++p) {
- if (*p == '\0' || isblank(*p)) {
- if ((len = p - t) > 1) {
+ if (*p == '\0' || cmdskip(*p)) {
+ if ((len = p - t)) {
MALLOC_RET(sp, tfp, TAGF *, sizeof(TAGF));
MALLOC(sp, tfp->name, char *, len + 1);
if (tfp->name == NULL) {
@@ -901,7 +867,7 @@ ex_tagf_alloc(sp, str)
memcpy(tfp->name, t, len);
tfp->name[len] = '\0';
tfp->flags = 0;
- TAILQ_INSERT_TAIL(&exp->tagfq, tfp, q);
+ TAILQ_INSERT_TAIL(exp->tagfq, tfp, q);
}
t = p + 1;
}
@@ -918,8 +884,7 @@ ex_tagf_alloc(sp, str)
* PUBLIC: int ex_tag_free __P((SCR *));
*/
int
-ex_tag_free(sp)
- SCR *sp;
+ex_tag_free(SCR *sp)
{
EX_PRIVATE *exp;
TAGF *tfp;
@@ -927,9 +892,9 @@ ex_tag_free(sp)
/* Free up tag information. */
exp = EXP(sp);
- while ((tqp = exp->tq.cqh_first) != (void *)&exp->tq)
+ while ((tqp = TAILQ_FIRST(exp->tq)) != NULL)
tagq_free(sp, tqp);
- while ((tfp = exp->tagfq.tqh_first) != NULL)
+ while ((tfp = TAILQ_FIRST(exp->tagfq)) != NULL)
tagf_free(sp, tfp);
if (exp->tag_last != NULL)
free(exp->tag_last);
@@ -941,13 +906,12 @@ ex_tag_free(sp)
* Search a file for a tag.
*/
static int
-ctag_search(sp, search, slen, tag)
- SCR *sp;
- char *search, *tag;
- size_t slen;
+ctag_search(SCR *sp, CHAR_T *search, size_t slen, char *tag)
{
MARK m;
char *p;
+ char *np;
+ size_t nlen;
/*
* !!!
@@ -955,8 +919,9 @@ ctag_search(sp, search, slen, tag)
* used a line number, not a search string. I got complaints, so
* people are still using the format. POSIX 1003.2 permits it.
*/
- if (isdigit(search[0])) {
- m.lno = atoi(search);
+ if (ISDIGIT(search[0])) {
+ INT2CHAR(sp, search, slen+1, np, nlen);
+ m.lno = atoi(np);
if (!db_exist(sp, m.lno)) {
tag_msg(sp, TAG_BADLNO, tag);
return (1);
@@ -969,9 +934,10 @@ ctag_search(sp, search, slen, tag)
m.lno = 1;
m.cno = 0;
if (f_search(sp, &m, &m,
- search, slen, NULL, SEARCH_FILE | SEARCH_TAG))
- if ((p = strrchr(search, '(')) != NULL) {
- slen = p - search;
+ search, slen, NULL, SEARCH_FILE | SEARCH_TAG)) {
+ INT2CHAR(sp, search, slen, np, nlen);
+ if ((p = strrchr(np, '(')) != NULL) {
+ slen = p - np;
if (f_search(sp, &m, &m, search, slen,
NULL, SEARCH_FILE | SEARCH_TAG))
goto notfound;
@@ -979,6 +945,7 @@ ctag_search(sp, search, slen, tag)
notfound: tag_msg(sp, TAG_SEARCH, tag);
return (1);
}
+ }
/*
* !!!
* Historically, tags set the search direction if it wasn't
@@ -998,171 +965,47 @@ 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 = 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'", 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.
*/
static TAGQ *
-ctag_slist(sp, tag)
- SCR *sp;
- char *tag;
+ctag_slist(SCR *sp, CHAR_T *tag)
{
EX_PRIVATE *exp;
TAGF *tfp;
TAGQ *tqp;
size_t len;
- int echk;
+ int echk = 0;
+ char *np;
+ size_t nlen;
exp = EXP(sp);
/* Allocate and initialize the tag queue structure. */
- len = strlen(tag);
+ 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);
+ TAILQ_INIT(tqp->tagq);
tqp->tag = tqp->buf;
- memcpy(tqp->tag, tag, (tqp->tlen = len) + 1);
+ 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.
*/
- for (echk = 0,
- tfp = exp->tagfq.tqh_first; tfp != NULL; tfp = tfp->q.tqe_next)
- if (ctag_sfile(sp, tfp, tqp, tag)) {
+ TAILQ_FOREACH(tfp, exp->tagfq, q)
+ if (ctag_sfile(sp, tfp, tqp, tqp->tag)) {
echk = 1;
F_SET(tfp, TAGF_ERR);
} else
F_CLR(tfp, TAGF_ERR | TAGF_ERR_WARN);
/* 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");
+ if (TAILQ_EMPTY(tqp->tagq)) {
+ msgq_str(sp, M_ERR, tqp->tag, "162|%s: tag not found");
if (echk)
- for (tfp = exp->tagfq.tqh_first;
- tfp != NULL; tfp = tfp->q.tqe_next)
+ TAILQ_FOREACH(tfp, exp->tagfq, q)
if (F_ISSET(tfp, TAGF_ERR) &&
!F_ISSET(tfp, TAGF_ERR_WARN)) {
errno = tfp->errnum;
@@ -1173,7 +1016,6 @@ ctag_slist(sp, tag)
return (NULL);
}
- tqp->current = tqp->tagq.cqh_first;
return (tqp);
alloc_err:
@@ -1185,51 +1027,36 @@ alloc_err:
* Search a tags file for a tag, adding any found to the tag queue.
*/
static int
-ctag_sfile(sp, tfp, tqp, tname)
- SCR *sp;
- TAGF *tfp;
- TAGQ *tqp;
- char *tname;
+ctag_sfile(SCR *sp, TAGF *tfp, TAGQ *tqp, char *tname)
{
struct stat sb;
TAG *tp;
- size_t dlen, nlen, slen;
+ size_t dlen, nlen = 0, slen;
int fd, i, nf1, nf2;
- char *back, *cname, *dname, *front, *map, *name, *p, *search, *t;
+ char *back, *front, *map, *p, *search, *t;
+ char *cname = NULL, *dname = NULL, *name = NULL;
+ CHAR_T *wp;
+ size_t wlen;
+ long tl;
if ((fd = open(tfp->name, O_RDONLY, 0)) < 0) {
tfp->errnum = errno;
return (1);
}
- /*
- * XXX
- * Some old BSD systems require MAP_FILE as an argument when mapping
- * regular files.
- */
-#ifndef MAP_FILE
-#define MAP_FILE 0
-#endif
- /*
- * XXX
- * We'd like to test if the file is too big to mmap. Since we don't
- * know what size or type off_t's or size_t's are, what the largest
- * unsigned integral type is, or what random insanity the local C
- * compiler will perpetrate, doing the comparison in a portable way
- * is flatly impossible. Hope mmap fails if the file is too large.
- */
if (fstat(fd, &sb) != 0 ||
- (map = mmap(NULL, (size_t)sb.st_size, PROT_READ | PROT_WRITE,
- MAP_FILE | MAP_PRIVATE, fd, (off_t)0)) == (caddr_t)-1) {
+ (map = mmap(NULL, sb.st_size, PROT_READ | PROT_WRITE,
+ MAP_PRIVATE, fd, 0)) == MAP_FAILED) {
tfp->errnum = errno;
(void)close(fd);
return (1);
}
+ tl = O_VAL(sp, O_TAGLENGTH);
front = map;
back = front + sb.st_size;
front = binary_search(tname, front, back);
- front = linear_search(tname, front, back);
+ front = linear_search(tname, front, back, tl);
if (front == NULL)
goto done;
@@ -1292,29 +1119,41 @@ corrupt: p = msg_print(sp, tname, &nf1);
}
/* Check for passing the last entry. */
- if (strcmp(tname, cname))
+ if (tl ? strncmp(tname, cname, tl) : strcmp(tname, cname))
break;
/* Resolve the file name. */
ctag_file(sp, tfp, name, &dname, &dlen);
CALLOC_GOTO(sp, tp,
- TAG *, 1, sizeof(TAG) + dlen + 2 + nlen + 1 + slen + 1);
- tp->fname = tp->buf;
- if (dlen != 0) {
+ TAG *, 1, sizeof(TAG) + dlen + 2 + nlen + 1 +
+ (slen + 1) * sizeof(CHAR_T));
+ tp->fname = (char *)tp->buf;
+ if (dlen == 1 && *dname == '.')
+ --dlen;
+ else if (dlen != 0) {
memcpy(tp->fname, dname, dlen);
tp->fname[dlen] = '/';
++dlen;
}
memcpy(tp->fname + dlen, name, nlen + 1);
tp->fnlen = dlen + nlen;
- tp->search = tp->fname + tp->fnlen + 1;
- memcpy(tp->search, search, (tp->slen = slen) + 1);
- CIRCLEQ_INSERT_TAIL(&tqp->tagq, tp, q);
+ tp->search = (CHAR_T*)(tp->fname + tp->fnlen + 1);
+ CHAR2INT(sp, search, slen + 1, wp, wlen);
+ MEMCPY(tp->search, wp, (tp->slen = slen) + 1);
+ TAILQ_INSERT_TAIL(tqp->tagq, tp, q);
+
+ /* Try to preset the tag within the current file. */
+ if (sp->frp != NULL && sp->frp->name != NULL &&
+ tqp->current == NULL && !strcmp(tp->fname, sp->frp->name))
+ tqp->current = tp;
}
+ if (tqp->current == NULL)
+ tqp->current = TAILQ_FIRST(tqp->tagq);
+
alloc_err:
-done: if (munmap(map, (size_t)sb.st_size))
+done: if (munmap(map, sb.st_size))
msgq(sp, M_SYSERR, "munmap");
if (close(fd))
msgq(sp, M_SYSERR, "close");
@@ -1326,15 +1165,10 @@ done: if (munmap(map, (size_t)sb.st_size))
* Search for the right path to this file.
*/
static void
-ctag_file(sp, tfp, name, dirp, dlenp)
- SCR *sp;
- TAGF *tfp;
- char *name, **dirp;
- size_t *dlenp;
+ctag_file(SCR *sp, TAGF *tfp, char *name, char **dirp, size_t *dlenp)
{
struct stat sb;
- size_t len;
- char *p, buf[MAXPATHLEN];
+ char *p, *buf;
/*
* !!!
@@ -1348,12 +1182,16 @@ ctag_file(sp, tfp, name, dirp, dlenp)
if (name[0] != '/' &&
stat(name, &sb) && (p = strrchr(tfp->name, '/')) != NULL) {
*p = '\0';
- len = snprintf(buf, sizeof(buf), "%s/%s", tfp->name, name);
- *p = '/';
+ if ((buf = join(tfp->name, name)) == NULL) {
+ msgq(sp, M_SYSERR, NULL);
+ return;
+ }
if (stat(buf, &sb) == 0) {
*dirp = tfp->name;
*dlenp = strlen(*dirp);
}
+ free(buf);
+ *p = '/';
}
}
@@ -1399,11 +1237,11 @@ ctag_file(sp, tfp, name, dirp, dlenp)
#define GREATER 1
#define LESS (-1)
-#define SKIP_PAST_NEWLINE(p, back) while (p < back && *p++ != '\n');
+#define SKIP_PAST_NEWLINE(p, back) \
+ while (p < back && *p++ != '\n') continue;
static char *
-binary_search(string, front, back)
- register char *string, *front, *back;
+binary_search(register char *string, register char *front, register char *back)
{
register char *p;
@@ -1433,11 +1271,12 @@ binary_search(string, front, back)
* o front is before or at the first line to be printed.
*/
static char *
-linear_search(string, front, back)
- char *string, *front, *back;
+linear_search(char *string, char *front, char *back, long tl)
{
+ char *end;
while (front < back) {
- switch (compare(string, front, back)) {
+ end = tl && back-front > tl ? front+tl : back;
+ switch (compare(string, front, end)) {
case EQUAL: /* Found it. */
return (front);
case LESS: /* No such string. */
@@ -1465,8 +1304,7 @@ linear_search(string, front, back)
* However, historic programs did use spaces, and, I got complaints.
*/
static int
-compare(s1, s2, back)
- register char *s1, *s2, *back;
+compare(register char *s1, register char *s2, register char *back)
{
for (; *s1 && s2 < back && (*s2 != '\t' && *s2 != ' '); ++s1, ++s2)
if (*s1 != *s2)
OpenPOWER on IntegriCloud