1 /* 2 * Copyright (c) 1983 Regents of the University of California. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms are permitted 6 * provided that this notice is preserved and that due credit is given 7 * to the University of California at Berkeley. The name of the University 8 * may not be used to endorse or promote products derived from this 9 * software without specific prior written permission. This software 10 * is provided ``as is'' without express or implied warranty. 11 */ 12 13 #ifndef lint 14 static char sccsid[] = "@(#)lcmd1.c 3.32 (Berkeley) 02/21/88"; 15 #endif /* not lint */ 16 17 #include "defs.h" 18 #include "string.h" 19 #include "value.h" 20 #include "lcmd.h" 21 #include "var.h" 22 23 struct lcmd_arg arg_window[] = { 24 { "row", 1, ARG_NUM }, 25 { "column", 1, ARG_NUM }, 26 { "nrows", 2, ARG_NUM }, 27 { "ncols", 2, ARG_NUM }, 28 { "nlines", 2, ARG_NUM }, 29 { "label", 1, ARG_STR }, 30 { "pty", 1, ARG_ANY }, 31 { "frame", 1, ARG_ANY }, 32 { "mapnl", 1, ARG_ANY }, 33 { "keepopen", 1, ARG_ANY }, 34 { "smooth", 1, ARG_ANY }, 35 { "shell", 1, ARG_STR|ARG_LIST }, 36 0 37 }; 38 39 l_window(v, a) 40 struct value *v; 41 register struct value *a; 42 { 43 struct ww *w; 44 int col, row, ncol, nrow, id, nline; 45 char *label; 46 char haspty, hasframe, mapnl, keepopen, smooth; 47 char *shf, **sh; 48 char *argv[sizeof shell / sizeof *shell]; 49 register char **pp; 50 51 if ((id = findid()) < 0) 52 return; 53 row = a->v_type == V_ERR ? 1 : a->v_num; 54 a++; 55 col = a->v_type == V_ERR ? 0 : a->v_num; 56 a++; 57 nrow = a->v_type == V_ERR ? wwnrow - row : a->v_num; 58 a++; 59 ncol = a->v_type == V_ERR ? wwncol - col : a->v_num; 60 a++; 61 nline = a->v_type == V_ERR ? nbufline : a->v_num; 62 a++; 63 label = a->v_type == V_ERR ? 0 : a->v_str; 64 if ((haspty = vtobool(++a, 1, -1)) < 0) 65 return; 66 if ((hasframe = vtobool(++a, 1, -1)) < 0) 67 return; 68 if ((mapnl = vtobool(++a, !haspty, -1)) < 0) 69 return; 70 if ((keepopen = vtobool(++a, 0, -1)) < 0) 71 return; 72 if ((smooth = vtobool(++a, 1, -1)) < 0) 73 return; 74 if ((++a)->v_type != V_ERR) { 75 for (pp = argv; a->v_type != V_ERR && 76 pp < &argv[sizeof argv/sizeof *argv-1]; pp++, a++) 77 *pp = a->v_str; 78 *pp = 0; 79 shf = *(sh = argv); 80 if (*sh = rindex(shf, '/')) 81 (*sh)++; 82 else 83 *sh = shf; 84 } else { 85 sh = shell; 86 shf = shellfile; 87 } 88 if ((w = openwin(id, row, col, nrow, ncol, nline, label, haspty, 89 hasframe, shf, sh)) == 0) 90 return; 91 w->ww_mapnl = mapnl; 92 w->ww_keepopen = keepopen; 93 w->ww_noupdate = !smooth; 94 v->v_type = V_NUM; 95 v->v_num = id + 1; 96 } 97 98 struct lcmd_arg arg_nline[] = { 99 { "nlines", 1, ARG_NUM }, 100 0 101 }; 102 103 l_nline(v, a) 104 register struct value *v, *a; 105 { 106 v->v_num = nbufline; 107 v->v_type = V_NUM; 108 if (a->v_type != V_ERR) 109 nbufline = a->v_num; 110 } 111 112 struct lcmd_arg arg_smooth[] = { 113 { "window", 1, ARG_NUM }, 114 { "flag", 1, ARG_ANY }, 115 0 116 }; 117 118 l_smooth(v, a) 119 register struct value *v, *a; 120 { 121 struct ww *w; 122 123 v->v_type = V_NUM; 124 v->v_num = 0; 125 if ((w = vtowin(a++, selwin)) == 0) 126 return; 127 v->v_num = !w->ww_noupdate; 128 w->ww_noupdate = !vtobool(a, v->v_num, v->v_num); 129 } 130 131 struct lcmd_arg arg_select[] = { 132 { "window", 1, ARG_NUM }, 133 0 134 }; 135 136 l_select(v, a) 137 register struct value *v, *a; 138 { 139 struct ww *w; 140 141 v->v_type = V_NUM; 142 v->v_num = selwin ? selwin->ww_id + 1 : -1; 143 if (a->v_type == V_ERR) 144 return; 145 if ((w = vtowin(a, (struct ww *)0)) == 0) 146 return; 147 setselwin(w); 148 } 149 150 struct lcmd_arg arg_debug[] = { 151 { "flag", 1, ARG_ANY }, 152 0 153 }; 154 155 l_debug(v, a) 156 register struct value *v, *a; 157 { 158 v->v_type = V_NUM; 159 v->v_num = debug; 160 debug = vtobool(a, debug, debug); 161 } 162 163 struct lcmd_arg arg_escape[] = { 164 { "escapec", 1, ARG_STR }, 165 0 166 }; 167 168 l_escape(v, a) 169 register struct value *v, *a; 170 { 171 char buf[2]; 172 173 buf[0] = escapec; 174 buf[1] = 0; 175 if ((v->v_str = str_cpy(buf)) == 0) { 176 error("Out of memory."); 177 return; 178 } 179 v->v_type = V_STR; 180 if (a->v_type != V_ERR) 181 setescape(a->v_str); 182 } 183 184 struct lcmd_arg arg_label[] = { 185 { "window", 1, ARG_NUM }, 186 { "label", 1, ARG_STR }, 187 0 188 }; 189 190 /*ARGSUSED*/ 191 l_label(v, a) 192 struct value *v; 193 register struct value *a; 194 { 195 struct ww *w; 196 197 if ((w = vtowin(a, selwin)) == 0) 198 return; 199 if ((++a)->v_type != V_ERR && setlabel(w, a->v_str) < 0) 200 error("Out of memory."); 201 reframe(); 202 } 203 204 struct lcmd_arg arg_foreground[] = { 205 { "window", 1, ARG_NUM }, 206 { "flag", 1, ARG_ANY }, 207 0 208 }; 209 210 l_foreground(v, a) 211 register struct value *v, *a; 212 { 213 struct ww *w; 214 char flag; 215 216 if ((w = vtowin(a, selwin)) == 0) 217 return; 218 v->v_type = V_NUM; 219 v->v_num = isfg(w); 220 flag = vtobool(++a, v->v_num, v->v_num); 221 if (flag == v->v_num) 222 return; 223 deletewin(w); 224 addwin(w, flag); 225 reframe(); 226 } 227 228 struct lcmd_arg arg_terse[] = { 229 { "flag", 1, ARG_ANY }, 230 0 231 }; 232 233 l_terse(v, a) 234 register struct value *v, *a; 235 { 236 v->v_type = V_NUM; 237 v->v_num = terse; 238 setterse(vtobool(a, terse, terse)); 239 } 240 241 struct lcmd_arg arg_source[] = { 242 { "filename", 1, ARG_STR }, 243 0 244 }; 245 246 l_source(v, a) 247 register struct value *v, *a; 248 { 249 v->v_type = V_NUM; 250 if (a->v_type != V_ERR && dosource(a->v_str) < 0) { 251 error("Can't open %s.", a->v_str); 252 v->v_num = -1; 253 } else 254 v->v_num = 0; 255 } 256 257 struct lcmd_arg arg_write[] = { 258 { "window", 1, ARG_NUM }, 259 { "", 0, ARG_ANY|ARG_LIST }, 260 0 261 }; 262 263 /*ARGSUSED*/ 264 l_write(v, a) 265 struct value *v; 266 register struct value *a; 267 { 268 char buf[20]; 269 struct ww *w; 270 271 if ((w = vtowin(a++, selwin)) == 0) 272 return; 273 while (a->v_type != V_ERR) { 274 if (a->v_type == V_NUM) { 275 (void) sprintf(buf, "%d", a->v_num); 276 (void) write(w->ww_pty, buf, strlen(buf)); 277 } else 278 (void) write(w->ww_pty, a->v_str, strlen(a->v_str)); 279 if ((++a)->v_type != V_ERR) 280 (void) write(w->ww_pty, " ", 1); 281 } 282 } 283 284 struct lcmd_arg arg_close[] = { 285 { "window", 1, ARG_ANY|ARG_LIST }, 286 0 287 }; 288 289 /*ARGSUSED*/ 290 l_close(v, a) 291 struct value *v; 292 register struct value *a; 293 { 294 struct ww *w; 295 296 if (a->v_type == V_STR && str_match(a->v_str, "all", 3)) 297 closewin((struct ww *)0); 298 else 299 for (; a->v_type != V_ERR; a++) 300 if ((w = vtowin(a, (struct ww *)0)) != 0) 301 closewin(w); 302 } 303 304 struct lcmd_arg arg_cursormodes[] = { 305 { "modes", 1, ARG_NUM }, 306 0 307 }; 308 309 l_cursormodes(v, a) 310 register struct value *v, *a; 311 { 312 313 v->v_type = V_NUM; 314 v->v_num = wwcursormodes; 315 if (a->v_type != V_ERR) 316 wwsetcursormodes(a->v_num); 317 } 318 319 struct lcmd_arg arg_unset[] = { 320 { "variable", 1, ARG_ANY }, 321 0 322 }; 323 324 l_unset(v, a) 325 register struct value *v, *a; 326 { 327 v->v_type = V_NUM; 328 switch (a->v_type) { 329 case V_ERR: 330 v->v_num = -1; 331 return; 332 case V_NUM: 333 if ((a->v_str = str_itoa(a->v_num)) == 0) { 334 error("Out of memory."); 335 v->v_num = -1; 336 return; 337 } 338 a->v_type = V_STR; 339 break; 340 } 341 v->v_num = var_unset(a->v_str); 342 } 343 344 struct ww * 345 vtowin(v, w) 346 register struct value *v; 347 struct ww *w; 348 { 349 switch (v->v_type) { 350 case V_ERR: 351 if (w != 0) 352 return w; 353 error("No window specified."); 354 return 0; 355 case V_STR: 356 error("%s: No such window.", v->v_str); 357 return 0; 358 } 359 if (v->v_num < 1 || v->v_num > NWINDOW 360 || (w = window[v->v_num - 1]) == 0) { 361 error("%d: No such window.", v->v_num); 362 return 0; 363 } 364 return w; 365 } 366 367 vtobool(v, def, err) 368 register struct value *v; 369 char def, err; 370 { 371 switch (v->v_type) { 372 case V_NUM: 373 return v->v_num != 0; 374 case V_STR: 375 if (str_match(v->v_str, "true", 1) 376 || str_match(v->v_str, "on", 2) 377 || str_match(v->v_str, "yes", 1)) 378 return 1; 379 else if (str_match(v->v_str, "false", 1) 380 || str_match(v->v_str, "off", 2) 381 || str_match(v->v_str, "no", 1)) 382 return 0; 383 else { 384 error("%s: Illegal boolean value.", v->v_str); 385 return err; 386 } 387 /*NOTREACHED*/ 388 case V_ERR: 389 return def; 390 } 391 /*NOTREACHED*/ 392 } 393