1/*	$NetBSD: ex_util.c,v 1.3 2014/01/26 21:43:45 christos Exp $ */
2/*-
3 * Copyright (c) 1993, 1994
4 *	The Regents of the University of California.  All rights reserved.
5 * Copyright (c) 1993, 1994, 1995, 1996
6 *	Keith Bostic.  All rights reserved.
7 *
8 * See the LICENSE file for redistribution information.
9 */
10
11#include "config.h"
12
13#include <sys/cdefs.h>
14#if 0
15#ifndef lint
16static const char sccsid[] = "Id: ex_util.c,v 10.32 2001/06/25 15:19:21 skimo Exp  (Berkeley) Date: 2001/06/25 15:19:21 ";
17#endif /* not lint */
18#else
19__RCSID("$NetBSD: ex_util.c,v 1.3 2014/01/26 21:43:45 christos Exp $");
20#endif
21
22#include <sys/types.h>
23#include <sys/queue.h>
24#include <sys/stat.h>
25
26#include <bitstring.h>
27#include <errno.h>
28#include <limits.h>
29#include <stdio.h>
30#include <stdlib.h>
31#include <string.h>
32#include <unistd.h>
33
34#include "../common/common.h"
35
36/*
37 * ex_cinit --
38 *	Create an EX command structure.
39 *
40 * PUBLIC: void ex_cinit __P((SCR *, EXCMD *, int, int, db_recno_t, db_recno_t, int));
41 */
42void
43ex_cinit(SCR *sp, EXCMD *cmdp, int cmd_id, int naddr, db_recno_t lno1, db_recno_t lno2, int force)
44{
45	memset(cmdp, 0, sizeof(EXCMD));
46	cmdp->cmd = &cmds[cmd_id];
47	cmdp->addrcnt = naddr;
48	cmdp->addr1.lno = lno1;
49	cmdp->addr2.lno = lno2;
50	cmdp->addr1.cno = cmdp->addr2.cno = 1;
51	if (force)
52		cmdp->iflags |= E_C_FORCE;
53	(void)argv_init(sp, cmdp);
54}
55
56/*
57 * ex_getline --
58 *	Return a line from the file.
59 *
60 * PUBLIC: int ex_getline __P((SCR *, FILE *, size_t *));
61 */
62int
63ex_getline(SCR *sp, FILE *fp, size_t *lenp)
64{
65	EX_PRIVATE *exp;
66	size_t off;
67	int ch;
68	char *p;
69
70	exp = EXP(sp);
71	for (errno = 0, off = 0, p = exp->ibp;;) {
72		if (off >= exp->ibp_len) {
73			BINC_RETC(sp, exp->ibp, exp->ibp_len, off + 1);
74			p = exp->ibp + off;
75		}
76		if ((ch = getc(fp)) == EOF && !feof(fp)) {
77			if (errno == EINTR) {
78				errno = 0;
79				clearerr(fp);
80				continue;
81			}
82			return (1);
83		}
84		if (ch == EOF || ch == '\n') {
85			if (ch == EOF && !off)
86				return (1);
87			*lenp = off;
88			return (0);
89		}
90		*p++ = ch;
91		++off;
92	}
93	/* NOTREACHED */
94}
95
96/*
97 * ex_ncheck --
98 *	Check for more files to edit.
99 *
100 * PUBLIC: int ex_ncheck __P((SCR *, int));
101 */
102int
103ex_ncheck(SCR *sp, int force)
104{
105	char **ap;
106
107	/*
108	 * !!!
109	 * Historic practice: quit! or two quit's done in succession
110	 * (where ZZ counts as a quit) didn't check for other files.
111	 */
112	if (!force && sp->ccnt != sp->q_ccnt + 1 &&
113	    sp->cargv != NULL && sp->cargv[1] != NULL) {
114		sp->q_ccnt = sp->ccnt;
115
116		for (ap = sp->cargv + 1; *ap != NULL; ++ap);
117		msgq(sp, M_ERR,
118		    "167|%zd more files to edit", (ap - sp->cargv) - 1);
119
120		return (1);
121	}
122	return (0);
123}
124
125/*
126 * ex_init --
127 *	Init the screen for ex.
128 *
129 * PUBLIC: int ex_init __P((SCR *));
130 */
131int
132ex_init(SCR *sp)
133{
134	GS *gp;
135
136	gp = sp->gp;
137
138	if (gp->scr_screen(sp, SC_EX))
139		return (1);
140	(void)gp->scr_attr(sp, SA_ALTERNATE, 0);
141
142	sp->rows = O_VAL(sp, O_LINES);
143	sp->cols = O_VAL(sp, O_COLUMNS);
144
145	F_CLR(sp, SC_VI);
146	F_SET(sp, SC_EX | SC_SCR_EX);
147	return (0);
148}
149
150/*
151 * ex_emsg --
152 *	Display a few common ex and vi error messages.
153 *
154 * PUBLIC: void ex_wemsg __P((SCR *, const CHAR_T *, exm_t));
155 */
156void
157ex_wemsg(SCR* sp, const CHAR_T *p, exm_t which)
158{
159	const char *np;
160	size_t nlen;
161
162	if (p) INT2CHAR(sp, p, STRLEN(p), np, nlen);
163	else np = NULL;
164	ex_emsg(sp, np, which);
165}
166
167/*
168 * ex_emsg --
169 *	Display a few common ex and vi error messages.
170 *
171 * PUBLIC: void ex_emsg __P((SCR *, const char *, exm_t));
172 */
173void
174ex_emsg(SCR *sp, const char *p, exm_t which)
175{
176	switch (which) {
177	case EXM_EMPTYBUF:
178		msgq(sp, M_ERR, "168|Buffer %s is empty", p);
179		break;
180	case EXM_FILECOUNT:
181		 msgq_str(sp, M_ERR, p,
182		     "144|%s: expanded into too many file names");
183		break;
184	case EXM_LOCKED:
185		msgq(sp, M_ERR,
186		    "Command failed, buffer is locked");
187		break;
188	case EXM_NOCANON:
189		msgq(sp, M_ERR,
190		    "283|The %s command requires the ex terminal interface", p);
191		break;
192	case EXM_NOCANON_F:
193		msgq(sp, M_ERR,
194		    "272|That form of %s requires the ex terminal interface",
195		    p);
196		break;
197	case EXM_NOFILEYET:
198		if (p == NULL)
199			msgq(sp, M_ERR,
200			    "274|Command failed, no file read in yet.");
201		else
202			msgq(sp, M_ERR,
203	"173|The %s command requires that a file have already been read in", p);
204		break;
205	case EXM_NOPREVBUF:
206		msgq(sp, M_ERR, "171|No previous buffer to execute");
207		break;
208	case EXM_NOPREVRE:
209		msgq(sp, M_ERR, "172|No previous regular expression");
210		break;
211	case EXM_NOSUSPEND:
212		msgq(sp, M_ERR, "230|This screen may not be suspended");
213		break;
214	case EXM_SECURE:
215		msgq(sp, M_ERR,
216"290|The %s command is not supported when the secure edit option is set", p);
217		break;
218	case EXM_SECURE_F:
219		msgq(sp, M_ERR,
220"284|That form of %s is not supported when the secure edit option is set", p);
221		break;
222	case EXM_USAGE:
223		msgq(sp, M_ERR, "174|Usage: %s", p);
224		break;
225	}
226}
227