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