xref: /minix/external/bsd/nvi/dist/ex/ex_util.c (revision 0a6a1f1d)
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
16 static 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  */
42 void
ex_cinit(SCR * sp,EXCMD * cmdp,int cmd_id,int naddr,db_recno_t lno1,db_recno_t lno2,int force)43 ex_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  */
62 int
ex_getline(SCR * sp,FILE * fp,size_t * lenp)63 ex_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  */
102 int
ex_ncheck(SCR * sp,int force)103 ex_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  */
131 int
ex_init(SCR * sp)132 ex_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  */
156 void
ex_wemsg(SCR * sp,const CHAR_T * p,exm_t which)157 ex_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  */
173 void
ex_emsg(SCR * sp,const char * p,exm_t which)174 ex_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