1 /*- 2 * Copyright (c) 1980, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * %sccs.include.proprietary.c% 6 */ 7 8 #ifndef lint 9 static char sccsid[] = "@(#)ex_set.c 8.1 (Berkeley) 06/09/93"; 10 #endif /* not lint */ 11 12 #include "ex.h" 13 #include "ex_temp.h" 14 #include "ex_tty.h" 15 16 /* 17 * Set command. 18 */ 19 char optname[ONMSZ]; 20 21 set() 22 { 23 register char *cp; 24 register struct option *op; 25 register int c; 26 bool no; 27 extern short ospeed; 28 29 setnoaddr(); 30 if (skipend()) { 31 if (peekchar() != EOF) 32 ignchar(); 33 propts(); 34 return; 35 } 36 do { 37 cp = optname; 38 do { 39 if (cp < &optname[ONMSZ - 2]) 40 *cp++ = ex_getchar(); 41 } while (isalnum(peekchar())); 42 *cp = 0; 43 cp = optname; 44 if (eq("all", cp)) { 45 if (inopen) 46 pofix(); 47 prall(); 48 goto next; 49 } 50 no = 0; 51 if (cp[0] == 'n' && cp[1] == 'o') { 52 cp += 2; 53 no++; 54 } 55 /* Implement w300, w1200, and w9600 specially */ 56 if (eq(cp, "w300")) { 57 if (ospeed >= B1200) { 58 dontset: 59 ignore(ex_getchar()); /* = */ 60 ignore(getnum()); /* value */ 61 continue; 62 } 63 cp = "window"; 64 } else if (eq(cp, "w1200")) { 65 if (ospeed < B1200 || ospeed >= B2400) 66 goto dontset; 67 cp = "window"; 68 } else if (eq(cp, "w9600")) { 69 if (ospeed < B2400) 70 goto dontset; 71 cp = "window"; 72 } 73 for (op = options; op < &options[NOPTS]; op++) 74 if (eq(op->oname, cp) || op->oabbrev && eq(op->oabbrev, cp)) 75 break; 76 if (op->oname == 0) 77 serror("%s: No such option@- 'set all' gives all option values", cp); 78 c = skipwh(); 79 if (peekchar() == '?') { 80 ignchar(); 81 printone: 82 propt(op); 83 noonl(); 84 goto next; 85 } 86 if (op->otype == ONOFF) { 87 op->ovalue = 1 - no; 88 if (op == &options[PROMPT]) 89 oprompt = 1 - no; 90 goto next; 91 } 92 if (no) 93 serror("Option %s is not a toggle", op->oname); 94 if (c != 0 || setend()) 95 goto printone; 96 if (ex_getchar() != '=') 97 serror("Missing =@in assignment to option %s", op->oname); 98 switch (op->otype) { 99 100 case NUMERIC: 101 if (!isdigit(peekchar())) 102 error("Digits required@after ="); 103 op->ovalue = getnum(); 104 if (value(TABSTOP) <= 0) 105 value(TABSTOP) = TABS; 106 if (value(HARDTABS) <= 0) 107 value(HARDTABS) = TABS; 108 if (op == &options[WINDOW]) { 109 if (value(WINDOW) >= LINES) 110 value(WINDOW) = LINES-1; 111 vsetsiz(value(WINDOW)); 112 } 113 break; 114 115 case STRING: 116 case OTERM: 117 cp = optname; 118 while (!setend()) { 119 if (cp >= &optname[ONMSZ]) 120 error("String too long@in option assignment"); 121 /* adb change: allow whitepace in strings */ 122 if( (*cp = ex_getchar()) == '\\') 123 if( peekchar() != EOF) 124 *cp = ex_getchar(); 125 cp++; 126 } 127 *cp = 0; 128 if (op->otype == OTERM) { 129 /* 130 * At first glance it seems like we shouldn't care if the terminal type 131 * is changed inside visual mode, as long as we assume the screen is 132 * a mess and redraw it. However, it's a much harder problem than that. 133 * If you happen to change from 1 crt to another that both have the same 134 * size screen, it's OK. But if the screen size if different, the stuff 135 * that gets initialized in vop() will be wrong. This could be overcome 136 * by redoing the initialization, e.g. making the first 90% of vop into 137 * a subroutine. However, the most useful case is where you forgot to do 138 * a setenv before you went into the editor and it thinks you're on a dumb 139 * terminal. Ex treats this like hardcopy and goes into HARDOPEN mode. 140 * This loses because the first part of vop calls oop in this case. 141 * The problem is so hard I gave up. I'm not saying it can't be done, 142 * but I am saying it probably isn't worth the effort. 143 */ 144 if (inopen) 145 error("Can't change type of terminal from within open/visual"); 146 setterm(optname); 147 } else { 148 CP(op->osvalue, optname); 149 op->odefault = 1; 150 } 151 break; 152 } 153 next: 154 flush(); 155 } while (!skipend()); 156 eol(); 157 } 158 159 setend() 160 { 161 162 return (iswhite(peekchar()) || endcmd(peekchar())); 163 } 164 165 prall() 166 { 167 register int incr = (NOPTS + 2) / 3; 168 register int rows = incr; 169 register struct option *op = options; 170 171 for (; rows; rows--, op++) { 172 propt(op); 173 tab(24); 174 propt(&op[incr]); 175 if (&op[2*incr] < &options[NOPTS]) { 176 tab(56); 177 propt(&op[2 * incr]); 178 } 179 putNFL(); 180 } 181 } 182 183 propts() 184 { 185 register struct option *op; 186 187 for (op = options; op < &options[NOPTS]; op++) { 188 #ifdef V6 189 if (op == &options[TERM]) 190 #else 191 if (op == &options[TTYTYPE]) 192 #endif 193 continue; 194 switch (op->otype) { 195 196 case ONOFF: 197 case NUMERIC: 198 if (op->ovalue == op->odefault) 199 continue; 200 break; 201 202 case STRING: 203 if (op->odefault == 0) 204 continue; 205 break; 206 } 207 propt(op); 208 ex_putchar(' '); 209 } 210 noonl(); 211 flush(); 212 } 213 214 propt(op) 215 register struct option *op; 216 { 217 register char *name; 218 219 name = op->oname; 220 221 switch (op->otype) { 222 223 case ONOFF: 224 ex_printf("%s%s", op->ovalue ? "" : "no", name); 225 break; 226 227 case NUMERIC: 228 ex_printf("%s=%d", name, op->ovalue); 229 break; 230 231 case STRING: 232 case OTERM: 233 ex_printf("%s=%s", name, op->osvalue); 234 break; 235 } 236 } 237