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 <stdio.h> 42 #include <string.h> /* System string definitions. */ 43 44 #include "defs.h" 45 #include "mystring.h" /* Local string definitions. */ 46 #include "value.h" 47 #include "lcmd.h" 48 #include "var.h" 49 50 struct lcmd_arg arg_window[] = { 51 { "row", 1, ARG_NUM }, 52 { "column", 1, ARG_NUM }, 53 { "nrows", 2, ARG_NUM }, 54 { "ncols", 2, ARG_NUM }, 55 { "nlines", 2, ARG_NUM }, 56 { "label", 1, ARG_STR }, 57 { "pty", 1, ARG_ANY }, 58 { "frame", 1, ARG_ANY }, 59 { "mapnl", 1, ARG_ANY }, 60 { "keepopen", 1, ARG_ANY }, 61 { "smooth", 1, ARG_ANY }, 62 { "shell", 1, ARG_STR|ARG_LIST }, 63 0 64 }; 65 66 l_window(v, a) 67 struct value *v; 68 struct value *a; 69 { 70 struct ww *w; 71 int col, row, ncol, nrow, id, nline; 72 char *label; 73 char haspty, hasframe, mapnl, keepopen, smooth; 74 char *shf, **sh; 75 char *argv[sizeof default_shell / sizeof *default_shell]; 76 char **pp; 77 78 if ((id = findid()) < 0) 79 return; 80 row = a->v_type == V_ERR ? 1 : a->v_num; 81 a++; 82 col = a->v_type == V_ERR ? 0 : a->v_num; 83 a++; 84 nrow = a->v_type == V_ERR ? wwnrow - row : a->v_num; 85 a++; 86 ncol = a->v_type == V_ERR ? wwncol - col : a->v_num; 87 a++; 88 nline = a->v_type == V_ERR ? default_nline : a->v_num; 89 a++; 90 label = a->v_type == V_ERR ? 0 : a->v_str; 91 if ((haspty = vtobool(++a, 1, -1)) < 0) 92 return; 93 if ((hasframe = vtobool(++a, 1, -1)) < 0) 94 return; 95 if ((mapnl = vtobool(++a, !haspty, -1)) < 0) 96 return; 97 if ((keepopen = vtobool(++a, 0, -1)) < 0) 98 return; 99 if ((smooth = vtobool(++a, default_smooth, -1)) < 0) 100 return; 101 if ((++a)->v_type != V_ERR) { 102 for (pp = argv; a->v_type != V_ERR && 103 pp < &argv[sizeof argv/sizeof *argv-1]; pp++, a++) 104 *pp = a->v_str; 105 *pp = 0; 106 shf = *(sh = argv); 107 if (*sh = strrchr(shf, '/')) 108 (*sh)++; 109 else 110 *sh = shf; 111 } else { 112 sh = default_shell; 113 shf = default_shellfile; 114 } 115 if ((w = openwin(id, row, col, nrow, ncol, nline, label, haspty, 116 hasframe, shf, sh)) == 0) 117 return; 118 w->ww_mapnl = mapnl; 119 w->ww_keepopen = keepopen; 120 w->ww_noupdate = !smooth; 121 v->v_type = V_NUM; 122 v->v_num = id + 1; 123 } 124 125 struct lcmd_arg arg_def_nline[] = { 126 { "nlines", 1, ARG_NUM }, 127 0 128 }; 129 130 l_def_nline(v, a) 131 struct value *v, *a; 132 { 133 v->v_num = default_nline; 134 v->v_type = V_NUM; 135 if (a->v_type != V_ERR) 136 default_nline = a->v_num; 137 } 138 139 struct lcmd_arg arg_smooth[] = { 140 { "window", 1, ARG_NUM }, 141 { "flag", 1, ARG_ANY }, 142 0 143 }; 144 145 l_smooth(v, a) 146 struct value *v, *a; 147 { 148 struct ww *w; 149 150 v->v_type = V_NUM; 151 v->v_num = 0; 152 if ((w = vtowin(a++, selwin)) == 0) 153 return; 154 v->v_num = !w->ww_noupdate; 155 w->ww_noupdate = !vtobool(a, v->v_num, v->v_num); 156 } 157 158 struct lcmd_arg arg_def_smooth[] = { 159 { "flag", 1, ARG_ANY }, 160 0 161 }; 162 163 l_def_smooth(v, a) 164 struct value *v, *a; 165 { 166 v->v_type = V_NUM; 167 v->v_num = default_smooth; 168 default_smooth = vtobool(a, v->v_num, v->v_num); 169 } 170 171 struct lcmd_arg arg_select[] = { 172 { "window", 1, ARG_NUM }, 173 0 174 }; 175 176 l_select(v, a) 177 struct value *v, *a; 178 { 179 struct ww *w; 180 181 v->v_type = V_NUM; 182 v->v_num = selwin ? selwin->ww_id + 1 : -1; 183 if (a->v_type == V_ERR) 184 return; 185 if ((w = vtowin(a, NULL)) == 0) 186 return; 187 setselwin(w); 188 } 189 190 struct lcmd_arg arg_debug[] = { 191 { "flag", 1, ARG_ANY }, 192 0 193 }; 194 195 l_debug(v, a) 196 struct value *v, *a; 197 { 198 v->v_type = V_NUM; 199 v->v_num = debug; 200 debug = vtobool(a, debug, debug); 201 } 202 203 struct lcmd_arg arg_escape[] = { 204 { "escapec", 1, ARG_STR }, 205 0 206 }; 207 208 l_escape(v, a) 209 struct value *v, *a; 210 { 211 char buf[2]; 212 213 buf[0] = escapec; 214 buf[1] = 0; 215 if ((v->v_str = str_cpy(buf)) == 0) { 216 error("Out of memory."); 217 return; 218 } 219 v->v_type = V_STR; 220 if (a->v_type != V_ERR) 221 setescape(a->v_str); 222 } 223 224 struct lcmd_arg arg_label[] = { 225 { "window", 1, ARG_NUM }, 226 { "label", 1, ARG_STR }, 227 0 228 }; 229 230 /*ARGSUSED*/ 231 l_label(v, a) 232 struct value *v; 233 struct value *a; 234 { 235 struct ww *w; 236 237 if ((w = vtowin(a, selwin)) == 0) 238 return; 239 if ((++a)->v_type != V_ERR && setlabel(w, a->v_str) < 0) 240 error("Out of memory."); 241 reframe(); 242 } 243 244 struct lcmd_arg arg_foreground[] = { 245 { "window", 1, ARG_NUM }, 246 { "flag", 1, ARG_ANY }, 247 0 248 }; 249 250 l_foreground(v, a) 251 struct value *v, *a; 252 { 253 struct ww *w; 254 char flag; 255 256 if ((w = vtowin(a, selwin)) == 0) 257 return; 258 v->v_type = V_NUM; 259 v->v_num = isfg(w); 260 flag = vtobool(++a, v->v_num, v->v_num); 261 if (flag == v->v_num) 262 return; 263 deletewin(w); 264 addwin(w, flag); 265 reframe(); 266 } 267 268 struct lcmd_arg arg_terse[] = { 269 { "flag", 1, ARG_ANY }, 270 0 271 }; 272 273 l_terse(v, a) 274 struct value *v, *a; 275 { 276 v->v_type = V_NUM; 277 v->v_num = terse; 278 setterse(vtobool(a, terse, terse)); 279 } 280 281 struct lcmd_arg arg_source[] = { 282 { "filename", 1, ARG_STR }, 283 0 284 }; 285 286 l_source(v, a) 287 struct value *v, *a; 288 { 289 v->v_type = V_NUM; 290 if (a->v_type != V_ERR && dosource(a->v_str) < 0) { 291 error("Can't open %s.", a->v_str); 292 v->v_num = -1; 293 } else 294 v->v_num = 0; 295 } 296 297 struct lcmd_arg arg_write[] = { 298 { "window", 1, ARG_NUM }, 299 { "", 0, ARG_ANY|ARG_LIST }, 300 0 301 }; 302 303 /*ARGSUSED*/ 304 l_write(v, a) 305 struct value *v; 306 struct value *a; 307 { 308 char buf[20]; 309 struct ww *w; 310 311 if ((w = vtowin(a++, selwin)) == 0) 312 return; 313 while (a->v_type != V_ERR) { 314 if (a->v_type == V_NUM) { 315 (void) sprintf(buf, "%d", a->v_num); 316 (void) write(w->ww_pty, buf, strlen(buf)); 317 } else 318 (void) write(w->ww_pty, a->v_str, strlen(a->v_str)); 319 if ((++a)->v_type != V_ERR) 320 (void) write(w->ww_pty, " ", 1); 321 } 322 } 323 324 struct lcmd_arg arg_close[] = { 325 { "window", 1, ARG_ANY|ARG_LIST }, 326 0 327 }; 328 329 /*ARGSUSED*/ 330 l_close(v, a) 331 struct value *v; 332 struct value *a; 333 { 334 struct ww *w; 335 336 if (a->v_type == V_STR && str_match(a->v_str, "all", 3)) 337 closewin(NULL); 338 else 339 for (; a->v_type != V_ERR; a++) 340 if ((w = vtowin(a, NULL)) != 0) 341 closewin(w); 342 } 343 344 struct lcmd_arg arg_cursormodes[] = { 345 { "modes", 1, ARG_NUM }, 346 0 347 }; 348 349 l_cursormodes(v, a) 350 struct value *v, *a; 351 { 352 353 v->v_type = V_NUM; 354 v->v_num = wwcursormodes; 355 if (a->v_type != V_ERR) 356 wwsetcursormodes(a->v_num); 357 } 358 359 struct lcmd_arg arg_unset[] = { 360 { "variable", 1, ARG_ANY }, 361 0 362 }; 363 364 l_unset(v, a) 365 struct value *v, *a; 366 { 367 v->v_type = V_NUM; 368 switch (a->v_type) { 369 case V_ERR: 370 v->v_num = -1; 371 return; 372 case V_NUM: 373 if ((a->v_str = str_itoa(a->v_num)) == 0) { 374 error("Out of memory."); 375 v->v_num = -1; 376 return; 377 } 378 a->v_type = V_STR; 379 break; 380 } 381 v->v_num = var_unset(a->v_str); 382 } 383 384 struct ww * 385 vtowin(v, w) 386 struct value *v; 387 struct ww *w; 388 { 389 switch (v->v_type) { 390 case V_ERR: 391 if (w != 0) 392 return w; 393 error("No window specified."); 394 return 0; 395 case V_STR: 396 error("%s: No such window.", v->v_str); 397 return 0; 398 } 399 if (v->v_num < 1 || v->v_num > NWINDOW 400 || (w = window[v->v_num - 1]) == 0) { 401 error("%d: No such window.", v->v_num); 402 return 0; 403 } 404 return w; 405 } 406 407 vtobool(v, def, err) 408 struct value *v; 409 char def, err; 410 { 411 switch (v->v_type) { 412 case V_NUM: 413 return v->v_num != 0; 414 case V_STR: 415 if (str_match(v->v_str, "true", 1) 416 || str_match(v->v_str, "on", 2) 417 || str_match(v->v_str, "yes", 1)) 418 return 1; 419 else if (str_match(v->v_str, "false", 1) 420 || str_match(v->v_str, "off", 2) 421 || str_match(v->v_str, "no", 1)) 422 return 0; 423 else { 424 error("%s: Illegal boolean value.", v->v_str); 425 return err; 426 } 427 /*NOTREACHED*/ 428 case V_ERR: 429 return def; 430 } 431 /*NOTREACHED*/ 432 } 433