test: code size saving, no logic changes
authorDenis Vlasenko <vda.linux@googlemail.com>
Tue, 1 May 2007 20:07:29 +0000 (20:07 -0000)
committerDenis Vlasenko <vda.linux@googlemail.com>
Tue, 1 May 2007 20:07:29 +0000 (20:07 -0000)
ps: fix warning, make a bit smaller
kill -l: make smaller & know much more signals

function                                             old     new   delta
get_signum                                           121     153     +32
kill_main                                            826     843     +17
get_signame                                           44      36      -8
signals                                              252     224     -28
.rodata                                           131955  131923     -32
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 2/3 up/down: 49/-68)            Total: -19 bytes

coreutils/test.c
libbb/u_signal_names.c
procps/kill.c
procps/ps.c

index e9b6276..70b392f 100644 (file)
@@ -85,12 +85,12 @@ enum token {
        RPAREN,
        OPERAND
 };
-#define __is_int_op(a) (((unsigned char)((a) - INTEQ)) <= 5)
-#define __is_str_op(a) (((unsigned char)((a) - STREZ)) <= 5)
-#define __is_file_op(a) (((unsigned char)((a) - FILNT)) <= 2)
-#define __is_file_access(a) (((unsigned char)((a) - FILRD)) <= 2)
-#define __is_file_type(a) (((unsigned char)((a) - FILREG)) <= 5)
-#define __is_file_bit(a) (((unsigned char)((a) - FILSUID)) <= 2)
+#define is_int_op(a) (((unsigned char)((a) - INTEQ)) <= 5)
+#define is_str_op(a) (((unsigned char)((a) - STREZ)) <= 5)
+#define is_file_op(a) (((unsigned char)((a) - FILNT)) <= 2)
+#define is_file_access(a) (((unsigned char)((a) - FILRD)) <= 2)
+#define is_file_type(a) (((unsigned char)((a) - FILREG)) <= 5)
+#define is_file_bit(a) (((unsigned char)((a) - FILSUID)) <= 2)
 enum token_types {
        UNOP,
        BINOP,
@@ -100,64 +100,67 @@ enum token_types {
 };
 
 static const struct t_op {
-       const char * const op_text;
+       char op_text[4];
        unsigned char op_num, op_type;
 } ops[] = {
-       {
-       "-r", FILRD, UNOP}, {
-       "-w", FILWR, UNOP}, {
-       "-x", FILEX, UNOP}, {
-       "-e", FILEXIST, UNOP}, {
-       "-f", FILREG, UNOP}, {
-       "-d", FILDIR, UNOP}, {
-       "-c", FILCDEV, UNOP}, {
-       "-b", FILBDEV, UNOP}, {
-       "-p", FILFIFO, UNOP}, {
-       "-u", FILSUID, UNOP}, {
-       "-g", FILSGID, UNOP}, {
-       "-k", FILSTCK, UNOP}, {
-       "-s", FILGZ, UNOP}, {
-       "-t", FILTT, UNOP}, {
-       "-z", STREZ, UNOP}, {
-       "-n", STRNZ, UNOP}, {
-       "-h", FILSYM, UNOP},    /* for backwards compat */
-       {
-       "-O", FILUID, UNOP}, {
-       "-G", FILGID, UNOP}, {
-       "-L", FILSYM, UNOP}, {
-       "-S", FILSOCK, UNOP}, {
-       "=", STREQ, BINOP}, {
-       "==", STREQ, BINOP}, {
-       "!=", STRNE, BINOP}, {
-       "<", STRLT, BINOP}, {
-       ">", STRGT, BINOP}, {
-       "-eq", INTEQ, BINOP}, {
-       "-ne", INTNE, BINOP}, {
-       "-ge", INTGE, BINOP}, {
-       "-gt", INTGT, BINOP}, {
-       "-le", INTLE, BINOP}, {
-       "-lt", INTLT, BINOP}, {
-       "-nt", FILNT, BINOP}, {
-       "-ot", FILOT, BINOP}, {
-       "-ef", FILEQ, BINOP}, {
-       "!", UNOT, BUNOP}, {
-       "-a", BAND, BBINOP}, {
-       "-o", BOR, BBINOP}, {
-       "(", LPAREN, PAREN}, {
-       ")", RPAREN, PAREN}, {
-       0, 0, 0}
+       { "-r", FILRD   , UNOP   },
+       { "-w", FILWR   , UNOP   },
+       { "-x", FILEX   , UNOP   },
+       { "-e", FILEXIST, UNOP   },
+       { "-f", FILREG  , UNOP   },
+       { "-d", FILDIR  , UNOP   },
+       { "-c", FILCDEV , UNOP   },
+       { "-b", FILBDEV , UNOP   },
+       { "-p", FILFIFO , UNOP   },
+       { "-u", FILSUID , UNOP   },
+       { "-g", FILSGID , UNOP   },
+       { "-k", FILSTCK , UNOP   },
+       { "-s", FILGZ   , UNOP   },
+       { "-t", FILTT   , UNOP   },
+       { "-z", STREZ   , UNOP   },
+       { "-n", STRNZ   , UNOP   },
+       { "-h", FILSYM  , UNOP   },    /* for backwards compat */
+
+       { "-O" , FILUID , UNOP   },
+       { "-G" , FILGID , UNOP   },
+       { "-L" , FILSYM , UNOP   },
+       { "-S" , FILSOCK, UNOP   },
+       { "="  , STREQ  , BINOP  },
+       { "==" , STREQ  , BINOP  },
+       { "!=" , STRNE  , BINOP  },
+       { "<"  , STRLT  , BINOP  },
+       { ">"  , STRGT  , BINOP  },
+       { "-eq", INTEQ  , BINOP  },
+       { "-ne", INTNE  , BINOP  },
+       { "-ge", INTGE  , BINOP  },
+       { "-gt", INTGT  , BINOP  },
+       { "-le", INTLE  , BINOP  },
+       { "-lt", INTLT  , BINOP  },
+       { "-nt", FILNT  , BINOP  },
+       { "-ot", FILOT  , BINOP  },
+       { "-ef", FILEQ  , BINOP  },
+       { "!"  , UNOT   , BUNOP  },
+       { "-a" , BAND   , BBINOP },
+       { "-o" , BOR    , BBINOP },
+       { "("  , LPAREN , PAREN  },
+       { ")"  , RPAREN , PAREN  },
 };
 
-#ifdef CONFIG_FEATURE_TEST_64
+enum { NUM_OPS = sizeof(ops) / sizeof(ops[0]) };
+
+#if ENABLE_FEATURE_TEST_64
 typedef int64_t arith_t;
 #else
 typedef int arith_t;
 #endif
 
+/* Cannot eliminate these static data (do the G trick)
+ * because of bb_test usage from other applets */
 static char **t_wp;
 static struct t_op const *t_wp_op;
 static gid_t *group_array;
 static int ngroups;
+static jmp_buf leaving;
 
 static enum token t_lex(char *s);
 static arith_t oexpr(enum token n);
@@ -176,8 +179,6 @@ static int test_eaccess(char *path, int mode);
 static int is_a_group_member(gid_t gid);
 static void initialize_group_array(void);
 
-static jmp_buf leaving;
-
 int bb_test(int argc, char **argv)
 {
        int res;
@@ -210,7 +211,7 @@ int bb_test(int argc, char **argv)
         * isn't likely in the case of a shell.  paranoia
         * prevails...
         */
-        ngroups = 0;
+       ngroups = 0;
 
        /* Implement special cases from POSIX.2, section 4.62.4 */
        if (argc == 1)
@@ -223,8 +224,9 @@ int bb_test(int argc, char **argv)
                if (argc == 3)
                        return *argv[2] != '\0';
                _off = argc - 4;
-               if (t_lex(argv[2+_off]), t_wp_op && t_wp_op->op_type == BINOP) {
-                       t_wp = &argv[1+_off];
+               t_lex(argv[2 + _off]);
+               if (t_wp_op && t_wp_op->op_type == BINOP) {
+                       t_wp = &argv[1 + _off];
                        return binop() == 0;
                }
        }
@@ -238,6 +240,7 @@ int bb_test(int argc, char **argv)
        return res;
 }
 
+static void syntax(const char *op, const char *msg) ATTRIBUTE_NORETURN;
 static void syntax(const char *op, const char *msg)
 {
        if (op && *op) {
@@ -296,20 +299,20 @@ static arith_t primary(enum token n)
                if (*++t_wp == NULL)
                        syntax(t_wp_op->op_text, "argument expected");
                if (n == STREZ)
-                       return strlen(*t_wp) == 0;
-               else if (n == STRNZ)
-                       return strlen(*t_wp) != 0;
-               else if (n == FILTT)
+                       return t_wp[0][0] == '\0';
+               if (n == STRNZ)
+                       return t_wp[0][0] != '\0';
+               if (n == FILTT)
                        return isatty(getn(*t_wp));
-               else
-                       return filstat(*t_wp, n);
+               return filstat(*t_wp, n);
        }
 
-       if (t_lex(t_wp[1]), t_wp_op && t_wp_op->op_type == BINOP) {
+       t_lex(t_wp[1]);
+       if (t_wp_op && t_wp_op->op_type == BINOP) {
                return binop();
        }
 
-       return strlen(*t_wp) > 0;
+       return t_wp[0][0] != '\0';
 }
 
 static int binop(void)
@@ -322,10 +325,11 @@ static int binop(void)
        (void) t_lex(*++t_wp);
        op = t_wp_op;
 
-       if ((opnd2 = *++t_wp) == (char *) 0)
+       opnd2 = *++t_wp;
+       if (opnd2 == NULL)
                syntax(op->op_text, "argument expected");
 
-       if (__is_int_op(op->op_num)) {
+       if (is_int_op(op->op_num)) {
                val1 = getn(opnd1);
                val2 = getn(opnd2);
                if (op->op_num == INTEQ)
@@ -341,7 +345,7 @@ static int binop(void)
                if (op->op_num == INTLT)
                        return val1 <  val2;
        }
-       if (__is_str_op(op->op_num)) {
+       if (is_str_op(op->op_num)) {
                val1 = strcmp(opnd1, opnd2);
                if (op->op_num == STREQ)
                        return val1 == 0;
@@ -355,7 +359,7 @@ static int binop(void)
        /* We are sure that these three are by now the only binops we didn't check
         * yet, so we do not check if the class is correct:
         */
-/*     if (__is_file_op(op->op_num)) */
+/*     if (is_file_op(op->op_num)) */
        {
                struct stat b1, b2;
 
@@ -390,7 +394,7 @@ static int filstat(char *nm, enum token mode)
                return 0;
        if (mode == FILEXIST)
                return 1;
-       else if (__is_file_access(mode)) {
+       if (is_file_access(mode)) {
                if (mode == FILRD)
                        i = R_OK;
                if (mode == FILWR)
@@ -399,7 +403,7 @@ static int filstat(char *nm, enum token mode)
                        i = X_OK;
                return test_eaccess(nm, i) == 0;
        }
-       else if (__is_file_type(mode)) {
+       if (is_file_type(mode)) {
                if (mode == FILREG)
                        i = S_IFREG;
                if (mode == FILDIR)
@@ -422,10 +426,10 @@ static int filstat(char *nm, enum token mode)
                        return 0;
 #endif
                }
-filetype:
+ filetype:
                return ((s.st_mode & S_IFMT) == i);
        }
-       else if (__is_file_bit(mode)) {
+       if (is_file_bit(mode)) {
                if (mode == FILSUID)
                        i = S_ISUID;
                if (mode == FILSGID)
@@ -434,33 +438,33 @@ filetype:
                        i = S_ISVTX;
                return ((s.st_mode & i) != 0);
        }
-       else if (mode == FILGZ)
+       if (mode == FILGZ)
                return s.st_size > 0L;
-       else if (mode == FILUID)
+       if (mode == FILUID)
                return s.st_uid == geteuid();
-       else if (mode == FILGID)
+       if (mode == FILGID)
                return s.st_gid == getegid();
-       else
-               return 1; /* NOTREACHED */
-
+       return 1; /* NOTREACHED */
 }
 
 static enum token t_lex(char *s)
 {
-       struct t_op const *op = ops;
+       const struct t_op *op;
 
-       if (s == 0) {
-               t_wp_op = (struct t_op *) 0;
+       t_wp_op = NULL;
+       if (s == NULL) {
                return EOI;
        }
-       while (op->op_text) {
+
+       op = ops;
+       do {
                if (strcmp(s, op->op_text) == 0) {
                        t_wp_op = op;
                        return op->op_num;
                }
                op++;
-       }
-       t_wp_op = (struct t_op *) 0;
+       } while (op < ops + NUM_OPS);
+
        return OPERAND;
 }
 
@@ -469,14 +473,14 @@ static enum token t_lex(char *s)
 static arith_t getn(const char *s)
 {
        char *p;
-#ifdef CONFIG_FEATURE_TEST_64
+#if ENABLE_FEATURE_TEST_64
        long long r;
 #else
        long r;
 #endif
 
        errno = 0;
-#ifdef CONFIG_FEATURE_TEST_64
+#if ENABLE_FEATURE_TEST_64
        r = strtoll(s, &p, 10);
 #else
        r = strtol(s, &p, 10);
@@ -591,4 +595,3 @@ int test_main(int argc, char **argv)
 {
        return bb_test(argc, argv);
 }
-
index 52861d4..dc4c0b2 100644 (file)
 
 #include "libbb.h"
 
-static const struct signal_name {
-       int number;
-       char name[5];
-} signals[] = {
+static const char signals[32][7] = {
        // SUSv3 says kill must support these, and specifies the numerical values,
        // http://www.opengroup.org/onlinepubs/009695399/utilities/kill.html
        // TODO: "[SIG]EXIT" shouldn't work for kill, right?
-       {0, "EXIT"}, {1, "HUP"}, {2, "INT"}, {3, "QUIT"}, {6, "ABRT"}, {9, "KILL"},
-       {14, "ALRM"}, {15, "TERM"},
+       // {0, "EXIT"}, {1, "HUP"}, {2, "INT"}, {3, "QUIT"},
+       // {6, "ABRT"}, {9, "KILL"}, {14, "ALRM"}, {15, "TERM"}
        // And Posix adds the following:
-       {SIGILL, "ILL"}, {SIGTRAP, "TRAP"}, {SIGFPE, "FPE"}, {SIGUSR1, "USR1"},
-       {SIGSEGV, "SEGV"}, {SIGUSR2, "USR2"}, {SIGPIPE, "PIPE"}, {SIGCHLD, "CHLD"},
-       {SIGCONT, "CONT"}, {SIGSTOP, "STOP"}, {SIGTSTP, "TSTP"}, {SIGTTIN, "TTIN"},
-       {SIGTTOU, "TTOU"}
+       // {SIGILL, "ILL"}, {SIGTRAP, "TRAP"}, {SIGFPE, "FPE"}, {SIGUSR1, "USR1"},
+       // {SIGSEGV, "SEGV"}, {SIGUSR2, "USR2"}, {SIGPIPE, "PIPE"}, {SIGCHLD, "CHLD"},
+       // {SIGCONT, "CONT"}, {SIGSTOP, "STOP"}, {SIGTSTP, "TSTP"}, {SIGTTIN, "TTIN"},
+       // {SIGTTOU, "TTOU"}
+       [0] = "EXIT",
+#ifdef SIGHUP
+       [SIGHUP   ] = "HUP",
+#endif
+#ifdef SIGINT
+       [SIGINT   ] = "INT",
+#endif
+#ifdef SIGQUIT
+       [SIGQUIT  ] = "QUIT",
+#endif
+#ifdef SIGILL
+       [SIGILL   ] = "ILL",
+#endif
+#ifdef SIGTRAP
+       [SIGTRAP  ] = "TRAP",
+#endif
+#ifdef SIGABRT
+       [SIGABRT  ] = "ABRT",
+#endif
+#ifdef SIGBUS
+       [SIGBUS   ] = "BUS",
+#endif
+#ifdef SIGFPE
+       [SIGFPE   ] = "FPE",
+#endif
+#ifdef SIGKILL
+       [SIGKILL  ] = "KILL",
+#endif
+#ifdef SIGUSR1
+       [SIGUSR1  ] = "USR1",
+#endif
+#ifdef SIGSEGV
+       [SIGSEGV  ] = "SEGV",
+#endif
+#ifdef SIGUSR2
+       [SIGUSR2  ] = "USR2",
+#endif
+#ifdef SIGPIPE
+       [SIGPIPE  ] = "PIPE",
+#endif
+#ifdef SIGALRM
+       [SIGALRM  ] = "ALRM",
+#endif
+#ifdef SIGTERM
+       [SIGTERM  ] = "TERM",
+#endif
+#ifdef SIGSTKFLT
+       [SIGSTKFLT] = "STKFLT",
+#endif
+#ifdef SIGCHLD
+       [SIGCHLD  ] = "CHLD",
+#endif
+#ifdef SIGCONT
+       [SIGCONT  ] = "CONT",
+#endif
+#ifdef SIGSTOP
+       [SIGSTOP  ] = "STOP",
+#endif
+#ifdef SIGTSTP
+       [SIGTSTP  ] = "TSTP",
+#endif
+#ifdef SIGTTIN
+       [SIGTTIN  ] = "TTIN",
+#endif
+#ifdef SIGTTOU
+       [SIGTTOU  ] = "TTOU",
+#endif
+#ifdef SIGURG
+       [SIGURG   ] = "URG",
+#endif
+#ifdef SIGXCPU
+       [SIGXCPU  ] = "XCPU",
+#endif
+#ifdef SIGXFSZ
+       [SIGXFSZ  ] = "XFSZ",
+#endif
+#ifdef SIGVTALRM
+       [SIGVTALRM] = "VTALRM",
+#endif
+#ifdef SIGPROF
+       [SIGPROF  ] = "PROF",
+#endif
+#ifdef SIGWINCH
+       [SIGWINCH ] = "WINCH",
+#endif
+#ifdef SIGPOLL
+       [SIGPOLL  ] = "POLL",
+#endif
+#ifdef SIGPWR
+       [SIGPWR   ] = "PWR",
+#endif
+#ifdef SIGSYS
+       [SIGSYS   ] = "SYS",
+#endif
 };
 
 // Convert signal name to number.
@@ -32,12 +123,28 @@ int get_signum(const char *name)
        int i;
 
        i = bb_strtou(name, NULL, 10);
-       if (!errno) return i;
-       for (i = 0; i < sizeof(signals) / sizeof(struct signal_name); i++)
-               if (strcasecmp(name, signals[i].name) == 0
-                || (strncasecmp(name, "SIG", 3) == 0
-                    && strcasecmp(&name[3], signals[i].name) == 0))
-                               return signals[i].number;
+       if (!errno)
+               return i;
+       if (strncasecmp(name, "SIG", 3) == 0)
+               name += 3;
+       for (i = 0; i < sizeof(signals) / sizeof(signals[0]); i++)
+               if (strcasecmp(name, signals[i]) == 0)
+                       return i;
+
+#if ENABLE_DESKTOP && (defined(SIGIOT) || defined(SIGIO))
+       /* These are aliased to other names */
+       if ((name[0] | 0x20) == 'i' && (name[1] | 0x20) == 'o') {
+#ifdef SIGIO
+               if (!name[2])
+                       return SIGIO;
+#endif
+#ifdef SIGIOT
+               if ((name[2] | 0x20) == 't' && !name[3])
+                       return SIGIOT;
+#endif
+       }
+#endif
+
        return -1;
 }
 
@@ -45,12 +152,9 @@ int get_signum(const char *name)
 
 const char *get_signame(int number)
 {
-       int i;
-
-       for (i=0; i < sizeof(signals) / sizeof(struct signal_name); i++) {
-               if (number == signals[i].number) {
-                       return signals[i].name;
-               }
+       if ((unsigned)number < sizeof(signals) / sizeof(signals[0])) {
+               if (signals[number][0]) /* if it's not an empty str */
+                       return signals[number];
        }
 
        return itoa(number);
index e2b029d..b325749 100644 (file)
@@ -51,7 +51,9 @@ int kill_main(int argc, char **argv)
                if (argc == 1) {
                        /* Print the whole signal list */
                        for (signo = 1; signo < 32; signo++) {
-                               puts(get_signame(signo));
+                               const char *name = get_signame(signo);
+                               if (!isdigit(name[0]))
+                                       puts(name);
                        }
                } else { /* -l <sig list> */
                        while ((arg = *++argv)) {
index 5128c3d..5545313 100644 (file)
@@ -47,18 +47,21 @@ static void func_pgid(char *buf, int size, const procps_status_t *ps)
        sprintf(buf, "%*u", size, ps->pgid);
 }
 
-static void func_vsz(char *buf, int size, const procps_status_t *ps)
+static void put_u(char *buf, int size, unsigned u)
 {
        char buf5[5];
-       smart_ulltoa5( ((unsigned long long)ps->vsz) << 10, buf5);
+       smart_ulltoa5( ((unsigned long long)u) << 10, buf5);
        sprintf(buf, "%.*s", size, buf5);
 }
 
+static void func_vsz(char *buf, int size, const procps_status_t *ps)
+{
+       put_u(buf, size, ps->vsz);
+}
+
 static void func_rss(char *buf, int size, const procps_status_t *ps)
 {
-       char buf5[5];
-       smart_ulltoa5( ((unsigned long long)ps->rss) << 10, buf5);
-       sprintf(buf, "%.*s", size, buf5);
+       put_u(buf, size, ps->rss);
 }
 
 static void func_tty(char *buf, int size, const procps_status_t *ps)
@@ -383,7 +386,7 @@ int ps_main(int argc, char **argv)
                                len = printf("%5u %-8s        %s ",
                                        p->pid, user, p->state);
                        else
-                               len = printf("%5u %-8s %6ld %s ",
+                               len = printf("%5u %-8s %6u %s ",
                                        p->pid, user, p->vsz, p->state);
                }