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
This commit is contained in:
Denis Vlasenko 2007-11-24 04:32:49 +00:00
parent fe5e23bf75
commit dd8bbfd084

View File

@ -133,18 +133,27 @@ enum {
#define REV 4 /* Can be turned off by prepending '-' */
#define OMIT 8 /* Don't display value */
/* Each mode */
/* Each mode.
* This structure should be kept as small as humanly possible.
*/
struct mode_info {
const char name[9]; /* Name given on command line */
const unsigned char type; /* Which structure element to change */
const unsigned char flags; /* Setting and display options */
/* were using short here, but ppc32 was unhappy: */
const uint8_t type; /* Which structure element to change */
const uint8_t flags; /* Setting and display options */
/* only these values are ever used, so... */
#if (CSIZE | NLDLY | CRDLY | TABDLY | BSDLY | VTDLY | FFDLY) < 0x100
const uint8_t mask;
#elif (CSIZE | NLDLY | CRDLY | TABDLY | BSDLY | VTDLY | FFDLY) < 0x10000
const uint16_t mask;
#else
const tcflag_t mask; /* Other bits to turn off for this mode */
#endif
/* was using short here, but ppc32 was unhappy */
const tcflag_t bits; /* Bits to set for this mode */
};
enum {
/* Must match mode_info[] order! */
/* Must match mode_name[] and mode_info[] order! */
IDX_evenp = 0,
IDX_parity,
IDX_oddp,
@ -170,151 +179,302 @@ enum {
#endif
};
#define MI_ENTRY(N,T,F,B,M) { N, T, F, M, B }
#define MI_ENTRY(N,T,F,B,M) N "\0"
static const struct mode_info mode_info[] = {
MI_ENTRY("evenp", combination, REV | OMIT, 0, 0 ),
MI_ENTRY("parity", combination, REV | OMIT, 0, 0 ),
MI_ENTRY("oddp", combination, REV | OMIT, 0, 0 ),
MI_ENTRY("nl", combination, REV | OMIT, 0, 0 ),
MI_ENTRY("ek", combination, OMIT, 0, 0 ),
MI_ENTRY("sane", combination, OMIT, 0, 0 ),
MI_ENTRY("cooked", combination, REV | OMIT, 0, 0 ),
MI_ENTRY("raw", combination, REV | OMIT, 0, 0 ),
MI_ENTRY("pass8", combination, REV | OMIT, 0, 0 ),
MI_ENTRY("litout", combination, REV | OMIT, 0, 0 ),
MI_ENTRY("cbreak", combination, REV | OMIT, 0, 0 ),
MI_ENTRY("crt", combination, OMIT, 0, 0 ),
MI_ENTRY("dec", combination, OMIT, 0, 0 ),
/* Mode names given on command line */
static const char mode_name[] =
MI_ENTRY("evenp", combination, REV | OMIT, 0, 0 )
MI_ENTRY("parity", combination, REV | OMIT, 0, 0 )
MI_ENTRY("oddp", combination, REV | OMIT, 0, 0 )
MI_ENTRY("nl", combination, REV | OMIT, 0, 0 )
MI_ENTRY("ek", combination, OMIT, 0, 0 )
MI_ENTRY("sane", combination, OMIT, 0, 0 )
MI_ENTRY("cooked", combination, REV | OMIT, 0, 0 )
MI_ENTRY("raw", combination, REV | OMIT, 0, 0 )
MI_ENTRY("pass8", combination, REV | OMIT, 0, 0 )
MI_ENTRY("litout", combination, REV | OMIT, 0, 0 )
MI_ENTRY("cbreak", combination, REV | OMIT, 0, 0 )
MI_ENTRY("crt", combination, OMIT, 0, 0 )
MI_ENTRY("dec", combination, OMIT, 0, 0 )
#ifdef IXANY
MI_ENTRY("decctlq", combination, REV | OMIT, 0, 0 ),
MI_ENTRY("decctlq", combination, REV | OMIT, 0, 0 )
#endif
#if defined(TABDLY) || defined(OXTABS)
MI_ENTRY("tabs", combination, REV | OMIT, 0, 0 ),
MI_ENTRY("tabs", combination, REV | OMIT, 0, 0 )
#endif
#if defined(XCASE) && defined(IUCLC) && defined(OLCUC)
MI_ENTRY("lcase", combination, REV | OMIT, 0, 0 ),
MI_ENTRY("LCASE", combination, REV | OMIT, 0, 0 ),
MI_ENTRY("lcase", combination, REV | OMIT, 0, 0 )
MI_ENTRY("LCASE", combination, REV | OMIT, 0, 0 )
#endif
MI_ENTRY("parenb", control, REV, PARENB, 0 ),
MI_ENTRY("parodd", control, REV, PARODD, 0 ),
MI_ENTRY("cs5", control, 0, CS5, CSIZE),
MI_ENTRY("cs6", control, 0, CS6, CSIZE),
MI_ENTRY("cs7", control, 0, CS7, CSIZE),
MI_ENTRY("cs8", control, 0, CS8, CSIZE),
MI_ENTRY("hupcl", control, REV, HUPCL, 0 ),
MI_ENTRY("hup", control, REV | OMIT, HUPCL, 0 ),
MI_ENTRY("cstopb", control, REV, CSTOPB, 0 ),
MI_ENTRY("cread", control, SANE_SET | REV, CREAD, 0 ),
MI_ENTRY("clocal", control, REV, CLOCAL, 0 ),
MI_ENTRY("parenb", control, REV, PARENB, 0 )
MI_ENTRY("parodd", control, REV, PARODD, 0 )
MI_ENTRY("cs5", control, 0, CS5, CSIZE)
MI_ENTRY("cs6", control, 0, CS6, CSIZE)
MI_ENTRY("cs7", control, 0, CS7, CSIZE)
MI_ENTRY("cs8", control, 0, CS8, CSIZE)
MI_ENTRY("hupcl", control, REV, HUPCL, 0 )
MI_ENTRY("hup", control, REV | OMIT, HUPCL, 0 )
MI_ENTRY("cstopb", control, REV, CSTOPB, 0 )
MI_ENTRY("cread", control, SANE_SET | REV, CREAD, 0 )
MI_ENTRY("clocal", control, REV, CLOCAL, 0 )
#ifdef CRTSCTS
MI_ENTRY("crtscts", control, REV, CRTSCTS, 0 ),
MI_ENTRY("crtscts", control, REV, CRTSCTS, 0 )
#endif
MI_ENTRY("ignbrk", input, SANE_UNSET | REV, IGNBRK, 0 ),
MI_ENTRY("brkint", input, SANE_SET | REV, BRKINT, 0 ),
MI_ENTRY("ignpar", input, REV, IGNPAR, 0 ),
MI_ENTRY("parmrk", input, REV, PARMRK, 0 ),
MI_ENTRY("inpck", input, REV, INPCK, 0 ),
MI_ENTRY("istrip", input, REV, ISTRIP, 0 ),
MI_ENTRY("inlcr", input, SANE_UNSET | REV, INLCR, 0 ),
MI_ENTRY("igncr", input, SANE_UNSET | REV, IGNCR, 0 ),
MI_ENTRY("icrnl", input, SANE_SET | REV, ICRNL, 0 ),
MI_ENTRY("ixon", input, REV, IXON, 0 ),
MI_ENTRY("ixoff", input, SANE_UNSET | REV, IXOFF, 0 ),
MI_ENTRY("tandem", input, REV | OMIT, IXOFF, 0 ),
MI_ENTRY("ignbrk", input, SANE_UNSET | REV, IGNBRK, 0 )
MI_ENTRY("brkint", input, SANE_SET | REV, BRKINT, 0 )
MI_ENTRY("ignpar", input, REV, IGNPAR, 0 )
MI_ENTRY("parmrk", input, REV, PARMRK, 0 )
MI_ENTRY("inpck", input, REV, INPCK, 0 )
MI_ENTRY("istrip", input, REV, ISTRIP, 0 )
MI_ENTRY("inlcr", input, SANE_UNSET | REV, INLCR, 0 )
MI_ENTRY("igncr", input, SANE_UNSET | REV, IGNCR, 0 )
MI_ENTRY("icrnl", input, SANE_SET | REV, ICRNL, 0 )
MI_ENTRY("ixon", input, REV, IXON, 0 )
MI_ENTRY("ixoff", input, SANE_UNSET | REV, IXOFF, 0 )
MI_ENTRY("tandem", input, REV | OMIT, IXOFF, 0 )
#ifdef IUCLC
MI_ENTRY("iuclc", input, SANE_UNSET | REV, IUCLC, 0 ),
MI_ENTRY("iuclc", input, SANE_UNSET | REV, IUCLC, 0 )
#endif
#ifdef IXANY
MI_ENTRY("ixany", input, SANE_UNSET | REV, IXANY, 0 ),
MI_ENTRY("ixany", input, SANE_UNSET | REV, IXANY, 0 )
#endif
#ifdef IMAXBEL
MI_ENTRY("imaxbel", input, SANE_SET | REV, IMAXBEL, 0 ),
MI_ENTRY("imaxbel", input, SANE_SET | REV, IMAXBEL, 0 )
#endif
MI_ENTRY("opost", output, SANE_SET | REV, OPOST, 0 ),
MI_ENTRY("opost", output, SANE_SET | REV, OPOST, 0 )
#ifdef OLCUC
MI_ENTRY("olcuc", output, SANE_UNSET | REV, OLCUC, 0 ),
MI_ENTRY("olcuc", output, SANE_UNSET | REV, OLCUC, 0 )
#endif
#ifdef OCRNL
MI_ENTRY("ocrnl", output, SANE_UNSET | REV, OCRNL, 0 ),
MI_ENTRY("ocrnl", output, SANE_UNSET | REV, OCRNL, 0 )
#endif
#ifdef ONLCR
MI_ENTRY("onlcr", output, SANE_SET | REV, ONLCR, 0 ),
MI_ENTRY("onlcr", output, SANE_SET | REV, ONLCR, 0 )
#endif
#ifdef ONOCR
MI_ENTRY("onocr", output, SANE_UNSET | REV, ONOCR, 0 ),
MI_ENTRY("onocr", output, SANE_UNSET | REV, ONOCR, 0 )
#endif
#ifdef ONLRET
MI_ENTRY("onlret", output, SANE_UNSET | REV, ONLRET, 0 ),
MI_ENTRY("onlret", output, SANE_UNSET | REV, ONLRET, 0 )
#endif
#ifdef OFILL
MI_ENTRY("ofill", output, SANE_UNSET | REV, OFILL, 0 ),
MI_ENTRY("ofill", output, SANE_UNSET | REV, OFILL, 0 )
#endif
#ifdef OFDEL
MI_ENTRY("ofdel", output, SANE_UNSET | REV, OFDEL, 0 ),
MI_ENTRY("ofdel", output, SANE_UNSET | REV, OFDEL, 0 )
#endif
#ifdef NLDLY
MI_ENTRY("nl1", output, SANE_UNSET, NL1, NLDLY),
MI_ENTRY("nl0", output, SANE_SET, NL0, NLDLY),
MI_ENTRY("nl1", output, SANE_UNSET, NL1, NLDLY)
MI_ENTRY("nl0", output, SANE_SET, NL0, NLDLY)
#endif
#ifdef CRDLY
MI_ENTRY("cr3", output, SANE_UNSET, CR3, CRDLY),
MI_ENTRY("cr2", output, SANE_UNSET, CR2, CRDLY),
MI_ENTRY("cr1", output, SANE_UNSET, CR1, CRDLY),
MI_ENTRY("cr0", output, SANE_SET, CR0, CRDLY),
MI_ENTRY("cr3", output, SANE_UNSET, CR3, CRDLY)
MI_ENTRY("cr2", output, SANE_UNSET, CR2, CRDLY)
MI_ENTRY("cr1", output, SANE_UNSET, CR1, CRDLY)
MI_ENTRY("cr0", output, SANE_SET, CR0, CRDLY)
#endif
#ifdef TABDLY
MI_ENTRY("tab3", output, SANE_UNSET, TAB3, TABDLY),
MI_ENTRY("tab2", output, SANE_UNSET, TAB2, TABDLY),
MI_ENTRY("tab1", output, SANE_UNSET, TAB1, TABDLY),
MI_ENTRY("tab0", output, SANE_SET, TAB0, TABDLY),
MI_ENTRY("tab3", output, SANE_UNSET, TAB3, TABDLY)
MI_ENTRY("tab2", output, SANE_UNSET, TAB2, TABDLY)
MI_ENTRY("tab1", output, SANE_UNSET, TAB1, TABDLY)
MI_ENTRY("tab0", output, SANE_SET, TAB0, TABDLY)
#else
# ifdef OXTABS
MI_ENTRY("tab3", output, SANE_UNSET, OXTABS, 0 ),
MI_ENTRY("tab3", output, SANE_UNSET, OXTABS, 0 )
# endif
#endif
#ifdef BSDLY
MI_ENTRY("bs1", output, SANE_UNSET, BS1, BSDLY),
MI_ENTRY("bs0", output, SANE_SET, BS0, BSDLY),
MI_ENTRY("bs1", output, SANE_UNSET, BS1, BSDLY)
MI_ENTRY("bs0", output, SANE_SET, BS0, BSDLY)
#endif
#ifdef VTDLY
MI_ENTRY("vt1", output, SANE_UNSET, VT1, VTDLY),
MI_ENTRY("vt0", output, SANE_SET, VT0, VTDLY),
MI_ENTRY("vt1", output, SANE_UNSET, VT1, VTDLY)
MI_ENTRY("vt0", output, SANE_SET, VT0, VTDLY)
#endif
#ifdef FFDLY
MI_ENTRY("ff1", output, SANE_UNSET, FF1, FFDLY),
MI_ENTRY("ff0", output, SANE_SET, FF0, FFDLY),
MI_ENTRY("ff1", output, SANE_UNSET, FF1, FFDLY)
MI_ENTRY("ff0", output, SANE_SET, FF0, FFDLY)
#endif
MI_ENTRY("isig", local, SANE_SET | REV, ISIG, 0 ),
MI_ENTRY("icanon", local, SANE_SET | REV, ICANON, 0 ),
MI_ENTRY("isig", local, SANE_SET | REV, ISIG, 0 )
MI_ENTRY("icanon", local, SANE_SET | REV, ICANON, 0 )
#ifdef IEXTEN
MI_ENTRY("iexten", local, SANE_SET | REV, IEXTEN, 0 ),
MI_ENTRY("iexten", local, SANE_SET | REV, IEXTEN, 0 )
#endif
MI_ENTRY("echo", local, SANE_SET | REV, ECHO, 0 ),
MI_ENTRY("echoe", local, SANE_SET | REV, ECHOE, 0 ),
MI_ENTRY("crterase", local, REV | OMIT, ECHOE, 0 ),
MI_ENTRY("echok", local, SANE_SET | REV, ECHOK, 0 ),
MI_ENTRY("echonl", local, SANE_UNSET | REV, ECHONL, 0 ),
MI_ENTRY("noflsh", local, SANE_UNSET | REV, NOFLSH, 0 ),
MI_ENTRY("echo", local, SANE_SET | REV, ECHO, 0 )
MI_ENTRY("echoe", local, SANE_SET | REV, ECHOE, 0 )
MI_ENTRY("crterase", local, REV | OMIT, ECHOE, 0 )
MI_ENTRY("echok", local, SANE_SET | REV, ECHOK, 0 )
MI_ENTRY("echonl", local, SANE_UNSET | REV, ECHONL, 0 )
MI_ENTRY("noflsh", local, SANE_UNSET | REV, NOFLSH, 0 )
#ifdef XCASE
MI_ENTRY("xcase", local, SANE_UNSET | REV, XCASE, 0 ),
MI_ENTRY("xcase", local, SANE_UNSET | REV, XCASE, 0 )
#endif
#ifdef TOSTOP
MI_ENTRY("tostop", local, SANE_UNSET | REV, TOSTOP, 0 ),
MI_ENTRY("tostop", local, SANE_UNSET | REV, TOSTOP, 0 )
#endif
#ifdef ECHOPRT
MI_ENTRY("echoprt", local, SANE_UNSET | REV, ECHOPRT, 0 ),
MI_ENTRY("prterase", local, REV | OMIT, ECHOPRT, 0 ),
MI_ENTRY("echoprt", local, SANE_UNSET | REV, ECHOPRT, 0 )
MI_ENTRY("prterase", local, REV | OMIT, ECHOPRT, 0 )
#endif
#ifdef ECHOCTL
MI_ENTRY("echoctl", local, SANE_SET | REV, ECHOCTL, 0 ),
MI_ENTRY("ctlecho", local, REV | OMIT, ECHOCTL, 0 ),
MI_ENTRY("echoctl", local, SANE_SET | REV, ECHOCTL, 0 )
MI_ENTRY("ctlecho", local, REV | OMIT, ECHOCTL, 0 )
#endif
#ifdef ECHOKE
MI_ENTRY("echoke", local, SANE_SET | REV, ECHOKE, 0 ),
MI_ENTRY("crtkill", local, REV | OMIT, ECHOKE, 0 ),
MI_ENTRY("echoke", local, SANE_SET | REV, ECHOKE, 0 )
MI_ENTRY("crtkill", local, REV | OMIT, ECHOKE, 0 )
#endif
;
#undef MI_ENTRY
#define MI_ENTRY(N,T,F,B,M) { T, F, M, B },
static const struct mode_info mode_info[] = {
/* This should be verbatim cut-n-paste copy of the above MI_ENTRYs */
MI_ENTRY("evenp", combination, REV | OMIT, 0, 0 )
MI_ENTRY("parity", combination, REV | OMIT, 0, 0 )
MI_ENTRY("oddp", combination, REV | OMIT, 0, 0 )
MI_ENTRY("nl", combination, REV | OMIT, 0, 0 )
MI_ENTRY("ek", combination, OMIT, 0, 0 )
MI_ENTRY("sane", combination, OMIT, 0, 0 )
MI_ENTRY("cooked", combination, REV | OMIT, 0, 0 )
MI_ENTRY("raw", combination, REV | OMIT, 0, 0 )
MI_ENTRY("pass8", combination, REV | OMIT, 0, 0 )
MI_ENTRY("litout", combination, REV | OMIT, 0, 0 )
MI_ENTRY("cbreak", combination, REV | OMIT, 0, 0 )
MI_ENTRY("crt", combination, OMIT, 0, 0 )
MI_ENTRY("dec", combination, OMIT, 0, 0 )
#ifdef IXANY
MI_ENTRY("decctlq", combination, REV | OMIT, 0, 0 )
#endif
#if defined(TABDLY) || defined(OXTABS)
MI_ENTRY("tabs", combination, REV | OMIT, 0, 0 )
#endif
#if defined(XCASE) && defined(IUCLC) && defined(OLCUC)
MI_ENTRY("lcase", combination, REV | OMIT, 0, 0 )
MI_ENTRY("LCASE", combination, REV | OMIT, 0, 0 )
#endif
MI_ENTRY("parenb", control, REV, PARENB, 0 )
MI_ENTRY("parodd", control, REV, PARODD, 0 )
MI_ENTRY("cs5", control, 0, CS5, CSIZE)
MI_ENTRY("cs6", control, 0, CS6, CSIZE)
MI_ENTRY("cs7", control, 0, CS7, CSIZE)
MI_ENTRY("cs8", control, 0, CS8, CSIZE)
MI_ENTRY("hupcl", control, REV, HUPCL, 0 )
MI_ENTRY("hup", control, REV | OMIT, HUPCL, 0 )
MI_ENTRY("cstopb", control, REV, CSTOPB, 0 )
MI_ENTRY("cread", control, SANE_SET | REV, CREAD, 0 )
MI_ENTRY("clocal", control, REV, CLOCAL, 0 )
#ifdef CRTSCTS
MI_ENTRY("crtscts", control, REV, CRTSCTS, 0 )
#endif
MI_ENTRY("ignbrk", input, SANE_UNSET | REV, IGNBRK, 0 )
MI_ENTRY("brkint", input, SANE_SET | REV, BRKINT, 0 )
MI_ENTRY("ignpar", input, REV, IGNPAR, 0 )
MI_ENTRY("parmrk", input, REV, PARMRK, 0 )
MI_ENTRY("inpck", input, REV, INPCK, 0 )
MI_ENTRY("istrip", input, REV, ISTRIP, 0 )
MI_ENTRY("inlcr", input, SANE_UNSET | REV, INLCR, 0 )
MI_ENTRY("igncr", input, SANE_UNSET | REV, IGNCR, 0 )
MI_ENTRY("icrnl", input, SANE_SET | REV, ICRNL, 0 )
MI_ENTRY("ixon", input, REV, IXON, 0 )
MI_ENTRY("ixoff", input, SANE_UNSET | REV, IXOFF, 0 )
MI_ENTRY("tandem", input, REV | OMIT, IXOFF, 0 )
#ifdef IUCLC
MI_ENTRY("iuclc", input, SANE_UNSET | REV, IUCLC, 0 )
#endif
#ifdef IXANY
MI_ENTRY("ixany", input, SANE_UNSET | REV, IXANY, 0 )
#endif
#ifdef IMAXBEL
MI_ENTRY("imaxbel", input, SANE_SET | REV, IMAXBEL, 0 )
#endif
MI_ENTRY("opost", output, SANE_SET | REV, OPOST, 0 )
#ifdef OLCUC
MI_ENTRY("olcuc", output, SANE_UNSET | REV, OLCUC, 0 )
#endif
#ifdef OCRNL
MI_ENTRY("ocrnl", output, SANE_UNSET | REV, OCRNL, 0 )
#endif
#ifdef ONLCR
MI_ENTRY("onlcr", output, SANE_SET | REV, ONLCR, 0 )
#endif
#ifdef ONOCR
MI_ENTRY("onocr", output, SANE_UNSET | REV, ONOCR, 0 )
#endif
#ifdef ONLRET
MI_ENTRY("onlret", output, SANE_UNSET | REV, ONLRET, 0 )
#endif
#ifdef OFILL
MI_ENTRY("ofill", output, SANE_UNSET | REV, OFILL, 0 )
#endif
#ifdef OFDEL
MI_ENTRY("ofdel", output, SANE_UNSET | REV, OFDEL, 0 )
#endif
#ifdef NLDLY
MI_ENTRY("nl1", output, SANE_UNSET, NL1, NLDLY)
MI_ENTRY("nl0", output, SANE_SET, NL0, NLDLY)
#endif
#ifdef CRDLY
MI_ENTRY("cr3", output, SANE_UNSET, CR3, CRDLY)
MI_ENTRY("cr2", output, SANE_UNSET, CR2, CRDLY)
MI_ENTRY("cr1", output, SANE_UNSET, CR1, CRDLY)
MI_ENTRY("cr0", output, SANE_SET, CR0, CRDLY)
#endif
#ifdef TABDLY
MI_ENTRY("tab3", output, SANE_UNSET, TAB3, TABDLY)
MI_ENTRY("tab2", output, SANE_UNSET, TAB2, TABDLY)
MI_ENTRY("tab1", output, SANE_UNSET, TAB1, TABDLY)
MI_ENTRY("tab0", output, SANE_SET, TAB0, TABDLY)
#else
# ifdef OXTABS
MI_ENTRY("tab3", output, SANE_UNSET, OXTABS, 0 )
# endif
#endif
#ifdef BSDLY
MI_ENTRY("bs1", output, SANE_UNSET, BS1, BSDLY)
MI_ENTRY("bs0", output, SANE_SET, BS0, BSDLY)
#endif
#ifdef VTDLY
MI_ENTRY("vt1", output, SANE_UNSET, VT1, VTDLY)
MI_ENTRY("vt0", output, SANE_SET, VT0, VTDLY)
#endif
#ifdef FFDLY
MI_ENTRY("ff1", output, SANE_UNSET, FF1, FFDLY)
MI_ENTRY("ff0", output, SANE_SET, FF0, FFDLY)
#endif
MI_ENTRY("isig", local, SANE_SET | REV, ISIG, 0 )
MI_ENTRY("icanon", local, SANE_SET | REV, ICANON, 0 )
#ifdef IEXTEN
MI_ENTRY("iexten", local, SANE_SET | REV, IEXTEN, 0 )
#endif
MI_ENTRY("echo", local, SANE_SET | REV, ECHO, 0 )
MI_ENTRY("echoe", local, SANE_SET | REV, ECHOE, 0 )
MI_ENTRY("crterase", local, REV | OMIT, ECHOE, 0 )
MI_ENTRY("echok", local, SANE_SET | REV, ECHOK, 0 )
MI_ENTRY("echonl", local, SANE_UNSET | REV, ECHONL, 0 )
MI_ENTRY("noflsh", local, SANE_UNSET | REV, NOFLSH, 0 )
#ifdef XCASE
MI_ENTRY("xcase", local, SANE_UNSET | REV, XCASE, 0 )
#endif
#ifdef TOSTOP
MI_ENTRY("tostop", local, SANE_UNSET | REV, TOSTOP, 0 )
#endif
#ifdef ECHOPRT
MI_ENTRY("echoprt", local, SANE_UNSET | REV, ECHOPRT, 0 )
MI_ENTRY("prterase", local, REV | OMIT, ECHOPRT, 0 )
#endif
#ifdef ECHOCTL
MI_ENTRY("echoctl", local, SANE_SET | REV, ECHOCTL, 0 )
MI_ENTRY("ctlecho", local, REV | OMIT, ECHOCTL, 0 )
#endif
#ifdef ECHOKE
MI_ENTRY("echoke", local, SANE_SET | REV, ECHOKE, 0 )
MI_ENTRY("crtkill", local, REV | OMIT, ECHOKE, 0 )
#endif
};
@ -322,15 +482,15 @@ enum {
NUM_mode_info = ARRAY_SIZE(mode_info)
};
/* Control characters */
struct control_info {
const char name[7]; /* Name given on command line */
const unsigned char saneval; /* Value to set for 'stty sane' */
const unsigned char offset; /* Offset in c_cc */
const uint8_t saneval; /* Value to set for 'stty sane' */
const uint8_t offset; /* Offset in c_cc */
};
enum {
/* Must match control_info[] order! */
/* Must match control_name[] and control_info[] order! */
CIDX_intr = 0,
CIDX_quit,
CIDX_erase,
@ -368,60 +528,111 @@ enum {
CIDX_time,
};
static const struct control_info control_info[] = {
{"intr", CINTR, VINTR},
{"quit", CQUIT, VQUIT},
{"erase", CERASE, VERASE},
{"kill", CKILL, VKILL},
{"eof", CEOF, VEOF},
{"eol", CEOL, VEOL},
#define CI_ENTRY(n,s,o) n "\0"
/* Name given on command line */
static const char control_name[] =
CI_ENTRY("intr", CINTR, VINTR )
CI_ENTRY("quit", CQUIT, VQUIT )
CI_ENTRY("erase", CERASE, VERASE )
CI_ENTRY("kill", CKILL, VKILL )
CI_ENTRY("eof", CEOF, VEOF )
CI_ENTRY("eol", CEOL, VEOL )
#ifdef VEOL2
{"eol2", CEOL2, VEOL2},
CI_ENTRY("eol2", CEOL2, VEOL2 )
#endif
#ifdef VSWTCH
{"swtch", CSWTCH, VSWTCH},
CI_ENTRY("swtch", CSWTCH, VSWTCH )
#endif
{"start", CSTART, VSTART},
{"stop", CSTOP, VSTOP},
{"susp", CSUSP, VSUSP},
CI_ENTRY("start", CSTART, VSTART )
CI_ENTRY("stop", CSTOP, VSTOP )
CI_ENTRY("susp", CSUSP, VSUSP )
#ifdef VDSUSP
{"dsusp", CDSUSP, VDSUSP},
CI_ENTRY("dsusp", CDSUSP, VDSUSP )
#endif
#ifdef VREPRINT
{"rprnt", CRPRNT, VREPRINT},
CI_ENTRY("rprnt", CRPRNT, VREPRINT)
#endif
#ifdef VWERASE
{"werase", CWERASE, VWERASE},
CI_ENTRY("werase", CWERASE, VWERASE )
#endif
#ifdef VLNEXT
{"lnext", CLNEXT, VLNEXT},
CI_ENTRY("lnext", CLNEXT, VLNEXT )
#endif
#ifdef VFLUSHO
{"flush", CFLUSHO, VFLUSHO},
CI_ENTRY("flush", CFLUSHO, VFLUSHO )
#endif
#ifdef VSTATUS
{"status", CSTATUS, VSTATUS},
CI_ENTRY("status", CSTATUS, VSTATUS )
#endif
/* These must be last because of the display routines */
{"min", 1, VMIN},
{"time", 0, VTIME},
CI_ENTRY("min", 1, VMIN )
CI_ENTRY("time", 0, VTIME )
;
#undef CI_ENTRY
#define CI_ENTRY(n,s,o) { s, o },
static const struct control_info control_info[] = {
/* This should be verbatim cut-n-paste copy of the above CI_ENTRYs */
CI_ENTRY("intr", CINTR, VINTR )
CI_ENTRY("quit", CQUIT, VQUIT )
CI_ENTRY("erase", CERASE, VERASE )
CI_ENTRY("kill", CKILL, VKILL )
CI_ENTRY("eof", CEOF, VEOF )
CI_ENTRY("eol", CEOL, VEOL )
#ifdef VEOL2
CI_ENTRY("eol2", CEOL2, VEOL2 )
#endif
#ifdef VSWTCH
CI_ENTRY("swtch", CSWTCH, VSWTCH )
#endif
CI_ENTRY("start", CSTART, VSTART )
CI_ENTRY("stop", CSTOP, VSTOP )
CI_ENTRY("susp", CSUSP, VSUSP )
#ifdef VDSUSP
CI_ENTRY("dsusp", CDSUSP, VDSUSP )
#endif
#ifdef VREPRINT
CI_ENTRY("rprnt", CRPRNT, VREPRINT)
#endif
#ifdef VWERASE
CI_ENTRY("werase", CWERASE, VWERASE )
#endif
#ifdef VLNEXT
CI_ENTRY("lnext", CLNEXT, VLNEXT )
#endif
#ifdef VFLUSHO
CI_ENTRY("flush", CFLUSHO, VFLUSHO )
#endif
#ifdef VSTATUS
CI_ENTRY("status", CSTATUS, VSTATUS )
#endif
/* These must be last because of the display routines */
CI_ENTRY("min", 1, VMIN )
CI_ENTRY("time", 0, VTIME )
};
enum {
NUM_control_info = ARRAY_SIZE(control_info)
};
/* The width of the screen, for output wrapping */
static unsigned max_col = 80; /* default */
struct globals {
const char *device_name; // = bb_msg_standard_input;
/* The width of the screen, for output wrapping */
unsigned max_col; // = 80;
/* Current position, to know when to wrap */
unsigned current_col;
char buf[10];
};
#define G (*(struct globals*)&bb_common_bufsiz1)
#define INIT_G() \
do { \
G.device_name = bb_msg_standard_input; \
G.max_col = 80; \
} while (0)
static const char *device_name = bb_msg_standard_input;
/* Return a string that is the printable representation of character CH */
/* Adapted from 'cat' by Torbjorn Granlund */
@ -454,7 +665,7 @@ static const char *visible(unsigned ch)
static tcflag_t *mode_type_flag(unsigned type, const struct termios *mode)
{
static const unsigned char tcflag_offsets[] ALIGN1 = {
static const uint8_t tcflag_offsets[] ALIGN1 = {
offsetof(struct termios, c_cflag), /* control */
offsetof(struct termios, c_iflag), /* input */
offsetof(struct termios, c_oflag), /* output */
@ -484,12 +695,12 @@ static void set_speed_or_die(enum speed_setting type, const char *const arg,
static ATTRIBUTE_NORETURN void perror_on_device_and_die(const char *fmt)
{
bb_perror_msg_and_die(fmt, device_name);
bb_perror_msg_and_die(fmt, G.device_name);
}
static void perror_on_device(const char *fmt)
{
bb_perror_msg(fmt, device_name);
bb_perror_msg(fmt, G.device_name);
}
/* Print format string MESSAGE and optional args.
@ -511,7 +722,7 @@ static void wrapf(const char *message, ...)
if (G.current_col > 0) {
G.current_col++;
if (buf[0] != '\n') {
if (G.current_col + buflen >= max_col) {
if (G.current_col + buflen >= G.max_col) {
bb_putchar('\n');
G.current_col = 0;
} else
@ -526,7 +737,7 @@ static void wrapf(const char *message, ...)
static void set_window_size(const int rows, const int cols)
{
struct winsize win = { 0, 0, 0, 0};
struct winsize win = { 0, 0, 0, 0 };
if (ioctl(STDIN_FILENO, TIOCGWINSZ, &win)) {
if (errno != EINVAL) {
@ -569,20 +780,30 @@ static const struct suffix_mult stty_suffixes[] = {
static const struct mode_info *find_mode(const char *name)
{
int i;
for (i = 0; i < NUM_mode_info; ++i)
if (!strcmp(name, mode_info[i].name))
int i = 0;
const char *m = mode_name;
while (*m) {
if (strcmp(name, m) == 0)
return &mode_info[i];
return 0;
m += strlen(m) + 1;
i++;
}
return NULL;
}
static const struct control_info *find_control(const char *name)
{
int i;
for (i = 0; i < NUM_control_info; ++i)
if (!strcmp(name, control_info[i].name))
int i = 0;
const char *m = mode_name;
while (*m) {
if (strcmp(name, m) == 0)
return &control_info[i];
return 0;
m += strlen(m) + 1;
i++;
}
return NULL;
}
enum {
@ -704,7 +925,7 @@ static void do_display(const struct termios *mode, const int all)
continue;
}
#endif
wrapf("%s = %s;", control_info[i].name,
wrapf("%s = %s;", nth_string(control_name, i),
visible(mode->c_cc[control_info[i].offset]));
}
#if VEOF == VMIN
@ -726,12 +947,13 @@ static void do_display(const struct termios *mode, const int all)
mask = mode_info[i].mask ? mode_info[i].mask : mode_info[i].bits;
if ((*bitsp & mask) == mode_info[i].bits) {
if (all || (mode_info[i].flags & SANE_UNSET))
wrapf("%s", mode_info[i].name);
wrapf("-%s"+1, nth_string(mode_name, i));
} else {
if ((all && mode_info[i].flags & REV) ||
(!all &&
(mode_info[i].flags & (SANE_SET | REV)) == (SANE_SET | REV)))
wrapf("-%s", mode_info[i].name);
if ((all && mode_info[i].flags & REV)
|| (!all && (mode_info[i].flags & (SANE_SET | REV)) == (SANE_SET | REV))
) {
wrapf("-%s", nth_string(mode_name, i));
}
}
}
if (G.current_col) wrapf("\n");
@ -861,8 +1083,8 @@ static void set_mode(const struct mode_info *info, int reversed,
mode->c_oflag &= ~OPOST;
}
} else if (info == &mode_info[IDX_raw] || info == &mode_info[IDX_cooked]) {
if ((info->name[0] == 'r' && reversed)
|| (info->name[0] == 'c' && !reversed)
if ((info == &mode_info[IDX_raw] && reversed)
|| (info == &mode_info[IDX_cooked] && !reversed)
) {
/* Cooked mode */
mode->c_iflag |= BRKINT | IGNPAR | ISTRIP | ICRNL | IXON;
@ -944,11 +1166,12 @@ static void set_control_char_or_die(const struct control_info *info,
mode->c_cc[info->offset] = value;
}
#define STTY_require_set_attr (1<<0)
#define STTY_speed_was_set (1<<1)
#define STTY_verbose_output (1<<2)
#define STTY_recoverable_output (1<<3)
#define STTY_noargs (1<<4)
#define STTY_require_set_attr (1 << 0)
#define STTY_speed_was_set (1 << 1)
#define STTY_verbose_output (1 << 2)
#define STTY_recoverable_output (1 << 3)
#define STTY_noargs (1 << 4)
int stty_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
int stty_main(int argc, char **argv)
{
@ -959,6 +1182,8 @@ int stty_main(int argc, char **argv)
int stty_state;
int k;
INIT_G();
stty_state = STTY_noargs;
output_func = do_display;
@ -1086,8 +1311,8 @@ int stty_main(int argc, char **argv)
/* Now it is safe to start doing things */
if (file_name) {
int fd, fdflags;
device_name = file_name;
fd = xopen(device_name, O_RDONLY | O_NONBLOCK);
G.device_name = file_name;
fd = xopen(G.device_name, O_RDONLY | O_NONBLOCK);
if (fd != STDIN_FILENO) {
dup2(fd, STDIN_FILENO);
close(fd);
@ -1105,7 +1330,7 @@ int stty_main(int argc, char **argv)
perror_on_device_and_die("%s");
if (stty_state & (STTY_verbose_output | STTY_recoverable_output | STTY_noargs)) {
get_terminal_width_height(STDOUT_FILENO, &max_col, NULL);
get_terminal_width_height(STDOUT_FILENO, &G.max_col, NULL);
output_func(&mode, display_all);
return EXIT_SUCCESS;
}