test: code size saving, no logic changes
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

diff --git a/coreutils/test.c b/coreutils/test.c
index e9b6276..70b392f 100644
--- a/coreutils/test.c
+++ b/coreutils/test.c
@@ -85,12 +85,12 @@
 	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 @@
 };
 
 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 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 @@
 	 * 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 @@
 		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 @@
 	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 @@
 		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 @@
 	(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 @@
 		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 @@
 	/* 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 @@
 		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 @@
 			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 @@
 			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 @@
 			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 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 @@
 {
 	return bb_test(argc, argv);
 }
-
diff --git a/libbb/u_signal_names.c b/libbb/u_signal_names.c
index 52861d4..dc4c0b2 100644
--- a/libbb/u_signal_names.c
+++ b/libbb/u_signal_names.c
@@ -9,20 +9,111 @@
 
 #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 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 @@
 
 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);
diff --git a/procps/kill.c b/procps/kill.c
index e2b029d..b325749 100644
--- a/procps/kill.c
+++ b/procps/kill.c
@@ -51,7 +51,9 @@
 		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)) {
diff --git a/procps/ps.c b/procps/ps.c
index 5128c3d..5545313 100644
--- a/procps/ps.c
+++ b/procps/ps.c
@@ -47,18 +47,21 @@
 	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 @@
 				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);
 		}