1 /* @(#)cmdline.c 1.25 09/07/09 Copyright 1984-2009 J. Schilling */
2 #include <schily/mconfig.h>
3 #ifndef lint
4 static UConst char sccsid[] =
5 "@(#)cmdline.c 1.25 09/07/09 Copyright 1984-2009 J. Schilling";
6 #endif
7 /*
8 * Routines for command line input for ved
9 * Command line input is done on the top (status) line of the screen.
10 *
11 * Copyright (c) 1984-2009 J. Schilling
12 */
13 /*
14 * The contents of this file are subject to the terms of the
15 * Common Development and Distribution License, Version 1.0 only
16 * (the "License"). You may not use this file except in compliance
17 * with the License.
18 *
19 * See the file CDDL.Schily.txt in this distribution for details.
20 * A copy of the CDDL is also available via the Internet at
21 * http://www.opensource.org/licenses/cddl1.txt
22 *
23 * When distributing Covered Code, include this CDDL HEADER in each
24 * file and include the License file CDDL.Schily.txt from this distribution.
25 */
26
27 #include "ved.h"
28 #include "terminal.h"
29 #include <schily/varargs.h>
30
31 EXPORT void wait_for_confirm __PR((ewin_t *wp));
32 EXPORT void wait_continue __PR((ewin_t *wp));
33 EXPORT int getcmdchar __PR((ewin_t *wp, char *ans, char *msg, ...));
34 EXPORT int getcmdline __PR((ewin_t *wp, Uchar *result, int len, char *msg, ...));
35 EXPORT int getccmdline __PR((ewin_t *wp, int c, Uchar *result, int len, char *msg, ...));
36 LOCAL int _getcmdline __PR((ewin_t *wp, int ch, Uchar *result, int len, char *msg, va_list args));
37 LOCAL Uchar mygchar __PR((ewin_t *wp));
38 LOCAL void backspace __PR((int size));
39 LOCAL void space __PR((int size));
40
41 /*
42 * Allow the user to read the current screen before returning
43 * to the edit session.
44 */
45 EXPORT void
wait_for_confirm(wp)46 wait_for_confirm(wp)
47 ewin_t *wp;
48 {
49 output(UC "TYPE ANY CHAR TO RETURN TO EDITOR");
50 CLEAR_TO_EOF_LINE(wp);
51 flush();
52 nigchar(wp);
53 }
54
55 /*
56 * Wait for the user to allow us to output the next page.
57 */
58 EXPORT void
wait_continue(wp)59 wait_continue(wp)
60 ewin_t *wp;
61 {
62 output(UC "TYPE ANY CHAR TO CONTINUE");
63 CLEAR_TO_EOF_LINE(wp);
64 flush();
65 nigchar(wp);
66 }
67
68 /*
69 * Print a formatted message and get a conformation.
70 * If ans is NULL, confirmation may be in the range from space to DEL.
71 * If ans is != NULL confirmation may only be one of the chars in ans (TRUE).
72 * Any other input is taken as abortion.
73 * The calling routine is responsable for evaluating any non-abort input.
74 */
75 /* PRINTFLIKE3 */
76 #ifdef PROTOTYPES
77 EXPORT int
getcmdchar(ewin_t * wp,char * ans,char * msg,...)78 getcmdchar(ewin_t *wp, char *ans, char *msg, ...)
79 #else
80 EXPORT int
81 getcmdchar(wp, ans, msg, va_alist)
82 ewin_t *wp;
83 char *ans;
84 char *msg;
85 va_dcl
86 #endif
87 {
88 va_list args;
89 Uchar c;
90 char tbuf[NAMESIZE];
91 int ret = 0;
92
93 writemsg(wp, "");
94 CURSOR_HOME(wp);
95 #ifdef PROTOTYPES
96 va_start(args, msg);
97 #else
98 va_start(args);
99 #endif
100 snprintf(tbuf, sizeof (tbuf), "%r", msg, args);
101 va_end(args);
102 output(UC tbuf);
103 flush();
104
105 c = nigchar(wp);
106 if (ans == NULL && c > ' ' && c < 0177)
107 ret = c;
108 else if (ans != NULL && strchr(ans, c))
109 ret = c;
110
111 #ifdef PROTOTYPES
112 va_start(args, msg);
113 #else
114 va_start(args);
115 #endif
116 writemsg(wp, "%.20r%c", msg, args, (ret? c : ' '));
117 va_end(args);
118 if (!ret)
119 abortmsg(wp);
120 updatesysline = 1;
121 return (ret);
122 }
123
124 /*
125 * Print a formatted message and read a string.
126 * First character of input is not yet known.
127 */
128 /* PRINTFLIKE4 */
129 #ifdef PROTOTYPES
130 EXPORT int
getcmdline(ewin_t * wp,Uchar * result,int len,char * msg,...)131 getcmdline(ewin_t *wp, Uchar *result, int len, char *msg, ...)
132 #else
133 EXPORT int
134 getcmdline(wp, result, len, msg, va_alist)
135 ewin_t *wp;
136 Uchar *result;
137 int len;
138 char *msg;
139 va_dcl
140 #endif
141 {
142 va_list args;
143 int ret;
144
145 #ifdef PROTOTYPES
146 va_start(args, msg);
147 #else
148 va_start(args);
149 #endif
150 ret = _getcmdline(wp, -1, result, len, msg, args);
151 va_end(args);
152
153 return (ret);
154 }
155
156 /*
157 * Print a formatted message and read a string.
158 * First character of input is not yet known.
159 */
160 /* PRINTFLIKE5 */
161 #ifdef PROTOTYPES
162 EXPORT int
getccmdline(ewin_t * wp,int c,Uchar * result,int len,char * msg,...)163 getccmdline(ewin_t *wp, int c, Uchar *result, int len, char *msg, ...)
164 #else
165 EXPORT int
166 getccmdline(wp, c, result, len, msg, va_alist)
167 ewin_t *wp;
168 int c;
169 Uchar *result;
170 int len;
171 char *msg;
172 va_dcl
173 #endif
174 {
175 va_list args;
176 int ret;
177
178 #ifdef PROTOTYPES
179 va_start(args, msg);
180 #else
181 va_start(args);
182 #endif
183 ret = _getcmdline(wp, c, result, len, msg, args);
184 va_end(args);
185
186 return (ret);
187 }
188
189 /*
190 * Print a formatted message and read a string.
191 * If ch is != -1 take it as the first character.
192 * Return number of characters read.
193 */
194 LOCAL int
_getcmdline(wp,ch,result,len,msg,args)195 _getcmdline(wp, ch, result, len, msg, args)
196 ewin_t *wp;
197 int ch;
198 Uchar *result;
199 register int len;
200 char *msg;
201 va_list args;
202 {
203 extern Uchar csize[];
204 register Uchar *rcsize = csize;
205 register Uchar *str = result;
206 register int size;
207 register int i = 0;
208 register Uchar c;
209 char tbuf[NAMESIZE];
210
211 writemsg(wp, "");
212 CURSOR_HOME(wp);
213 snprintf(tbuf, sizeof (tbuf), "%r", msg, args);
214 output(UC tbuf);
215 flush();
216
217 if (ch == -1)
218 c = mygchar(wp);
219 else
220 c = (Uchar)ch;
221
222 while (c != '\012' && c != '\015') { /* c != ^J && c != ^M */
223 if (c == 0177) { /* DEL */
224 if (i <= 0) {
225 ringbell();
226 } else {
227 --i; --str;
228 cpos.hp -= size = rcsize[*str];
229 backspace(size);
230 space(size);
231 backspace(size);
232 }
233 } else if (c == '\025' || /* ^U -> Kill complete line */
234 c == ('C' & 0x1F)) { /* ^C -> Kill complete line */
235 *result = i = 0;
236 break;
237 } else if (c == '\022') { /* ^R -> Retype line */
238 *str = 0;
239 CURSOR_HOME(wp);
240 CLEAR_TO_EOF_LINE(wp);
241 output(UC msg);
242 printstring(result, i);
243 } else if (c == '\033' || /* ^[ -> Escape next char */
244 c == ('^' & 0x1F)) { /* ^^ -> Escape next char */
245 putoutchar('$');
246 backspace(1);
247 flush();
248 c = mygchar(wp);
249 *str++ = c;
250 i++;
251 printstring(&str[-1], 1);
252 } else {
253 *str++ = c;
254 i++;
255 printstring(&str[-1], 1);
256 }
257 flush();
258 if (i >= len) {
259 CURSOR_HOME(wp);
260 writeerr(wp, "OVERFLOW IN CMD LINE");
261 do {
262 c = nigchar(wp);
263 } while (c != '\03' &&
264 c != '\012' && c != '\015' && c != '\025');
265 /* c != ^C && c != ^J && c != ^M && c != ^U */
266 i = 0;
267 str--;
268 break;
269 }
270 c = mygchar(wp);
271 }
272 *str = '\0';
273 writemsg(wp, "%.20s%s ...", msg, result);
274 if (i == 0)
275 abortmsg(wp);
276 updatesysline = 1;
277 return (i);
278 }
279
280 /*
281 * Get a character from input.
282 * Close input line if environment SLASH is off and a slash was seen.
283 */
284 LOCAL Uchar
mygchar(wp)285 mygchar(wp)
286 ewin_t *wp;
287 {
288 register Uchar c = nigchar(wp);
289
290 if (c == '/' && streql(getenv("SLASH"), "off"))
291 c = '\r';
292 return (c);
293 }
294
295 /*
296 * Write 'size' backspaces
297 */
298 LOCAL void
backspace(size)299 backspace(size)
300 int size;
301 {
302 while (size-- > 0)
303 putoutchar('\b');
304 }
305
306 /*
307 * Write 'size' spaces
308 */
309 LOCAL void
space(size)310 space(size)
311 int size;
312 {
313 while (size-- > 0)
314 putoutchar(' ');
315 }
316