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