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