| Commit | Line | Data |
|---|---|---|
| 2c872e05 | 1 | /* @(#)lcmd1.c 8.1 (Berkeley) 6/6/93 */ |
| abecab39 SW |
2 | /* $NetBSD: lcmd1.c,v 1.11 2006/12/18 20:04:55 christos Exp $ */ |
| 3 | ||
| 984263bc MD |
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. | |
| abecab39 | 19 | * 3. Neither the name of the University nor the names of its contributors |
| 984263bc MD |
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 | ||
| abecab39 SW |
36 | #include <string.h> |
| 37 | #include <unistd.h> | |
| 7a2e9d59 | 38 | #include "defs.h" |
| abecab39 | 39 | #include "window_string.h" |
| 984263bc MD |
40 | #include "lcmd.h" |
| 41 | #include "var.h" | |
| 42 | ||
| abecab39 SW |
43 | char vtobool(struct value *, char, char); |
| 44 | ||
| 984263bc MD |
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 }, | |
| abecab39 | 58 | { NULL, 0, 0 } |
| 984263bc MD |
59 | }; |
| 60 | ||
| abecab39 SW |
61 | void |
| 62 | l_window(struct value *v, struct value *a) | |
| 984263bc MD |
63 | { |
| 64 | struct ww *w; | |
| 65 | int col, row, ncol, nrow, id, nline; | |
| 66 | char *label; | |
| abecab39 | 67 | int haspty, hasframe, mapnl, keepopen, smooth; |
| 984263bc MD |
68 | char *shf, **sh; |
| 69 | char *argv[sizeof default_shell / sizeof *default_shell]; | |
| 1e1668dd | 70 | char **pp; |
| 984263bc MD |
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); | |
| abecab39 | 101 | if ((*sh = strrchr(shf, '/'))) |
| 984263bc MD |
102 | (*sh)++; |
| 103 | else | |
| 104 | *sh = shf; | |
| 105 | } else { | |
| 106 | sh = default_shell; | |
| 107 | shf = default_shellfile; | |
| 108 | } | |
| abecab39 SW |
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) | |
| 984263bc | 112 | return; |
| abecab39 SW |
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); | |
| 984263bc MD |
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 }, | |
| abecab39 | 131 | { NULL, 0, 0 } |
| 984263bc MD |
132 | }; |
| 133 | ||
| abecab39 SW |
134 | void |
| 135 | l_def_nline(struct value *v, struct value *a) | |
| 984263bc MD |
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 }, | |
| abecab39 | 146 | { NULL, 0, 0 } |
| 984263bc MD |
147 | }; |
| 148 | ||
| abecab39 SW |
149 | void |
| 150 | l_smooth(struct value *v, struct value *a) | |
| 984263bc MD |
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; | |
| abecab39 SW |
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); | |
| 984263bc MD |
163 | } |
| 164 | ||
| 165 | struct lcmd_arg arg_def_smooth[] = { | |
| 166 | { "flag", 1, ARG_ANY }, | |
| abecab39 | 167 | { NULL, 0, 0 } |
| 984263bc MD |
168 | }; |
| 169 | ||
| abecab39 SW |
170 | void |
| 171 | l_def_smooth(struct value *v, struct value *a) | |
| 984263bc MD |
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 }, | |
| abecab39 | 180 | { NULL, 0, 0 } |
| 984263bc MD |
181 | }; |
| 182 | ||
| abecab39 SW |
183 | void |
| 184 | l_select(struct value *v, struct value *a) | |
| 984263bc MD |
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; | |
| abecab39 | 192 | if ((w = vtowin(a, (struct ww *)0)) == 0) |
| 984263bc MD |
193 | return; |
| 194 | setselwin(w); | |
| 195 | } | |
| 196 | ||
| 197 | struct lcmd_arg arg_debug[] = { | |
| 198 | { "flag", 1, ARG_ANY }, | |
| abecab39 | 199 | { NULL, 0, 0 } |
| 984263bc MD |
200 | }; |
| 201 | ||
| abecab39 SW |
202 | void |
| 203 | l_debug(struct value *v, struct value *a) | |
| 984263bc MD |
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 }, | |
| abecab39 | 212 | { NULL, 0, 0 } |
| 984263bc MD |
213 | }; |
| 214 | ||
| abecab39 SW |
215 | void |
| 216 | l_escape(struct value *v, struct value *a) | |
| 984263bc MD |
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 }, | |
| abecab39 | 234 | { NULL, 0, 0 } |
| 984263bc MD |
235 | }; |
| 236 | ||
| abecab39 SW |
237 | void |
| 238 | l_label(struct value *v __unused, struct value *a) | |
| 984263bc MD |
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 }, | |
| abecab39 | 252 | { NULL, 0, 0 } |
| 984263bc MD |
253 | }; |
| 254 | ||
| abecab39 SW |
255 | void |
| 256 | l_foreground(struct value *v, struct value *a) | |
| 984263bc MD |
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 }, | |
| abecab39 | 275 | { NULL, 0, 0 } |
| 984263bc MD |
276 | }; |
| 277 | ||
| abecab39 SW |
278 | void |
| 279 | l_terse(struct value *v, struct value *a) | |
| 984263bc MD |
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 }, | |
| abecab39 | 288 | { NULL, 0, 0 } |
| 984263bc MD |
289 | }; |
| 290 | ||
| abecab39 SW |
291 | void |
| 292 | l_source(struct value *v, struct value *a) | |
| 984263bc MD |
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 }, | |
| abecab39 | 305 | { NULL, 0, 0 } |
| 984263bc MD |
306 | }; |
| 307 | ||
| abecab39 SW |
308 | void |
| 309 | l_write(struct value *v __unused, struct value *a) | |
| 984263bc MD |
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 }, | |
| abecab39 | 329 | { NULL, 0, 0 } |
| 984263bc MD |
330 | }; |
| 331 | ||
| abecab39 SW |
332 | void |
| 333 | l_close(struct value *v __unused, struct value *a) | |
| 984263bc MD |
334 | { |
| 335 | struct ww *w; | |
| 336 | ||
| 337 | if (a->v_type == V_STR && str_match(a->v_str, "all", 3)) | |
| abecab39 | 338 | closewin((struct ww *)0); |
| 984263bc MD |
339 | else |
| 340 | for (; a->v_type != V_ERR; a++) | |
| abecab39 | 341 | if ((w = vtowin(a, (struct ww *)0)) != 0) |
| 984263bc MD |
342 | closewin(w); |
| 343 | } | |
| 344 | ||
| 345 | struct lcmd_arg arg_cursormodes[] = { | |
| 346 | { "modes", 1, ARG_NUM }, | |
| abecab39 | 347 | { NULL, 0, 0 } |
| 984263bc MD |
348 | }; |
| 349 | ||
| abecab39 SW |
350 | void |
| 351 | l_cursormodes(struct value *v, struct value *a) | |
| 984263bc MD |
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 }, | |
| abecab39 | 362 | { NULL, 0, 0 } |
| 984263bc MD |
363 | }; |
| 364 | ||
| abecab39 SW |
365 | void |
| 366 | l_unset(struct value *v, struct value *a) | |
| 984263bc MD |
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 * | |
| abecab39 | 386 | vtowin(struct value *v, struct ww *w) |
| 984263bc MD |
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 | ||
| abecab39 SW |
406 | char |
| 407 | vtobool(struct value *v, char def, char err) | |
| 984263bc MD |
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*/ | |
| abecab39 | 430 | return (0); |
| 984263bc | 431 | } |