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.3 2004/08/30 18:06:50 eirikn 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 register 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 register 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 register 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 register 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 register 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 register 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 register 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 register 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 register 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 register 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 register 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 register 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 register 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 register 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 register 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 register 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 register 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 register 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 } 431