1 /*
2 * Copyright (c) 1983, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * This code is derived from software contributed to Berkeley by
6 * Edward Wang at The University of California, Berkeley.
7 *
8 * %sccs.include.redist.c%
9 */
10
11 #ifndef lint
12 static char sccsid[] = "@(#)lcmd1.c 8.1 (Berkeley) 06/06/93";
13 #endif /* not lint */
14
15 #include "defs.h"
16 #include "string.h"
17 #include "value.h"
18 #include "lcmd.h"
19 #include "var.h"
20
21 struct lcmd_arg arg_window[] = {
22 { "row", 1, ARG_NUM },
23 { "column", 1, ARG_NUM },
24 { "nrows", 2, ARG_NUM },
25 { "ncols", 2, ARG_NUM },
26 { "nlines", 2, ARG_NUM },
27 { "label", 1, ARG_STR },
28 { "pty", 1, ARG_ANY },
29 { "frame", 1, ARG_ANY },
30 { "mapnl", 1, ARG_ANY },
31 { "keepopen", 1, ARG_ANY },
32 { "smooth", 1, ARG_ANY },
33 { "shell", 1, ARG_STR|ARG_LIST },
34 0
35 };
36
37 l_window(v, a)
38 struct value *v;
39 register struct value *a;
40 {
41 struct ww *w;
42 int col, row, ncol, nrow, id, nline;
43 char *label;
44 char haspty, hasframe, mapnl, keepopen, smooth;
45 char *shf, **sh;
46 char *argv[sizeof default_shell / sizeof *default_shell];
47 register char **pp;
48
49 if ((id = findid()) < 0)
50 return;
51 row = a->v_type == V_ERR ? 1 : a->v_num;
52 a++;
53 col = a->v_type == V_ERR ? 0 : a->v_num;
54 a++;
55 nrow = a->v_type == V_ERR ? wwnrow - row : a->v_num;
56 a++;
57 ncol = a->v_type == V_ERR ? wwncol - col : a->v_num;
58 a++;
59 nline = a->v_type == V_ERR ? default_nline : a->v_num;
60 a++;
61 label = a->v_type == V_ERR ? 0 : a->v_str;
62 if ((haspty = vtobool(++a, 1, -1)) < 0)
63 return;
64 if ((hasframe = vtobool(++a, 1, -1)) < 0)
65 return;
66 if ((mapnl = vtobool(++a, !haspty, -1)) < 0)
67 return;
68 if ((keepopen = vtobool(++a, 0, -1)) < 0)
69 return;
70 if ((smooth = vtobool(++a, default_smooth, -1)) < 0)
71 return;
72 if ((++a)->v_type != V_ERR) {
73 for (pp = argv; a->v_type != V_ERR &&
74 pp < &argv[sizeof argv/sizeof *argv-1]; pp++, a++)
75 *pp = a->v_str;
76 *pp = 0;
77 shf = *(sh = argv);
78 if (*sh = rindex(shf, '/'))
79 (*sh)++;
80 else
81 *sh = shf;
82 } else {
83 sh = default_shell;
84 shf = default_shellfile;
85 }
86 if ((w = openwin(id, row, col, nrow, ncol, nline, label, haspty,
87 hasframe, shf, sh)) == 0)
88 return;
89 w->ww_mapnl = mapnl;
90 w->ww_keepopen = keepopen;
91 w->ww_noupdate = !smooth;
92 v->v_type = V_NUM;
93 v->v_num = id + 1;
94 }
95
96 struct lcmd_arg arg_def_nline[] = {
97 { "nlines", 1, ARG_NUM },
98 0
99 };
100
l_def_nline(v,a)101 l_def_nline(v, a)
102 register struct value *v, *a;
103 {
104 v->v_num = default_nline;
105 v->v_type = V_NUM;
106 if (a->v_type != V_ERR)
107 default_nline = a->v_num;
108 }
109
110 struct lcmd_arg arg_smooth[] = {
111 { "window", 1, ARG_NUM },
112 { "flag", 1, ARG_ANY },
113 0
114 };
115
l_smooth(v,a)116 l_smooth(v, a)
117 register struct value *v, *a;
118 {
119 struct ww *w;
120
121 v->v_type = V_NUM;
122 v->v_num = 0;
123 if ((w = vtowin(a++, selwin)) == 0)
124 return;
125 v->v_num = !w->ww_noupdate;
126 w->ww_noupdate = !vtobool(a, v->v_num, v->v_num);
127 }
128
129 struct lcmd_arg arg_def_smooth[] = {
130 { "flag", 1, ARG_ANY },
131 0
132 };
133
l_def_smooth(v,a)134 l_def_smooth(v, a)
135 register struct value *v, *a;
136 {
137 v->v_type = V_NUM;
138 v->v_num = default_smooth;
139 default_smooth = vtobool(a, v->v_num, v->v_num);
140 }
141
142 struct lcmd_arg arg_select[] = {
143 { "window", 1, ARG_NUM },
144 0
145 };
146
l_select(v,a)147 l_select(v, a)
148 register struct value *v, *a;
149 {
150 struct ww *w;
151
152 v->v_type = V_NUM;
153 v->v_num = selwin ? selwin->ww_id + 1 : -1;
154 if (a->v_type == V_ERR)
155 return;
156 if ((w = vtowin(a, (struct ww *)0)) == 0)
157 return;
158 setselwin(w);
159 }
160
161 struct lcmd_arg arg_debug[] = {
162 { "flag", 1, ARG_ANY },
163 0
164 };
165
l_debug(v,a)166 l_debug(v, a)
167 register struct value *v, *a;
168 {
169 v->v_type = V_NUM;
170 v->v_num = debug;
171 debug = vtobool(a, debug, debug);
172 }
173
174 struct lcmd_arg arg_escape[] = {
175 { "escapec", 1, ARG_STR },
176 0
177 };
178
l_escape(v,a)179 l_escape(v, a)
180 register struct value *v, *a;
181 {
182 char buf[2];
183
184 buf[0] = escapec;
185 buf[1] = 0;
186 if ((v->v_str = str_cpy(buf)) == 0) {
187 error("Out of memory.");
188 return;
189 }
190 v->v_type = V_STR;
191 if (a->v_type != V_ERR)
192 setescape(a->v_str);
193 }
194
195 struct lcmd_arg arg_label[] = {
196 { "window", 1, ARG_NUM },
197 { "label", 1, ARG_STR },
198 0
199 };
200
201 /*ARGSUSED*/
202 l_label(v, a)
203 struct value *v;
204 register struct value *a;
205 {
206 struct ww *w;
207
208 if ((w = vtowin(a, selwin)) == 0)
209 return;
210 if ((++a)->v_type != V_ERR && setlabel(w, a->v_str) < 0)
211 error("Out of memory.");
212 reframe();
213 }
214
215 struct lcmd_arg arg_foreground[] = {
216 { "window", 1, ARG_NUM },
217 { "flag", 1, ARG_ANY },
218 0
219 };
220
l_foreground(v,a)221 l_foreground(v, a)
222 register struct value *v, *a;
223 {
224 struct ww *w;
225 char flag;
226
227 if ((w = vtowin(a, selwin)) == 0)
228 return;
229 v->v_type = V_NUM;
230 v->v_num = isfg(w);
231 flag = vtobool(++a, v->v_num, v->v_num);
232 if (flag == v->v_num)
233 return;
234 deletewin(w);
235 addwin(w, flag);
236 reframe();
237 }
238
239 struct lcmd_arg arg_terse[] = {
240 { "flag", 1, ARG_ANY },
241 0
242 };
243
l_terse(v,a)244 l_terse(v, a)
245 register struct value *v, *a;
246 {
247 v->v_type = V_NUM;
248 v->v_num = terse;
249 setterse(vtobool(a, terse, terse));
250 }
251
252 struct lcmd_arg arg_source[] = {
253 { "filename", 1, ARG_STR },
254 0
255 };
256
l_source(v,a)257 l_source(v, a)
258 register struct value *v, *a;
259 {
260 v->v_type = V_NUM;
261 if (a->v_type != V_ERR && dosource(a->v_str) < 0) {
262 error("Can't open %s.", a->v_str);
263 v->v_num = -1;
264 } else
265 v->v_num = 0;
266 }
267
268 struct lcmd_arg arg_write[] = {
269 { "window", 1, ARG_NUM },
270 { "", 0, ARG_ANY|ARG_LIST },
271 0
272 };
273
274 /*ARGSUSED*/
275 l_write(v, a)
276 struct value *v;
277 register struct value *a;
278 {
279 char buf[20];
280 struct ww *w;
281
282 if ((w = vtowin(a++, selwin)) == 0)
283 return;
284 while (a->v_type != V_ERR) {
285 if (a->v_type == V_NUM) {
286 (void) sprintf(buf, "%d", a->v_num);
287 (void) write(w->ww_pty, buf, strlen(buf));
288 } else
289 (void) write(w->ww_pty, a->v_str, strlen(a->v_str));
290 if ((++a)->v_type != V_ERR)
291 (void) write(w->ww_pty, " ", 1);
292 }
293 }
294
295 struct lcmd_arg arg_close[] = {
296 { "window", 1, ARG_ANY|ARG_LIST },
297 0
298 };
299
300 /*ARGSUSED*/
301 l_close(v, a)
302 struct value *v;
303 register struct value *a;
304 {
305 struct ww *w;
306
307 if (a->v_type == V_STR && str_match(a->v_str, "all", 3))
308 closewin((struct ww *)0);
309 else
310 for (; a->v_type != V_ERR; a++)
311 if ((w = vtowin(a, (struct ww *)0)) != 0)
312 closewin(w);
313 }
314
315 struct lcmd_arg arg_cursormodes[] = {
316 { "modes", 1, ARG_NUM },
317 0
318 };
319
l_cursormodes(v,a)320 l_cursormodes(v, a)
321 register struct value *v, *a;
322 {
323
324 v->v_type = V_NUM;
325 v->v_num = wwcursormodes;
326 if (a->v_type != V_ERR)
327 wwsetcursormodes(a->v_num);
328 }
329
330 struct lcmd_arg arg_unset[] = {
331 { "variable", 1, ARG_ANY },
332 0
333 };
334
l_unset(v,a)335 l_unset(v, a)
336 register struct value *v, *a;
337 {
338 v->v_type = V_NUM;
339 switch (a->v_type) {
340 case V_ERR:
341 v->v_num = -1;
342 return;
343 case V_NUM:
344 if ((a->v_str = str_itoa(a->v_num)) == 0) {
345 error("Out of memory.");
346 v->v_num = -1;
347 return;
348 }
349 a->v_type = V_STR;
350 break;
351 }
352 v->v_num = var_unset(a->v_str);
353 }
354
355 struct ww *
vtowin(v,w)356 vtowin(v, w)
357 register struct value *v;
358 struct ww *w;
359 {
360 switch (v->v_type) {
361 case V_ERR:
362 if (w != 0)
363 return w;
364 error("No window specified.");
365 return 0;
366 case V_STR:
367 error("%s: No such window.", v->v_str);
368 return 0;
369 }
370 if (v->v_num < 1 || v->v_num > NWINDOW
371 || (w = window[v->v_num - 1]) == 0) {
372 error("%d: No such window.", v->v_num);
373 return 0;
374 }
375 return w;
376 }
377
vtobool(v,def,err)378 vtobool(v, def, err)
379 register struct value *v;
380 char def, err;
381 {
382 switch (v->v_type) {
383 case V_NUM:
384 return v->v_num != 0;
385 case V_STR:
386 if (str_match(v->v_str, "true", 1)
387 || str_match(v->v_str, "on", 2)
388 || str_match(v->v_str, "yes", 1))
389 return 1;
390 else if (str_match(v->v_str, "false", 1)
391 || str_match(v->v_str, "off", 2)
392 || str_match(v->v_str, "no", 1))
393 return 0;
394 else {
395 error("%s: Illegal boolean value.", v->v_str);
396 return err;
397 }
398 /*NOTREACHED*/
399 case V_ERR:
400 return def;
401 }
402 /*NOTREACHED*/
403 }
404