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