Merge from vendor branch LIBEVENT:
[dragonfly.git] / usr.bin / window / lcmd1.c
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  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  * 3. All advertising materials mentioning features or use of this software
17  *    must display the following acknowledgement:
18  *      This product includes software developed by the University of
19  *      California, Berkeley and its contributors.
20  * 4. Neither the name of the University nor the names of its contributors
21  *    may be used to endorse or promote products derived from this software
22  *    without specific prior written permission.
23  *
24  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34  * SUCH DAMAGE.
35  *
36  * @(#)lcmd1.c  8.1 (Berkeley) 6/6/93
37  * $FreeBSD: src/usr.bin/window/lcmd1.c,v 1.2.6.2 2001/05/17 09:45:00 obrien Exp $
38  * $DragonFly: src/usr.bin/window/lcmd1.c,v 1.4 2005/04/15 17:55:29 drhodus Exp $
39  */
40
41 #include "defs.h"
42 #include <string.h> /* System string definitions. */
43 #include "mystring.h" /* Local string definitions. */
44 #include "value.h"
45 #include "lcmd.h"
46 #include "var.h"
47
48 struct lcmd_arg arg_window[] = {
49         { "row",        1,      ARG_NUM },
50         { "column",     1,      ARG_NUM },
51         { "nrows",      2,      ARG_NUM },
52         { "ncols",      2,      ARG_NUM },
53         { "nlines",     2,      ARG_NUM },
54         { "label",      1,      ARG_STR },
55         { "pty",        1,      ARG_ANY },
56         { "frame",      1,      ARG_ANY },
57         { "mapnl",      1,      ARG_ANY },
58         { "keepopen",   1,      ARG_ANY },
59         { "smooth",     1,      ARG_ANY },
60         { "shell",      1,      ARG_STR|ARG_LIST },
61         0
62 };
63
64 l_window(v, a)
65 struct value *v;
66 struct value *a;
67 {
68         struct ww *w;
69         int col, row, ncol, nrow, id, nline;
70         char *label;
71         char haspty, hasframe, mapnl, keepopen, smooth;
72         char *shf, **sh;
73         char *argv[sizeof default_shell / sizeof *default_shell];
74         char **pp;
75
76         if ((id = findid()) < 0)
77                 return;
78         row = a->v_type == V_ERR ? 1 : a->v_num;
79         a++;
80         col = a->v_type == V_ERR ? 0 : a->v_num;
81         a++;
82         nrow = a->v_type == V_ERR ? wwnrow - row : a->v_num;
83         a++;
84         ncol = a->v_type == V_ERR ? wwncol - col : a->v_num;
85         a++;
86         nline = a->v_type == V_ERR ? default_nline : a->v_num;
87         a++;
88         label = a->v_type == V_ERR ? 0 : a->v_str;
89         if ((haspty = vtobool(++a, 1, -1)) < 0)
90                 return;
91         if ((hasframe = vtobool(++a, 1, -1)) < 0)
92                 return;
93         if ((mapnl = vtobool(++a, !haspty, -1)) < 0)
94                 return;
95         if ((keepopen = vtobool(++a, 0, -1)) < 0)
96                 return;
97         if ((smooth = vtobool(++a, default_smooth, -1)) < 0)
98                 return;
99         if ((++a)->v_type != V_ERR) {
100                 for (pp = argv; a->v_type != V_ERR &&
101                      pp < &argv[sizeof argv/sizeof *argv-1]; pp++, a++)
102                         *pp = a->v_str;
103                 *pp = 0;
104                 shf = *(sh = argv);
105                 if (*sh = strrchr(shf, '/'))
106                         (*sh)++;
107                 else
108                         *sh = shf;
109         } else {
110                 sh = default_shell;
111                 shf = default_shellfile;
112         }
113         if ((w = openwin(id, row, col, nrow, ncol, nline, label, haspty,
114             hasframe, shf, sh)) == 0)
115                 return;
116         w->ww_mapnl = mapnl;
117         w->ww_keepopen = keepopen;
118         w->ww_noupdate = !smooth;
119         v->v_type = V_NUM;
120         v->v_num = id + 1;
121 }
122
123 struct lcmd_arg arg_def_nline[] = {
124         { "nlines",     1,      ARG_NUM },
125         0
126 };
127
128 l_def_nline(v, a)
129 struct value *v, *a;
130 {
131         v->v_num = default_nline;
132         v->v_type = V_NUM;
133         if (a->v_type != V_ERR)
134                 default_nline = a->v_num;
135 }
136
137 struct lcmd_arg arg_smooth[] = {
138         { "window",     1,      ARG_NUM },
139         { "flag",       1,      ARG_ANY },
140         0
141 };
142
143 l_smooth(v, a)
144 struct value *v, *a;
145 {
146         struct ww *w;
147
148         v->v_type = V_NUM;
149         v->v_num = 0;
150         if ((w = vtowin(a++, selwin)) == 0)
151                 return;
152         v->v_num = !w->ww_noupdate;
153         w->ww_noupdate = !vtobool(a, v->v_num, v->v_num);
154 }
155
156 struct lcmd_arg arg_def_smooth[] = {
157         { "flag",       1,      ARG_ANY },
158         0
159 };
160
161 l_def_smooth(v, a)
162 struct value *v, *a;
163 {
164         v->v_type = V_NUM;
165         v->v_num = default_smooth;
166         default_smooth = vtobool(a, v->v_num, v->v_num);
167 }
168
169 struct lcmd_arg arg_select[] = {
170         { "window",     1,      ARG_NUM },
171         0
172 };
173
174 l_select(v, a)
175 struct value *v, *a;
176 {
177         struct ww *w;
178
179         v->v_type = V_NUM;
180         v->v_num = selwin ? selwin->ww_id + 1 : -1;
181         if (a->v_type == V_ERR)
182                 return;
183         if ((w = vtowin(a, (struct ww *)0)) == 0)
184                 return;
185         setselwin(w);
186 }
187
188 struct lcmd_arg arg_debug[] = {
189         { "flag",       1,      ARG_ANY },
190         0
191 };
192
193 l_debug(v, a)
194 struct value *v, *a;
195 {
196         v->v_type = V_NUM;
197         v->v_num = debug;
198         debug = vtobool(a, debug, debug);
199 }
200
201 struct lcmd_arg arg_escape[] = {
202         { "escapec",    1,      ARG_STR },
203         0
204 };
205
206 l_escape(v, a)
207 struct value *v, *a;
208 {
209         char buf[2];
210
211         buf[0] = escapec;
212         buf[1] = 0;
213         if ((v->v_str = str_cpy(buf)) == 0) {
214                 error("Out of memory.");
215                 return;
216         }
217         v->v_type = V_STR;
218         if (a->v_type != V_ERR)
219                 setescape(a->v_str);
220 }
221
222 struct lcmd_arg arg_label[] = {
223         { "window",     1,      ARG_NUM },
224         { "label",      1,      ARG_STR },
225         0
226 };
227
228 /*ARGSUSED*/
229 l_label(v, a)
230 struct value *v;
231 struct value *a;
232 {
233         struct ww *w;
234
235         if ((w = vtowin(a, selwin)) == 0)
236                 return;
237         if ((++a)->v_type != V_ERR && setlabel(w, a->v_str) < 0)
238                 error("Out of memory.");
239         reframe();
240 }
241
242 struct lcmd_arg arg_foreground[] = {
243         { "window",     1,      ARG_NUM },
244         { "flag",       1,      ARG_ANY },
245         0
246 };
247
248 l_foreground(v, a)
249 struct value *v, *a;
250 {
251         struct ww *w;
252         char flag;
253
254         if ((w = vtowin(a, selwin)) == 0)
255                 return;
256         v->v_type = V_NUM;
257         v->v_num = isfg(w);
258         flag = vtobool(++a, v->v_num, v->v_num);
259         if (flag == v->v_num)
260                 return;
261         deletewin(w);
262         addwin(w, flag);
263         reframe();
264 }
265
266 struct lcmd_arg arg_terse[] = {
267         { "flag",       1,      ARG_ANY },
268         0
269 };
270
271 l_terse(v, a)
272 struct value *v, *a;
273 {
274         v->v_type = V_NUM;
275         v->v_num = terse;
276         setterse(vtobool(a, terse, terse));
277 }
278
279 struct lcmd_arg arg_source[] = {
280         { "filename",   1,      ARG_STR },
281         0
282 };
283
284 l_source(v, a)
285 struct value *v, *a;
286 {
287         v->v_type = V_NUM;
288         if (a->v_type != V_ERR && dosource(a->v_str) < 0) {
289                 error("Can't open %s.", a->v_str);
290                 v->v_num = -1;
291         } else
292                 v->v_num = 0;
293 }
294
295 struct lcmd_arg arg_write[] = {
296         { "window",     1,      ARG_NUM },
297         { "",           0,      ARG_ANY|ARG_LIST },
298         0
299 };
300
301 /*ARGSUSED*/
302 l_write(v, a)
303 struct value *v;
304 struct value *a;
305 {
306         char buf[20];
307         struct ww *w;
308
309         if ((w = vtowin(a++, selwin)) == 0)
310                 return;
311         while (a->v_type != V_ERR) {
312                 if (a->v_type == V_NUM) {
313                         (void) sprintf(buf, "%d", a->v_num);
314                         (void) write(w->ww_pty, buf, strlen(buf));
315                 } else
316                         (void) write(w->ww_pty, a->v_str, strlen(a->v_str));
317                 if ((++a)->v_type != V_ERR)
318                         (void) write(w->ww_pty, " ", 1);
319         }
320 }
321
322 struct lcmd_arg arg_close[] = {
323         { "window",     1,      ARG_ANY|ARG_LIST },
324         0
325 };
326
327 /*ARGSUSED*/
328 l_close(v, a)
329 struct value *v;
330 struct value *a;
331 {
332         struct ww *w;
333
334         if (a->v_type == V_STR && str_match(a->v_str, "all", 3))
335                 closewin((struct ww *)0);
336         else
337                 for (; a->v_type != V_ERR; a++)
338                         if ((w = vtowin(a, (struct ww *)0)) != 0)
339                                 closewin(w);
340 }
341
342 struct lcmd_arg arg_cursormodes[] = {
343         { "modes",      1,      ARG_NUM },
344         0
345 };
346
347 l_cursormodes(v, a)
348 struct value *v, *a;
349 {
350
351         v->v_type = V_NUM;
352         v->v_num = wwcursormodes;
353         if (a->v_type != V_ERR)
354                 wwsetcursormodes(a->v_num);
355 }
356
357 struct lcmd_arg arg_unset[] = {
358         { "variable",   1,      ARG_ANY },
359         0
360 };
361
362 l_unset(v, a)
363 struct value *v, *a;
364 {
365         v->v_type = V_NUM;
366         switch (a->v_type) {
367         case V_ERR:
368                 v->v_num = -1;
369                 return;
370         case V_NUM:
371                 if ((a->v_str = str_itoa(a->v_num)) == 0) {
372                         error("Out of memory.");
373                         v->v_num = -1;
374                         return;
375                 }
376                 a->v_type = V_STR;
377                 break;
378         }
379         v->v_num = var_unset(a->v_str);
380 }
381
382 struct ww *
383 vtowin(v, w)
384 struct value *v;
385 struct ww *w;
386 {
387         switch (v->v_type) {
388         case V_ERR:
389                 if (w != 0)
390                         return w;
391                 error("No window specified.");
392                 return 0;
393         case V_STR:
394                 error("%s: No such window.", v->v_str);
395                 return 0;
396         }
397         if (v->v_num < 1 || v->v_num > NWINDOW
398             || (w = window[v->v_num - 1]) == 0) {
399                 error("%d: No such window.", v->v_num);
400                 return 0;
401         }
402         return w;
403 }
404
405 vtobool(v, def, err)
406 struct value *v;
407 char def, err;
408 {
409         switch (v->v_type) {
410         case V_NUM:
411                 return v->v_num != 0;
412         case V_STR:
413                 if (str_match(v->v_str, "true", 1)
414                     || str_match(v->v_str, "on", 2)
415                     || str_match(v->v_str, "yes", 1))
416                         return 1;
417                 else if (str_match(v->v_str, "false", 1)
418                     || str_match(v->v_str, "off", 2)
419                     || str_match(v->v_str, "no", 1))
420                         return 0;
421                 else {
422                         error("%s: Illegal boolean value.", v->v_str);
423                         return err;
424                 }
425                 /*NOTREACHED*/
426         case V_ERR:
427                 return def;
428         }
429         /*NOTREACHED*/
430 }