1/*-
2 * Copyright (c) 1992, 1993, 1994
3 *	The Regents of the University of California.  All rights reserved.
4 * Copyright (c) 1992, 1993, 1994, 1995, 1996
5 *	Keith Bostic.  All rights reserved.
6 *
7 * See the LICENSE file for redistribution information.
8 */
9
10#include "config.h"
11
12#ifndef lint
13static const char sccsid[] = "$Id: ex_display.c,v 10.15 2001/06/25 15:19:15 skimo Exp $";
14#endif /* not lint */
15
16#include <sys/types.h>
17#include <sys/queue.h>
18#include <sys/time.h>
19
20#include <bitstring.h>
21#include <ctype.h>
22#include <limits.h>
23#include <stdio.h>
24#include <string.h>
25
26#include "../common/common.h"
27#include "tag.h"
28
29static int	is_prefix __P((ARGS *, CHAR_T *));
30static int	bdisplay __P((SCR *));
31static void	db __P((SCR *, CB *, const char *));
32
33/*
34 * ex_display -- :display b[uffers] | c[onnections] | s[creens] | t[ags]
35 *
36 *	Display cscope connections, buffers, tags or screens.
37 *
38 * PUBLIC: int ex_display __P((SCR *, EXCMD *));
39 */
40int
41ex_display(SCR *sp, EXCMD *cmdp)
42{
43	ARGS *arg;
44
45	arg = cmdp->argv[0];
46
47	switch (arg->bp[0]) {
48	case 'b':
49		if (!is_prefix(arg, L("buffers")))
50			break;
51		return (bdisplay(sp));
52	case 'c':
53		if (!is_prefix(arg, L("connections")))
54			break;
55		return (cscope_display(sp));
56	case 's':
57		if (!is_prefix(arg, L("screens")))
58			break;
59		return (ex_sdisplay(sp));
60	case 't':
61		if (!is_prefix(arg, L("tags")))
62			break;
63		return (ex_tag_display(sp));
64	}
65	ex_emsg(sp, cmdp->cmd->usage, EXM_USAGE);
66	return (1);
67}
68
69/*
70 * is_prefix --
71 *
72 *	Check that a command argument matches a prefix of a given string.
73 */
74static int
75is_prefix(ARGS *arg, CHAR_T *str)
76{
77	return arg->len <= STRLEN(str) && !MEMCMP(arg->bp, str, arg->len);
78}
79
80/*
81 * bdisplay --
82 *
83 *	Display buffers.
84 */
85static int
86bdisplay(SCR *sp)
87{
88	CB *cbp;
89
90	if (SLIST_EMPTY(sp->gp->cutq) && sp->gp->dcbp == NULL) {
91		msgq(sp, M_INFO, "123|No cut buffers to display");
92		return (0);
93	}
94
95	/* Display regular cut buffers. */
96	SLIST_FOREACH(cbp, sp->gp->cutq, q) {
97		if (isdigit(cbp->name))
98			continue;
99		if (!TAILQ_EMPTY(cbp->textq))
100			db(sp, cbp, NULL);
101		if (INTERRUPTED(sp))
102			return (0);
103	}
104	/* Display numbered buffers. */
105	SLIST_FOREACH(cbp, sp->gp->cutq, q) {
106		if (!isdigit(cbp->name))
107			continue;
108		if (!TAILQ_EMPTY(cbp->textq))
109			db(sp, cbp, NULL);
110		if (INTERRUPTED(sp))
111			return (0);
112	}
113	/* Display default buffer. */
114	if ((cbp = sp->gp->dcbp) != NULL)
115		db(sp, cbp, "default buffer");
116	return (0);
117}
118
119/*
120 * db --
121 *	Display a buffer.
122 */
123static void
124db(SCR *sp, CB *cbp, const char *name)
125{
126	CHAR_T *p;
127	GS *gp;
128	TEXT *tp;
129	size_t len;
130
131	gp = sp->gp;
132	(void)ex_printf(sp, "********** %s%s\n",
133	    name == NULL ? KEY_NAME(sp, cbp->name) : name,
134	    F_ISSET(cbp, CB_LMODE) ? " (line mode)" : " (character mode)");
135	TAILQ_FOREACH(tp, cbp->textq, q) {
136		for (len = tp->len, p = tp->lb; len--; ++p) {
137			(void)ex_puts(sp, KEY_NAME(sp, *p));
138			if (INTERRUPTED(sp))
139				return;
140		}
141		(void)ex_puts(sp, "\n");
142	}
143}
144