aboutsummaryrefslogtreecommitdiff
path: root/coreutils
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2007-11-24 04:32:49 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2007-11-24 04:32:49 +0000
commitdd8bbfd08465a8371769d6d12d568124058922ea (patch)
treebbb075897d8050eb62ae84980686822432c21495 /coreutils
parentfe5e23bf75043302a3492c9a7cd2f30f20f51b2e (diff)
downloadbusybox-w32-dd8bbfd08465a8371769d6d12d568124058922ea.tar.gz
busybox-w32-dd8bbfd08465a8371769d6d12d568124058922ea.tar.bz2
busybox-w32-dd8bbfd08465a8371769d6d12d568124058922ea.zip
stty: reorganize data tables - save 0.5k
function old new delta mode_name - 496 +496 control_name - 91 +91 stty_main 1235 1255 +20 find_mode 45 63 +18 find_control 45 63 +18 do_display 482 493 +11 wrapf 165 166 +1 set_mode 761 759 -2 max_col 4 - -4 device_name 4 - -4 control_info 153 34 -119 mode_info 1700 680 -1020 ------------------------------------------------------------------------------ (add/remove: 2/2 grow/shrink: 5/3 up/down: 655/-1149) Total: -494 bytes text data bss dec hex filename 777037 937 9100 787074 c0282 busybox_old 776551 929 9100 786580 c0094 busybox_unstripped
Diffstat (limited to 'coreutils')
-rw-r--r--coreutils/stty.c527
1 files changed, 376 insertions, 151 deletions
diff --git a/coreutils/stty.c b/coreutils/stty.c
index 849f61540..ade2468a8 100644
--- a/coreutils/stty.c
+++ b/coreutils/stty.c
@@ -133,18 +133,27 @@ enum {
133#define REV 4 /* Can be turned off by prepending '-' */ 133#define REV 4 /* Can be turned off by prepending '-' */
134#define OMIT 8 /* Don't display value */ 134#define OMIT 8 /* Don't display value */
135 135
136/* Each mode */ 136
137/* Each mode.
138 * This structure should be kept as small as humanly possible.
139 */
137struct mode_info { 140struct mode_info {
138 const char name[9]; /* Name given on command line */ 141 const uint8_t type; /* Which structure element to change */
139 const unsigned char type; /* Which structure element to change */ 142 const uint8_t flags; /* Setting and display options */
140 const unsigned char flags; /* Setting and display options */ 143 /* only these values are ever used, so... */
141 /* were using short here, but ppc32 was unhappy: */ 144#if (CSIZE | NLDLY | CRDLY | TABDLY | BSDLY | VTDLY | FFDLY) < 0x100
145 const uint8_t mask;
146#elif (CSIZE | NLDLY | CRDLY | TABDLY | BSDLY | VTDLY | FFDLY) < 0x10000
147 const uint16_t mask;
148#else
142 const tcflag_t mask; /* Other bits to turn off for this mode */ 149 const tcflag_t mask; /* Other bits to turn off for this mode */
150#endif
151 /* was using short here, but ppc32 was unhappy */
143 const tcflag_t bits; /* Bits to set for this mode */ 152 const tcflag_t bits; /* Bits to set for this mode */
144}; 153};
145 154
146enum { 155enum {
147 /* Must match mode_info[] order! */ 156 /* Must match mode_name[] and mode_info[] order! */
148 IDX_evenp = 0, 157 IDX_evenp = 0,
149 IDX_parity, 158 IDX_parity,
150 IDX_oddp, 159 IDX_oddp,
@@ -170,151 +179,302 @@ enum {
170#endif 179#endif
171}; 180};
172 181
173#define MI_ENTRY(N,T,F,B,M) { N, T, F, M, B } 182#define MI_ENTRY(N,T,F,B,M) N "\0"
183
184/* Mode names given on command line */
185static const char mode_name[] =
186 MI_ENTRY("evenp", combination, REV | OMIT, 0, 0 )
187 MI_ENTRY("parity", combination, REV | OMIT, 0, 0 )
188 MI_ENTRY("oddp", combination, REV | OMIT, 0, 0 )
189 MI_ENTRY("nl", combination, REV | OMIT, 0, 0 )
190 MI_ENTRY("ek", combination, OMIT, 0, 0 )
191 MI_ENTRY("sane", combination, OMIT, 0, 0 )
192 MI_ENTRY("cooked", combination, REV | OMIT, 0, 0 )
193 MI_ENTRY("raw", combination, REV | OMIT, 0, 0 )
194 MI_ENTRY("pass8", combination, REV | OMIT, 0, 0 )
195 MI_ENTRY("litout", combination, REV | OMIT, 0, 0 )
196 MI_ENTRY("cbreak", combination, REV | OMIT, 0, 0 )
197 MI_ENTRY("crt", combination, OMIT, 0, 0 )
198 MI_ENTRY("dec", combination, OMIT, 0, 0 )
199#ifdef IXANY
200 MI_ENTRY("decctlq", combination, REV | OMIT, 0, 0 )
201#endif
202#if defined(TABDLY) || defined(OXTABS)
203 MI_ENTRY("tabs", combination, REV | OMIT, 0, 0 )
204#endif
205#if defined(XCASE) && defined(IUCLC) && defined(OLCUC)
206 MI_ENTRY("lcase", combination, REV | OMIT, 0, 0 )
207 MI_ENTRY("LCASE", combination, REV | OMIT, 0, 0 )
208#endif
209 MI_ENTRY("parenb", control, REV, PARENB, 0 )
210 MI_ENTRY("parodd", control, REV, PARODD, 0 )
211 MI_ENTRY("cs5", control, 0, CS5, CSIZE)
212 MI_ENTRY("cs6", control, 0, CS6, CSIZE)
213 MI_ENTRY("cs7", control, 0, CS7, CSIZE)
214 MI_ENTRY("cs8", control, 0, CS8, CSIZE)
215 MI_ENTRY("hupcl", control, REV, HUPCL, 0 )
216 MI_ENTRY("hup", control, REV | OMIT, HUPCL, 0 )
217 MI_ENTRY("cstopb", control, REV, CSTOPB, 0 )
218 MI_ENTRY("cread", control, SANE_SET | REV, CREAD, 0 )
219 MI_ENTRY("clocal", control, REV, CLOCAL, 0 )
220#ifdef CRTSCTS
221 MI_ENTRY("crtscts", control, REV, CRTSCTS, 0 )
222#endif
223 MI_ENTRY("ignbrk", input, SANE_UNSET | REV, IGNBRK, 0 )
224 MI_ENTRY("brkint", input, SANE_SET | REV, BRKINT, 0 )
225 MI_ENTRY("ignpar", input, REV, IGNPAR, 0 )
226 MI_ENTRY("parmrk", input, REV, PARMRK, 0 )
227 MI_ENTRY("inpck", input, REV, INPCK, 0 )
228 MI_ENTRY("istrip", input, REV, ISTRIP, 0 )
229 MI_ENTRY("inlcr", input, SANE_UNSET | REV, INLCR, 0 )
230 MI_ENTRY("igncr", input, SANE_UNSET | REV, IGNCR, 0 )
231 MI_ENTRY("icrnl", input, SANE_SET | REV, ICRNL, 0 )
232 MI_ENTRY("ixon", input, REV, IXON, 0 )
233 MI_ENTRY("ixoff", input, SANE_UNSET | REV, IXOFF, 0 )
234 MI_ENTRY("tandem", input, REV | OMIT, IXOFF, 0 )
235#ifdef IUCLC
236 MI_ENTRY("iuclc", input, SANE_UNSET | REV, IUCLC, 0 )
237#endif
238#ifdef IXANY
239 MI_ENTRY("ixany", input, SANE_UNSET | REV, IXANY, 0 )
240#endif
241#ifdef IMAXBEL
242 MI_ENTRY("imaxbel", input, SANE_SET | REV, IMAXBEL, 0 )
243#endif
244 MI_ENTRY("opost", output, SANE_SET | REV, OPOST, 0 )
245#ifdef OLCUC
246 MI_ENTRY("olcuc", output, SANE_UNSET | REV, OLCUC, 0 )
247#endif
248#ifdef OCRNL
249 MI_ENTRY("ocrnl", output, SANE_UNSET | REV, OCRNL, 0 )
250#endif
251#ifdef ONLCR
252 MI_ENTRY("onlcr", output, SANE_SET | REV, ONLCR, 0 )
253#endif
254#ifdef ONOCR
255 MI_ENTRY("onocr", output, SANE_UNSET | REV, ONOCR, 0 )
256#endif
257#ifdef ONLRET
258 MI_ENTRY("onlret", output, SANE_UNSET | REV, ONLRET, 0 )
259#endif
260#ifdef OFILL
261 MI_ENTRY("ofill", output, SANE_UNSET | REV, OFILL, 0 )
262#endif
263#ifdef OFDEL
264 MI_ENTRY("ofdel", output, SANE_UNSET | REV, OFDEL, 0 )
265#endif
266#ifdef NLDLY
267 MI_ENTRY("nl1", output, SANE_UNSET, NL1, NLDLY)
268 MI_ENTRY("nl0", output, SANE_SET, NL0, NLDLY)
269#endif
270#ifdef CRDLY
271 MI_ENTRY("cr3", output, SANE_UNSET, CR3, CRDLY)
272 MI_ENTRY("cr2", output, SANE_UNSET, CR2, CRDLY)
273 MI_ENTRY("cr1", output, SANE_UNSET, CR1, CRDLY)
274 MI_ENTRY("cr0", output, SANE_SET, CR0, CRDLY)
275#endif
276
277#ifdef TABDLY
278 MI_ENTRY("tab3", output, SANE_UNSET, TAB3, TABDLY)
279 MI_ENTRY("tab2", output, SANE_UNSET, TAB2, TABDLY)
280 MI_ENTRY("tab1", output, SANE_UNSET, TAB1, TABDLY)
281 MI_ENTRY("tab0", output, SANE_SET, TAB0, TABDLY)
282#else
283# ifdef OXTABS
284 MI_ENTRY("tab3", output, SANE_UNSET, OXTABS, 0 )
285# endif
286#endif
287
288#ifdef BSDLY
289 MI_ENTRY("bs1", output, SANE_UNSET, BS1, BSDLY)
290 MI_ENTRY("bs0", output, SANE_SET, BS0, BSDLY)
291#endif
292#ifdef VTDLY
293 MI_ENTRY("vt1", output, SANE_UNSET, VT1, VTDLY)
294 MI_ENTRY("vt0", output, SANE_SET, VT0, VTDLY)
295#endif
296#ifdef FFDLY
297 MI_ENTRY("ff1", output, SANE_UNSET, FF1, FFDLY)
298 MI_ENTRY("ff0", output, SANE_SET, FF0, FFDLY)
299#endif
300 MI_ENTRY("isig", local, SANE_SET | REV, ISIG, 0 )
301 MI_ENTRY("icanon", local, SANE_SET | REV, ICANON, 0 )
302#ifdef IEXTEN
303 MI_ENTRY("iexten", local, SANE_SET | REV, IEXTEN, 0 )
304#endif
305 MI_ENTRY("echo", local, SANE_SET | REV, ECHO, 0 )
306 MI_ENTRY("echoe", local, SANE_SET | REV, ECHOE, 0 )
307 MI_ENTRY("crterase", local, REV | OMIT, ECHOE, 0 )
308 MI_ENTRY("echok", local, SANE_SET | REV, ECHOK, 0 )
309 MI_ENTRY("echonl", local, SANE_UNSET | REV, ECHONL, 0 )
310 MI_ENTRY("noflsh", local, SANE_UNSET | REV, NOFLSH, 0 )
311#ifdef XCASE
312 MI_ENTRY("xcase", local, SANE_UNSET | REV, XCASE, 0 )
313#endif
314#ifdef TOSTOP
315 MI_ENTRY("tostop", local, SANE_UNSET | REV, TOSTOP, 0 )
316#endif
317#ifdef ECHOPRT
318 MI_ENTRY("echoprt", local, SANE_UNSET | REV, ECHOPRT, 0 )
319 MI_ENTRY("prterase", local, REV | OMIT, ECHOPRT, 0 )
320#endif
321#ifdef ECHOCTL
322 MI_ENTRY("echoctl", local, SANE_SET | REV, ECHOCTL, 0 )
323 MI_ENTRY("ctlecho", local, REV | OMIT, ECHOCTL, 0 )
324#endif
325#ifdef ECHOKE
326 MI_ENTRY("echoke", local, SANE_SET | REV, ECHOKE, 0 )
327 MI_ENTRY("crtkill", local, REV | OMIT, ECHOKE, 0 )
328#endif
329 ;
330
331#undef MI_ENTRY
332#define MI_ENTRY(N,T,F,B,M) { T, F, M, B },
174 333
175static const struct mode_info mode_info[] = { 334static const struct mode_info mode_info[] = {
176 MI_ENTRY("evenp", combination, REV | OMIT, 0, 0 ), 335 /* This should be verbatim cut-n-paste copy of the above MI_ENTRYs */
177 MI_ENTRY("parity", combination, REV | OMIT, 0, 0 ), 336 MI_ENTRY("evenp", combination, REV | OMIT, 0, 0 )
178 MI_ENTRY("oddp", combination, REV | OMIT, 0, 0 ), 337 MI_ENTRY("parity", combination, REV | OMIT, 0, 0 )
179 MI_ENTRY("nl", combination, REV | OMIT, 0, 0 ), 338 MI_ENTRY("oddp", combination, REV | OMIT, 0, 0 )
180 MI_ENTRY("ek", combination, OMIT, 0, 0 ), 339 MI_ENTRY("nl", combination, REV | OMIT, 0, 0 )
181 MI_ENTRY("sane", combination, OMIT, 0, 0 ), 340 MI_ENTRY("ek", combination, OMIT, 0, 0 )
182 MI_ENTRY("cooked", combination, REV | OMIT, 0, 0 ), 341 MI_ENTRY("sane", combination, OMIT, 0, 0 )
183 MI_ENTRY("raw", combination, REV | OMIT, 0, 0 ), 342 MI_ENTRY("cooked", combination, REV | OMIT, 0, 0 )
184 MI_ENTRY("pass8", combination, REV | OMIT, 0, 0 ), 343 MI_ENTRY("raw", combination, REV | OMIT, 0, 0 )
185 MI_ENTRY("litout", combination, REV | OMIT, 0, 0 ), 344 MI_ENTRY("pass8", combination, REV | OMIT, 0, 0 )
186 MI_ENTRY("cbreak", combination, REV | OMIT, 0, 0 ), 345 MI_ENTRY("litout", combination, REV | OMIT, 0, 0 )
187 MI_ENTRY("crt", combination, OMIT, 0, 0 ), 346 MI_ENTRY("cbreak", combination, REV | OMIT, 0, 0 )
188 MI_ENTRY("dec", combination, OMIT, 0, 0 ), 347 MI_ENTRY("crt", combination, OMIT, 0, 0 )
348 MI_ENTRY("dec", combination, OMIT, 0, 0 )
189#ifdef IXANY 349#ifdef IXANY
190 MI_ENTRY("decctlq", combination, REV | OMIT, 0, 0 ), 350 MI_ENTRY("decctlq", combination, REV | OMIT, 0, 0 )
191#endif 351#endif
192#if defined(TABDLY) || defined(OXTABS) 352#if defined(TABDLY) || defined(OXTABS)
193 MI_ENTRY("tabs", combination, REV | OMIT, 0, 0 ), 353 MI_ENTRY("tabs", combination, REV | OMIT, 0, 0 )
194#endif 354#endif
195#if defined(XCASE) && defined(IUCLC) && defined(OLCUC) 355#if defined(XCASE) && defined(IUCLC) && defined(OLCUC)
196 MI_ENTRY("lcase", combination, REV | OMIT, 0, 0 ), 356 MI_ENTRY("lcase", combination, REV | OMIT, 0, 0 )
197 MI_ENTRY("LCASE", combination, REV | OMIT, 0, 0 ), 357 MI_ENTRY("LCASE", combination, REV | OMIT, 0, 0 )
198#endif 358#endif
199 MI_ENTRY("parenb", control, REV, PARENB, 0 ), 359 MI_ENTRY("parenb", control, REV, PARENB, 0 )
200 MI_ENTRY("parodd", control, REV, PARODD, 0 ), 360 MI_ENTRY("parodd", control, REV, PARODD, 0 )
201 MI_ENTRY("cs5", control, 0, CS5, CSIZE), 361 MI_ENTRY("cs5", control, 0, CS5, CSIZE)
202 MI_ENTRY("cs6", control, 0, CS6, CSIZE), 362 MI_ENTRY("cs6", control, 0, CS6, CSIZE)
203 MI_ENTRY("cs7", control, 0, CS7, CSIZE), 363 MI_ENTRY("cs7", control, 0, CS7, CSIZE)
204 MI_ENTRY("cs8", control, 0, CS8, CSIZE), 364 MI_ENTRY("cs8", control, 0, CS8, CSIZE)
205 MI_ENTRY("hupcl", control, REV, HUPCL, 0 ), 365 MI_ENTRY("hupcl", control, REV, HUPCL, 0 )
206 MI_ENTRY("hup", control, REV | OMIT, HUPCL, 0 ), 366 MI_ENTRY("hup", control, REV | OMIT, HUPCL, 0 )
207 MI_ENTRY("cstopb", control, REV, CSTOPB, 0 ), 367 MI_ENTRY("cstopb", control, REV, CSTOPB, 0 )
208 MI_ENTRY("cread", control, SANE_SET | REV, CREAD, 0 ), 368 MI_ENTRY("cread", control, SANE_SET | REV, CREAD, 0 )
209 MI_ENTRY("clocal", control, REV, CLOCAL, 0 ), 369 MI_ENTRY("clocal", control, REV, CLOCAL, 0 )
210#ifdef CRTSCTS 370#ifdef CRTSCTS
211 MI_ENTRY("crtscts", control, REV, CRTSCTS, 0 ), 371 MI_ENTRY("crtscts", control, REV, CRTSCTS, 0 )
212#endif 372#endif
213 MI_ENTRY("ignbrk", input, SANE_UNSET | REV, IGNBRK, 0 ), 373 MI_ENTRY("ignbrk", input, SANE_UNSET | REV, IGNBRK, 0 )
214 MI_ENTRY("brkint", input, SANE_SET | REV, BRKINT, 0 ), 374 MI_ENTRY("brkint", input, SANE_SET | REV, BRKINT, 0 )
215 MI_ENTRY("ignpar", input, REV, IGNPAR, 0 ), 375 MI_ENTRY("ignpar", input, REV, IGNPAR, 0 )
216 MI_ENTRY("parmrk", input, REV, PARMRK, 0 ), 376 MI_ENTRY("parmrk", input, REV, PARMRK, 0 )
217 MI_ENTRY("inpck", input, REV, INPCK, 0 ), 377 MI_ENTRY("inpck", input, REV, INPCK, 0 )
218 MI_ENTRY("istrip", input, REV, ISTRIP, 0 ), 378 MI_ENTRY("istrip", input, REV, ISTRIP, 0 )
219 MI_ENTRY("inlcr", input, SANE_UNSET | REV, INLCR, 0 ), 379 MI_ENTRY("inlcr", input, SANE_UNSET | REV, INLCR, 0 )
220 MI_ENTRY("igncr", input, SANE_UNSET | REV, IGNCR, 0 ), 380 MI_ENTRY("igncr", input, SANE_UNSET | REV, IGNCR, 0 )
221 MI_ENTRY("icrnl", input, SANE_SET | REV, ICRNL, 0 ), 381 MI_ENTRY("icrnl", input, SANE_SET | REV, ICRNL, 0 )
222 MI_ENTRY("ixon", input, REV, IXON, 0 ), 382 MI_ENTRY("ixon", input, REV, IXON, 0 )
223 MI_ENTRY("ixoff", input, SANE_UNSET | REV, IXOFF, 0 ), 383 MI_ENTRY("ixoff", input, SANE_UNSET | REV, IXOFF, 0 )
224 MI_ENTRY("tandem", input, REV | OMIT, IXOFF, 0 ), 384 MI_ENTRY("tandem", input, REV | OMIT, IXOFF, 0 )
225#ifdef IUCLC 385#ifdef IUCLC
226 MI_ENTRY("iuclc", input, SANE_UNSET | REV, IUCLC, 0 ), 386 MI_ENTRY("iuclc", input, SANE_UNSET | REV, IUCLC, 0 )
227#endif 387#endif
228#ifdef IXANY 388#ifdef IXANY
229 MI_ENTRY("ixany", input, SANE_UNSET | REV, IXANY, 0 ), 389 MI_ENTRY("ixany", input, SANE_UNSET | REV, IXANY, 0 )
230#endif 390#endif
231#ifdef IMAXBEL 391#ifdef IMAXBEL
232 MI_ENTRY("imaxbel", input, SANE_SET | REV, IMAXBEL, 0 ), 392 MI_ENTRY("imaxbel", input, SANE_SET | REV, IMAXBEL, 0 )
233#endif 393#endif
234 MI_ENTRY("opost", output, SANE_SET | REV, OPOST, 0 ), 394 MI_ENTRY("opost", output, SANE_SET | REV, OPOST, 0 )
235#ifdef OLCUC 395#ifdef OLCUC
236 MI_ENTRY("olcuc", output, SANE_UNSET | REV, OLCUC, 0 ), 396 MI_ENTRY("olcuc", output, SANE_UNSET | REV, OLCUC, 0 )
237#endif 397#endif
238#ifdef OCRNL 398#ifdef OCRNL
239 MI_ENTRY("ocrnl", output, SANE_UNSET | REV, OCRNL, 0 ), 399 MI_ENTRY("ocrnl", output, SANE_UNSET | REV, OCRNL, 0 )
240#endif 400#endif
241#ifdef ONLCR 401#ifdef ONLCR
242 MI_ENTRY("onlcr", output, SANE_SET | REV, ONLCR, 0 ), 402 MI_ENTRY("onlcr", output, SANE_SET | REV, ONLCR, 0 )
243#endif 403#endif
244#ifdef ONOCR 404#ifdef ONOCR
245 MI_ENTRY("onocr", output, SANE_UNSET | REV, ONOCR, 0 ), 405 MI_ENTRY("onocr", output, SANE_UNSET | REV, ONOCR, 0 )
246#endif 406#endif
247#ifdef ONLRET 407#ifdef ONLRET
248 MI_ENTRY("onlret", output, SANE_UNSET | REV, ONLRET, 0 ), 408 MI_ENTRY("onlret", output, SANE_UNSET | REV, ONLRET, 0 )
249#endif 409#endif
250#ifdef OFILL 410#ifdef OFILL
251 MI_ENTRY("ofill", output, SANE_UNSET | REV, OFILL, 0 ), 411 MI_ENTRY("ofill", output, SANE_UNSET | REV, OFILL, 0 )
252#endif 412#endif
253#ifdef OFDEL 413#ifdef OFDEL
254 MI_ENTRY("ofdel", output, SANE_UNSET | REV, OFDEL, 0 ), 414 MI_ENTRY("ofdel", output, SANE_UNSET | REV, OFDEL, 0 )
255#endif 415#endif
256#ifdef NLDLY 416#ifdef NLDLY
257 MI_ENTRY("nl1", output, SANE_UNSET, NL1, NLDLY), 417 MI_ENTRY("nl1", output, SANE_UNSET, NL1, NLDLY)
258 MI_ENTRY("nl0", output, SANE_SET, NL0, NLDLY), 418 MI_ENTRY("nl0", output, SANE_SET, NL0, NLDLY)
259#endif 419#endif
260#ifdef CRDLY 420#ifdef CRDLY
261 MI_ENTRY("cr3", output, SANE_UNSET, CR3, CRDLY), 421 MI_ENTRY("cr3", output, SANE_UNSET, CR3, CRDLY)
262 MI_ENTRY("cr2", output, SANE_UNSET, CR2, CRDLY), 422 MI_ENTRY("cr2", output, SANE_UNSET, CR2, CRDLY)
263 MI_ENTRY("cr1", output, SANE_UNSET, CR1, CRDLY), 423 MI_ENTRY("cr1", output, SANE_UNSET, CR1, CRDLY)
264 MI_ENTRY("cr0", output, SANE_SET, CR0, CRDLY), 424 MI_ENTRY("cr0", output, SANE_SET, CR0, CRDLY)
265#endif 425#endif
266 426
267#ifdef TABDLY 427#ifdef TABDLY
268 MI_ENTRY("tab3", output, SANE_UNSET, TAB3, TABDLY), 428 MI_ENTRY("tab3", output, SANE_UNSET, TAB3, TABDLY)
269 MI_ENTRY("tab2", output, SANE_UNSET, TAB2, TABDLY), 429 MI_ENTRY("tab2", output, SANE_UNSET, TAB2, TABDLY)
270 MI_ENTRY("tab1", output, SANE_UNSET, TAB1, TABDLY), 430 MI_ENTRY("tab1", output, SANE_UNSET, TAB1, TABDLY)
271 MI_ENTRY("tab0", output, SANE_SET, TAB0, TABDLY), 431 MI_ENTRY("tab0", output, SANE_SET, TAB0, TABDLY)
272#else 432#else
273# ifdef OXTABS 433# ifdef OXTABS
274 MI_ENTRY("tab3", output, SANE_UNSET, OXTABS, 0 ), 434 MI_ENTRY("tab3", output, SANE_UNSET, OXTABS, 0 )
275# endif 435# endif
276#endif 436#endif
277 437
278#ifdef BSDLY 438#ifdef BSDLY
279 MI_ENTRY("bs1", output, SANE_UNSET, BS1, BSDLY), 439 MI_ENTRY("bs1", output, SANE_UNSET, BS1, BSDLY)
280 MI_ENTRY("bs0", output, SANE_SET, BS0, BSDLY), 440 MI_ENTRY("bs0", output, SANE_SET, BS0, BSDLY)
281#endif 441#endif
282#ifdef VTDLY 442#ifdef VTDLY
283 MI_ENTRY("vt1", output, SANE_UNSET, VT1, VTDLY), 443 MI_ENTRY("vt1", output, SANE_UNSET, VT1, VTDLY)
284 MI_ENTRY("vt0", output, SANE_SET, VT0, VTDLY), 444 MI_ENTRY("vt0", output, SANE_SET, VT0, VTDLY)
285#endif 445#endif
286#ifdef FFDLY 446#ifdef FFDLY
287 MI_ENTRY("ff1", output, SANE_UNSET, FF1, FFDLY), 447 MI_ENTRY("ff1", output, SANE_UNSET, FF1, FFDLY)
288 MI_ENTRY("ff0", output, SANE_SET, FF0, FFDLY), 448 MI_ENTRY("ff0", output, SANE_SET, FF0, FFDLY)
289#endif 449#endif
290 MI_ENTRY("isig", local, SANE_SET | REV, ISIG, 0 ), 450 MI_ENTRY("isig", local, SANE_SET | REV, ISIG, 0 )
291 MI_ENTRY("icanon", local, SANE_SET | REV, ICANON, 0 ), 451 MI_ENTRY("icanon", local, SANE_SET | REV, ICANON, 0 )
292#ifdef IEXTEN 452#ifdef IEXTEN
293 MI_ENTRY("iexten", local, SANE_SET | REV, IEXTEN, 0 ), 453 MI_ENTRY("iexten", local, SANE_SET | REV, IEXTEN, 0 )
294#endif 454#endif
295 MI_ENTRY("echo", local, SANE_SET | REV, ECHO, 0 ), 455 MI_ENTRY("echo", local, SANE_SET | REV, ECHO, 0 )
296 MI_ENTRY("echoe", local, SANE_SET | REV, ECHOE, 0 ), 456 MI_ENTRY("echoe", local, SANE_SET | REV, ECHOE, 0 )
297 MI_ENTRY("crterase", local, REV | OMIT, ECHOE, 0 ), 457 MI_ENTRY("crterase", local, REV | OMIT, ECHOE, 0 )
298 MI_ENTRY("echok", local, SANE_SET | REV, ECHOK, 0 ), 458 MI_ENTRY("echok", local, SANE_SET | REV, ECHOK, 0 )
299 MI_ENTRY("echonl", local, SANE_UNSET | REV, ECHONL, 0 ), 459 MI_ENTRY("echonl", local, SANE_UNSET | REV, ECHONL, 0 )
300 MI_ENTRY("noflsh", local, SANE_UNSET | REV, NOFLSH, 0 ), 460 MI_ENTRY("noflsh", local, SANE_UNSET | REV, NOFLSH, 0 )
301#ifdef XCASE 461#ifdef XCASE
302 MI_ENTRY("xcase", local, SANE_UNSET | REV, XCASE, 0 ), 462 MI_ENTRY("xcase", local, SANE_UNSET | REV, XCASE, 0 )
303#endif 463#endif
304#ifdef TOSTOP 464#ifdef TOSTOP
305 MI_ENTRY("tostop", local, SANE_UNSET | REV, TOSTOP, 0 ), 465 MI_ENTRY("tostop", local, SANE_UNSET | REV, TOSTOP, 0 )
306#endif 466#endif
307#ifdef ECHOPRT 467#ifdef ECHOPRT
308 MI_ENTRY("echoprt", local, SANE_UNSET | REV, ECHOPRT, 0 ), 468 MI_ENTRY("echoprt", local, SANE_UNSET | REV, ECHOPRT, 0 )
309 MI_ENTRY("prterase", local, REV | OMIT, ECHOPRT, 0 ), 469 MI_ENTRY("prterase", local, REV | OMIT, ECHOPRT, 0 )
310#endif 470#endif
311#ifdef ECHOCTL 471#ifdef ECHOCTL
312 MI_ENTRY("echoctl", local, SANE_SET | REV, ECHOCTL, 0 ), 472 MI_ENTRY("echoctl", local, SANE_SET | REV, ECHOCTL, 0 )
313 MI_ENTRY("ctlecho", local, REV | OMIT, ECHOCTL, 0 ), 473 MI_ENTRY("ctlecho", local, REV | OMIT, ECHOCTL, 0 )
314#endif 474#endif
315#ifdef ECHOKE 475#ifdef ECHOKE
316 MI_ENTRY("echoke", local, SANE_SET | REV, ECHOKE, 0 ), 476 MI_ENTRY("echoke", local, SANE_SET | REV, ECHOKE, 0 )
317 MI_ENTRY("crtkill", local, REV | OMIT, ECHOKE, 0 ), 477 MI_ENTRY("crtkill", local, REV | OMIT, ECHOKE, 0 )
318#endif 478#endif
319}; 479};
320 480
@@ -322,15 +482,15 @@ enum {
322 NUM_mode_info = ARRAY_SIZE(mode_info) 482 NUM_mode_info = ARRAY_SIZE(mode_info)
323}; 483};
324 484
485
325/* Control characters */ 486/* Control characters */
326struct control_info { 487struct control_info {
327 const char name[7]; /* Name given on command line */ 488 const uint8_t saneval; /* Value to set for 'stty sane' */
328 const unsigned char saneval; /* Value to set for 'stty sane' */ 489 const uint8_t offset; /* Offset in c_cc */
329 const unsigned char offset; /* Offset in c_cc */
330}; 490};
331 491
332enum { 492enum {
333 /* Must match control_info[] order! */ 493 /* Must match control_name[] and control_info[] order! */
334 CIDX_intr = 0, 494 CIDX_intr = 0,
335 CIDX_quit, 495 CIDX_quit,
336 CIDX_erase, 496 CIDX_erase,
@@ -368,60 +528,111 @@ enum {
368 CIDX_time, 528 CIDX_time,
369}; 529};
370 530
531#define CI_ENTRY(n,s,o) n "\0"
532
533/* Name given on command line */
534static const char control_name[] =
535 CI_ENTRY("intr", CINTR, VINTR )
536 CI_ENTRY("quit", CQUIT, VQUIT )
537 CI_ENTRY("erase", CERASE, VERASE )
538 CI_ENTRY("kill", CKILL, VKILL )
539 CI_ENTRY("eof", CEOF, VEOF )
540 CI_ENTRY("eol", CEOL, VEOL )
541#ifdef VEOL2
542 CI_ENTRY("eol2", CEOL2, VEOL2 )
543#endif
544#ifdef VSWTCH
545 CI_ENTRY("swtch", CSWTCH, VSWTCH )
546#endif
547 CI_ENTRY("start", CSTART, VSTART )
548 CI_ENTRY("stop", CSTOP, VSTOP )
549 CI_ENTRY("susp", CSUSP, VSUSP )
550#ifdef VDSUSP
551 CI_ENTRY("dsusp", CDSUSP, VDSUSP )
552#endif
553#ifdef VREPRINT
554 CI_ENTRY("rprnt", CRPRNT, VREPRINT)
555#endif
556#ifdef VWERASE
557 CI_ENTRY("werase", CWERASE, VWERASE )
558#endif
559#ifdef VLNEXT
560 CI_ENTRY("lnext", CLNEXT, VLNEXT )
561#endif
562#ifdef VFLUSHO
563 CI_ENTRY("flush", CFLUSHO, VFLUSHO )
564#endif
565#ifdef VSTATUS
566 CI_ENTRY("status", CSTATUS, VSTATUS )
567#endif
568 /* These must be last because of the display routines */
569 CI_ENTRY("min", 1, VMIN )
570 CI_ENTRY("time", 0, VTIME )
571 ;
572
573#undef CI_ENTRY
574#define CI_ENTRY(n,s,o) { s, o },
575
371static const struct control_info control_info[] = { 576static const struct control_info control_info[] = {
372 {"intr", CINTR, VINTR}, 577 /* This should be verbatim cut-n-paste copy of the above CI_ENTRYs */
373 {"quit", CQUIT, VQUIT}, 578 CI_ENTRY("intr", CINTR, VINTR )
374 {"erase", CERASE, VERASE}, 579 CI_ENTRY("quit", CQUIT, VQUIT )
375 {"kill", CKILL, VKILL}, 580 CI_ENTRY("erase", CERASE, VERASE )
376 {"eof", CEOF, VEOF}, 581 CI_ENTRY("kill", CKILL, VKILL )
377 {"eol", CEOL, VEOL}, 582 CI_ENTRY("eof", CEOF, VEOF )
583 CI_ENTRY("eol", CEOL, VEOL )
378#ifdef VEOL2 584#ifdef VEOL2
379 {"eol2", CEOL2, VEOL2}, 585 CI_ENTRY("eol2", CEOL2, VEOL2 )
380#endif 586#endif
381#ifdef VSWTCH 587#ifdef VSWTCH
382 {"swtch", CSWTCH, VSWTCH}, 588 CI_ENTRY("swtch", CSWTCH, VSWTCH )
383#endif 589#endif
384 {"start", CSTART, VSTART}, 590 CI_ENTRY("start", CSTART, VSTART )
385 {"stop", CSTOP, VSTOP}, 591 CI_ENTRY("stop", CSTOP, VSTOP )
386 {"susp", CSUSP, VSUSP}, 592 CI_ENTRY("susp", CSUSP, VSUSP )
387#ifdef VDSUSP 593#ifdef VDSUSP
388 {"dsusp", CDSUSP, VDSUSP}, 594 CI_ENTRY("dsusp", CDSUSP, VDSUSP )
389#endif 595#endif
390#ifdef VREPRINT 596#ifdef VREPRINT
391 {"rprnt", CRPRNT, VREPRINT}, 597 CI_ENTRY("rprnt", CRPRNT, VREPRINT)
392#endif 598#endif
393#ifdef VWERASE 599#ifdef VWERASE
394 {"werase", CWERASE, VWERASE}, 600 CI_ENTRY("werase", CWERASE, VWERASE )
395#endif 601#endif
396#ifdef VLNEXT 602#ifdef VLNEXT
397 {"lnext", CLNEXT, VLNEXT}, 603 CI_ENTRY("lnext", CLNEXT, VLNEXT )
398#endif 604#endif
399#ifdef VFLUSHO 605#ifdef VFLUSHO
400 {"flush", CFLUSHO, VFLUSHO}, 606 CI_ENTRY("flush", CFLUSHO, VFLUSHO )
401#endif 607#endif
402#ifdef VSTATUS 608#ifdef VSTATUS
403 {"status", CSTATUS, VSTATUS}, 609 CI_ENTRY("status", CSTATUS, VSTATUS )
404#endif 610#endif
405 /* These must be last because of the display routines */ 611 /* These must be last because of the display routines */
406 {"min", 1, VMIN}, 612 CI_ENTRY("min", 1, VMIN )
407 {"time", 0, VTIME}, 613 CI_ENTRY("time", 0, VTIME )
408}; 614};
409 615
410enum { 616enum {
411 NUM_control_info = ARRAY_SIZE(control_info) 617 NUM_control_info = ARRAY_SIZE(control_info)
412}; 618};
413 619
414/* The width of the screen, for output wrapping */
415static unsigned max_col = 80; /* default */
416 620
417struct globals { 621struct globals {
622 const char *device_name; // = bb_msg_standard_input;
623 /* The width of the screen, for output wrapping */
624 unsigned max_col; // = 80;
418 /* Current position, to know when to wrap */ 625 /* Current position, to know when to wrap */
419 unsigned current_col; 626 unsigned current_col;
420 char buf[10]; 627 char buf[10];
421}; 628};
422#define G (*(struct globals*)&bb_common_bufsiz1) 629#define G (*(struct globals*)&bb_common_bufsiz1)
630#define INIT_G() \
631 do { \
632 G.device_name = bb_msg_standard_input; \
633 G.max_col = 80; \
634 } while (0)
423 635
424static const char *device_name = bb_msg_standard_input;
425 636
426/* Return a string that is the printable representation of character CH */ 637/* Return a string that is the printable representation of character CH */
427/* Adapted from 'cat' by Torbjorn Granlund */ 638/* Adapted from 'cat' by Torbjorn Granlund */
@@ -454,7 +665,7 @@ static const char *visible(unsigned ch)
454 665
455static tcflag_t *mode_type_flag(unsigned type, const struct termios *mode) 666static tcflag_t *mode_type_flag(unsigned type, const struct termios *mode)
456{ 667{
457 static const unsigned char tcflag_offsets[] ALIGN1 = { 668 static const uint8_t tcflag_offsets[] ALIGN1 = {
458 offsetof(struct termios, c_cflag), /* control */ 669 offsetof(struct termios, c_cflag), /* control */
459 offsetof(struct termios, c_iflag), /* input */ 670 offsetof(struct termios, c_iflag), /* input */
460 offsetof(struct termios, c_oflag), /* output */ 671 offsetof(struct termios, c_oflag), /* output */
@@ -484,12 +695,12 @@ static void set_speed_or_die(enum speed_setting type, const char *const arg,
484 695
485static ATTRIBUTE_NORETURN void perror_on_device_and_die(const char *fmt) 696static ATTRIBUTE_NORETURN void perror_on_device_and_die(const char *fmt)
486{ 697{
487 bb_perror_msg_and_die(fmt, device_name); 698 bb_perror_msg_and_die(fmt, G.device_name);
488} 699}
489 700
490static void perror_on_device(const char *fmt) 701static void perror_on_device(const char *fmt)
491{ 702{
492 bb_perror_msg(fmt, device_name); 703 bb_perror_msg(fmt, G.device_name);
493} 704}
494 705
495/* Print format string MESSAGE and optional args. 706/* Print format string MESSAGE and optional args.
@@ -511,7 +722,7 @@ static void wrapf(const char *message, ...)
511 if (G.current_col > 0) { 722 if (G.current_col > 0) {
512 G.current_col++; 723 G.current_col++;
513 if (buf[0] != '\n') { 724 if (buf[0] != '\n') {
514 if (G.current_col + buflen >= max_col) { 725 if (G.current_col + buflen >= G.max_col) {
515 bb_putchar('\n'); 726 bb_putchar('\n');
516 G.current_col = 0; 727 G.current_col = 0;
517 } else 728 } else
@@ -526,7 +737,7 @@ static void wrapf(const char *message, ...)
526 737
527static void set_window_size(const int rows, const int cols) 738static void set_window_size(const int rows, const int cols)
528{ 739{
529 struct winsize win = { 0, 0, 0, 0}; 740 struct winsize win = { 0, 0, 0, 0 };
530 741
531 if (ioctl(STDIN_FILENO, TIOCGWINSZ, &win)) { 742 if (ioctl(STDIN_FILENO, TIOCGWINSZ, &win)) {
532 if (errno != EINVAL) { 743 if (errno != EINVAL) {
@@ -569,20 +780,30 @@ static const struct suffix_mult stty_suffixes[] = {
569 780
570static const struct mode_info *find_mode(const char *name) 781static const struct mode_info *find_mode(const char *name)
571{ 782{
572 int i; 783 int i = 0;
573 for (i = 0; i < NUM_mode_info; ++i) 784 const char *m = mode_name;
574 if (!strcmp(name, mode_info[i].name)) 785
786 while (*m) {
787 if (strcmp(name, m) == 0)
575 return &mode_info[i]; 788 return &mode_info[i];
576 return 0; 789 m += strlen(m) + 1;
790 i++;
791 }
792 return NULL;
577} 793}
578 794
579static const struct control_info *find_control(const char *name) 795static const struct control_info *find_control(const char *name)
580{ 796{
581 int i; 797 int i = 0;
582 for (i = 0; i < NUM_control_info; ++i) 798 const char *m = mode_name;
583 if (!strcmp(name, control_info[i].name)) 799
800 while (*m) {
801 if (strcmp(name, m) == 0)
584 return &control_info[i]; 802 return &control_info[i];
585 return 0; 803 m += strlen(m) + 1;
804 i++;
805 }
806 return NULL;
586} 807}
587 808
588enum { 809enum {
@@ -704,7 +925,7 @@ static void do_display(const struct termios *mode, const int all)
704 continue; 925 continue;
705 } 926 }
706#endif 927#endif
707 wrapf("%s = %s;", control_info[i].name, 928 wrapf("%s = %s;", nth_string(control_name, i),
708 visible(mode->c_cc[control_info[i].offset])); 929 visible(mode->c_cc[control_info[i].offset]));
709 } 930 }
710#if VEOF == VMIN 931#if VEOF == VMIN
@@ -726,12 +947,13 @@ static void do_display(const struct termios *mode, const int all)
726 mask = mode_info[i].mask ? mode_info[i].mask : mode_info[i].bits; 947 mask = mode_info[i].mask ? mode_info[i].mask : mode_info[i].bits;
727 if ((*bitsp & mask) == mode_info[i].bits) { 948 if ((*bitsp & mask) == mode_info[i].bits) {
728 if (all || (mode_info[i].flags & SANE_UNSET)) 949 if (all || (mode_info[i].flags & SANE_UNSET))
729 wrapf("%s", mode_info[i].name); 950 wrapf("-%s"+1, nth_string(mode_name, i));
730 } else { 951 } else {
731 if ((all && mode_info[i].flags & REV) || 952 if ((all && mode_info[i].flags & REV)
732 (!all && 953 || (!all && (mode_info[i].flags & (SANE_SET | REV)) == (SANE_SET | REV))
733 (mode_info[i].flags & (SANE_SET | REV)) == (SANE_SET | REV))) 954 ) {
734 wrapf("-%s", mode_info[i].name); 955 wrapf("-%s", nth_string(mode_name, i));
956 }
735 } 957 }
736 } 958 }
737 if (G.current_col) wrapf("\n"); 959 if (G.current_col) wrapf("\n");
@@ -861,8 +1083,8 @@ static void set_mode(const struct mode_info *info, int reversed,
861 mode->c_oflag &= ~OPOST; 1083 mode->c_oflag &= ~OPOST;
862 } 1084 }
863 } else if (info == &mode_info[IDX_raw] || info == &mode_info[IDX_cooked]) { 1085 } else if (info == &mode_info[IDX_raw] || info == &mode_info[IDX_cooked]) {
864 if ((info->name[0] == 'r' && reversed) 1086 if ((info == &mode_info[IDX_raw] && reversed)
865 || (info->name[0] == 'c' && !reversed) 1087 || (info == &mode_info[IDX_cooked] && !reversed)
866 ) { 1088 ) {
867 /* Cooked mode */ 1089 /* Cooked mode */
868 mode->c_iflag |= BRKINT | IGNPAR | ISTRIP | ICRNL | IXON; 1090 mode->c_iflag |= BRKINT | IGNPAR | ISTRIP | ICRNL | IXON;
@@ -944,11 +1166,12 @@ static void set_control_char_or_die(const struct control_info *info,
944 mode->c_cc[info->offset] = value; 1166 mode->c_cc[info->offset] = value;
945} 1167}
946 1168
947#define STTY_require_set_attr (1<<0) 1169#define STTY_require_set_attr (1 << 0)
948#define STTY_speed_was_set (1<<1) 1170#define STTY_speed_was_set (1 << 1)
949#define STTY_verbose_output (1<<2) 1171#define STTY_verbose_output (1 << 2)
950#define STTY_recoverable_output (1<<3) 1172#define STTY_recoverable_output (1 << 3)
951#define STTY_noargs (1<<4) 1173#define STTY_noargs (1 << 4)
1174
952int stty_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 1175int stty_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
953int stty_main(int argc, char **argv) 1176int stty_main(int argc, char **argv)
954{ 1177{
@@ -959,6 +1182,8 @@ int stty_main(int argc, char **argv)
959 int stty_state; 1182 int stty_state;
960 int k; 1183 int k;
961 1184
1185 INIT_G();
1186
962 stty_state = STTY_noargs; 1187 stty_state = STTY_noargs;
963 output_func = do_display; 1188 output_func = do_display;
964 1189
@@ -1086,8 +1311,8 @@ int stty_main(int argc, char **argv)
1086 /* Now it is safe to start doing things */ 1311 /* Now it is safe to start doing things */
1087 if (file_name) { 1312 if (file_name) {
1088 int fd, fdflags; 1313 int fd, fdflags;
1089 device_name = file_name; 1314 G.device_name = file_name;
1090 fd = xopen(device_name, O_RDONLY | O_NONBLOCK); 1315 fd = xopen(G.device_name, O_RDONLY | O_NONBLOCK);
1091 if (fd != STDIN_FILENO) { 1316 if (fd != STDIN_FILENO) {
1092 dup2(fd, STDIN_FILENO); 1317 dup2(fd, STDIN_FILENO);
1093 close(fd); 1318 close(fd);
@@ -1105,7 +1330,7 @@ int stty_main(int argc, char **argv)
1105 perror_on_device_and_die("%s"); 1330 perror_on_device_and_die("%s");
1106 1331
1107 if (stty_state & (STTY_verbose_output | STTY_recoverable_output | STTY_noargs)) { 1332 if (stty_state & (STTY_verbose_output | STTY_recoverable_output | STTY_noargs)) {
1108 get_terminal_width_height(STDOUT_FILENO, &max_col, NULL); 1333 get_terminal_width_height(STDOUT_FILENO, &G.max_col, NULL);
1109 output_func(&mode, display_all); 1334 output_func(&mode, display_all);
1110 return EXIT_SUCCESS; 1335 return EXIT_SUCCESS;
1111 } 1336 }