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