1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 23 /* All Rights Reserved */ 24 25 26 /* Copyright (c) 1981 Regents of the University of California */ 27 #ident "%Z%%M% %I% %E% SMI" /* SVr4.0 1.14 */ 28 29 #include "ex.h" 30 #include "ex_temp.h" 31 #include "ex_tty.h" 32 33 /* 34 * Set command. 35 */ 36 unsigned char optname[ONMSZ]; 37 38 set() 39 { 40 register unsigned char *cp; 41 register struct option *op; 42 register int c; 43 bool no; 44 extern short ospeed; 45 #ifdef TRACE 46 int k, label; 47 line *tmpadr; 48 #endif 49 50 setnoaddr(); 51 if (skipend()) { 52 if (peekchar() != EOF) 53 ignchar(); 54 propts(); 55 return; 56 } 57 do { 58 cp = optname; 59 do { 60 if (cp < &optname[ONMSZ - 2]) 61 *cp++ = getchar(); 62 } while (isalnum(peekchar())); 63 *cp = 0; 64 cp = optname; 65 if (eq("all", cp)) { 66 if (inopen) 67 pofix(); 68 prall(); 69 goto next; 70 } 71 no = 0; 72 #ifdef TRACE 73 /* 74 * General purpose test code for looking at address of those 75 * invisible marks (as well as the visible ones). 76 */ 77 if (eq("marks",cp)) { 78 printf("Marks Address\n\r"); 79 printf(" \n"); 80 printf("\n"); 81 for (k=0; k<=25; k++) 82 printf("Mark:%c\t%d\n",k+'a',names[k]); 83 goto next; 84 } 85 86 /* 87 * General purpose test code for looking at 88 * named registers. 89 */ 90 91 if (eq("named",cp)) { 92 if (inopen) 93 pofix(); 94 shownam(); 95 goto next; 96 } 97 98 /* 99 * General purpose test code for looking at 100 * numbered registers. 101 */ 102 103 if (eq("nbrreg",cp)) { 104 if (inopen) 105 pofix(); 106 shownbr(); 107 goto next; 108 } 109 110 /* 111 * General purpose test code for looking at addresses 112 * in the edit and save areas of VI. 113 */ 114 115 if (eq("buffers",cp)) { 116 if (inopen) 117 pofix(); 118 printf("\nLabels Address Contents\n"); 119 printf("====== ======= ========"); 120 for (tmpadr = zero; tmpadr <= dol; tmpadr++) { 121 label =0; 122 if (tmpadr == zero) { 123 printf("ZERO:\t"); 124 label = 2; 125 } 126 if (tmpadr == one) { 127 if (label > 0) 128 printf("\nONE:\t"); 129 else 130 printf("ONE:\t"); 131 label = 1; 132 } 133 if (tmpadr == dot) { 134 if (label > 0) 135 printf("\nDOT:\t"); 136 else 137 printf("DOT:\t"); 138 label = 1; 139 } 140 if (tmpadr == undap1) { 141 if (label > 0) 142 printf("\nUNDAP1:\t"); 143 else 144 printf("UNDAP1:\t"); 145 label = 1; 146 } 147 if (tmpadr == undap2) { 148 if (label > 0) 149 printf("\nUNDAP2:\t"); 150 else 151 printf("UNDAP2:\t"); 152 label = 1; 153 } 154 if (tmpadr == unddel) { 155 if (label > 0) 156 printf("\nUNDDEL:\t"); 157 else 158 printf("UNDDEL:\t"); 159 label = 1; 160 } 161 if (tmpadr == dol) { 162 if (label > 0) 163 printf("\nDOL:\t"); 164 else 165 printf("DOL:\t"); 166 label = 1; 167 } 168 for (k=0; k<=25; k++) 169 if (names[k] == (*tmpadr &~ 01)) { 170 if (label > 0) 171 printf("\nMark:%c\t%d\t",k+'a',names[k]); 172 else 173 printf("Mark:%c\t%d\t",k+'a',names[k]); 174 label=1; 175 } 176 if (label == 0) 177 continue; 178 179 if (label == 2) 180 printf("%d\n",tmpadr); 181 else { 182 printf("%d\t",tmpadr); 183 getline(*tmpadr); 184 pline(lineno(tmpadr)); 185 putchar('\n'); 186 } 187 } 188 189 for (tmpadr = dol+1; tmpadr <= unddol; tmpadr++) { 190 label =0; 191 if (tmpadr == dol+1) { 192 printf("DOL+1:\t"); 193 label = 1; 194 } 195 if (tmpadr == unddel) { 196 if (label > 0) 197 printf("\nUNDDEL:\t"); 198 else 199 printf("UNDDEL:\t"); 200 label = 1; 201 } 202 if (tmpadr == unddol) { 203 if (label > 0) 204 printf("\nUNDDOL:\t"); 205 else 206 printf("UNDDOL:\t"); 207 label = 1; 208 } 209 for (k=0; k<=25; k++) 210 if (names[k] == (*tmpadr &~ 01)) { 211 if (label > 0) 212 printf("\nMark:%c\t%d\t",k+'a',names[k]); 213 else 214 printf("Mark:%c\t%d\t",k+'a',names[k]); 215 label=1; 216 } 217 if (label == 0) 218 continue; 219 if (label == 2) 220 printf("%d\n",tmpadr); 221 else { 222 printf("%d\t",tmpadr); 223 getline(*tmpadr); 224 pline(lineno(tmpadr)); 225 putchar('\n'); 226 } 227 } 228 goto next; 229 } 230 #endif 231 if (cp[0] == 'n' && cp[1] == 'o' && cp[2] != 'v') { 232 cp += 2; 233 no++; 234 } 235 /* Implement w300, w1200, and w9600 specially */ 236 if (eq(cp, "w300")) { 237 if (ospeed >= B1200) { 238 dontset: 239 (void)getchar(); /* = */ 240 (void)getnum(); /* value */ 241 continue; 242 } 243 cp = (unsigned char *)"window"; 244 } else if (eq(cp, "w1200")) { 245 if (ospeed < B1200 || ospeed >= B2400) 246 goto dontset; 247 cp = (unsigned char *)"window"; 248 } else if (eq(cp, "w9600")) { 249 if (ospeed < B2400) 250 goto dontset; 251 cp = (unsigned char *)"window"; 252 } 253 for (op = options; op < &options[vi_NOPTS]; op++) 254 if (eq(op->oname, cp) || op->oabbrev && eq(op->oabbrev, cp)) 255 break; 256 if (op->oname == 0) 257 serror(value(vi_TERSE) ? gettext("%s: No such option") : 258 gettext("%s: No such option - 'set all' gives all option values"), cp); 259 c = skipwh(); 260 if (peekchar() == '?') { 261 ignchar(); 262 printone: 263 propt(op); 264 noonl(); 265 goto next; 266 } 267 if (op->otype == ONOFF) { 268 op->ovalue = 1 - no; 269 if (op == &options[vi_PROMPT]) 270 oprompt = 1 - no; 271 goto next; 272 } 273 if (no) 274 serror(gettext("Option %s is not a toggle"), op->oname); 275 if (c != 0 || setend()) 276 goto printone; 277 if (getchar() != '=') 278 serror(value(vi_TERSE) ? gettext("Missing =") : 279 gettext("Missing = in assignment to option %s"), op->oname); 280 switch (op->otype) { 281 282 case NUMERIC: 283 if (!isdigit(peekchar())) 284 error(value(vi_TERSE) ? 285 gettext("Digits required") : gettext("Digits required after =")); 286 op->ovalue = getnum(); 287 if (value(vi_TABSTOP) <= 0) 288 value(vi_TABSTOP) = TABS; 289 if (op == &options[vi_WINDOW]) { 290 if (value(vi_WINDOW) >= lines) 291 value(vi_WINDOW) = lines-1; 292 vsetsiz(value(vi_WINDOW)); 293 } 294 break; 295 296 case STRING: 297 case OTERM: 298 cp = optname; 299 while (!setend()) { 300 if (cp >= &optname[ONMSZ]) 301 error(value(vi_TERSE) ? 302 gettext("String too long") : gettext("String too long in option assignment")); 303 /* adb change: allow whitepace in strings */ 304 if( (*cp = getchar()) == '\\') 305 if( peekchar() != EOF) 306 *cp = getchar(); 307 cp++; 308 } 309 *cp = 0; 310 if (op->otype == OTERM) { 311 /* 312 * At first glance it seems like we shouldn't care if the terminal type 313 * is changed inside visual mode, as long as we assume the screen is 314 * a mess and redraw it. However, it's a much harder problem than that. 315 * If you happen to change from 1 crt to another that both have the same 316 * size screen, it's OK. But if the screen size if different, the stuff 317 * that gets initialized in vop() will be wrong. This could be overcome 318 * by redoing the initialization, e.g. making the first 90% of vop into 319 * a subroutine. However, the most useful case is where you forgot to do 320 * a setenv before you went into the editor and it thinks you're on a dumb 321 * terminal. Ex treats this like hardcopy and goes into HARDOPEN mode. 322 * This loses because the first part of vop calls oop in this case. 323 */ 324 if (inopen) 325 error(gettext("Can't change type of terminal from within open/visual")); 326 unterm(); 327 setterm(optname); 328 } else { 329 CP(op->osvalue, optname); 330 op->odefault = 1; 331 } 332 break; 333 } 334 next: 335 flush(); 336 } while (!skipend()); 337 eol(); 338 } 339 340 unterm() 341 { 342 /* 343 * All terminal mapped statements must be deleted. 344 * All user-defined mapped statements, cap=descr, 345 * are left unchanged. 346 */ 347 348 int i; 349 350 for (i=0; i < MAXNOMACS; i++) { 351 352 /* 353 * Unmap any terminal-defined arrow keys 354 */ 355 356 if (arrows[i].cap && arrows[i].descr && 357 strcmp(arrows[i].cap, arrows[i].descr)) 358 addmac(arrows[i].cap, NOSTR, NOSTR, arrows); 359 360 /* 361 * Unmap any terminal-defined function keys 362 */ 363 364 if (immacs[i].cap && immacs[i].descr && strcmp(immacs[i].cap, immacs[i].descr)) 365 addmac(immacs[i].cap, NOSTR, NOSTR, immacs); 366 367 } 368 } 369 370 371 setend() 372 { 373 374 return (iswhite(peekchar()) || endcmd(peekchar())); 375 } 376 377 prall() 378 { 379 register int incr = (vi_NOPTS + 2) / 3; 380 register int rows = incr; 381 register struct option *op = options; 382 383 for (; rows; rows--, op++) { 384 propt(op); 385 gotab(24); 386 propt(&op[incr]); 387 if (&op[2*incr] < &options[vi_NOPTS]) { 388 gotab(56); 389 propt(&op[2 * incr]); 390 } 391 putNFL(); 392 } 393 } 394 395 propts() 396 { 397 register struct option *op; 398 399 for (op = options; op < &options[vi_NOPTS]; op++) { 400 if (op == &options[vi_TTYTYPE]) 401 continue; 402 switch (op->otype) { 403 404 case ONOFF: 405 case NUMERIC: 406 if (op->ovalue == op->odefault) 407 continue; 408 break; 409 410 case STRING: 411 if (op->odefault == 0) 412 continue; 413 break; 414 } 415 propt(op); 416 putchar(' '); 417 } 418 noonl(); 419 flush(); 420 } 421 422 propt(op) 423 register struct option *op; 424 { 425 register unsigned char *name; 426 427 name = (unsigned char *)op->oname; 428 429 switch (op->otype) { 430 431 case ONOFF: 432 printf("%s%s", op->ovalue ? "" : "no", name); 433 break; 434 435 case NUMERIC: 436 printf("%s=%d", name, op->ovalue); 437 break; 438 439 case STRING: 440 case OTERM: 441 printf("%s=%s", name, op->osvalue); 442 break; 443 } 444 } 445