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