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 } 432