Back in 2007, bb_simple_perror_msg() was introduced to allow for a lower
overhead call to bb_perror_msg() when only a string was being printed
with no parameters. This saves space because it avoids the overhead of a
call to a variadic function. However there has never been a simple
version of bb_error_msg(), and since that time various new calls to
bb_perror_msg() have been added that only take a single parameter and so
could have been using bb_simple_perror_message().

This changeset introduces 'simple' versions of bb_error_msg(),
bb_error_msg_and_die(), bb_herror_msg() and bb_herror_msg_and_die(), and
also overrides the standard versions with macros that use some
preprocessor magic to automatically substitute any calls that only take
a single parameter with the corresponding 'simple' version.

All calls to the standard functions in the codebase that pass something
like ("%s", arg) as the parameters have been replaced with 'simple'
calls, as the macros can't fix these up.

The space saving gained by this (using 'defconfig' on x86_64 with gcc
Ubuntu 6.4.0-17ubuntu1~16.04) was:

------------------------------------------------------------------------------
(add/remove: 3/0 grow/shrink: 4/301 up/down: 73/-910)        Total: -837
bytes
   text    data     bss     dec     hex filename
 936949    4263    1856  943068   e63dc busybox_old
 936098    4263    1856  942217   e6089 busybox_unstripped

Signed-off-by: James Byrne <james.by...@origamienergy.com>
---
 include/libbb.h         | 19 +++++++++++++++++++
 libbb/herror_msg.c      | 10 ++++++++++
 libbb/verror_msg.c      | 10 ++++++++++
 libbb/xgethostbyname.c  |  2 +-
 miscutils/chat.c        |  2 +-
 networking/arp.c        | 10 +++++-----
 networking/tftp.c       |  2 +-
 networking/wget.c       |  2 +-
 shell/hush.c            |  2 +-
 util-linux/acpid.c      |  2 +-
 util-linux/fsck_minix.c |  2 +-
 util-linux/mount.c      |  4 ++--
 12 files changed, 53 insertions(+), 14 deletions(-)

diff --git a/include/libbb.h b/include/libbb.h
index a605c7f..23ad68d 100644
--- a/include/libbb.h
+++ b/include/libbb.h
@@ -1286,19 +1286,38 @@ extern void (*die_func)(void);
 void xfunc_die(void) NORETURN FAST_FUNC;
 void bb_show_usage(void) NORETURN FAST_FUNC;
 void bb_error_msg(const char *s, ...) __attribute__ ((format (printf, 1, 2))) 
FAST_FUNC;
+void bb_simple_error_msg(const char *s) FAST_FUNC;
 void bb_error_msg_and_die(const char *s, ...) __attribute__ ((noreturn, format 
(printf, 1, 2))) FAST_FUNC;
+void bb_simple_error_msg_and_die(const char *s) NORETURN FAST_FUNC;
 void bb_perror_msg(const char *s, ...) __attribute__ ((format (printf, 1, 2))) 
FAST_FUNC;
 void bb_simple_perror_msg(const char *s) FAST_FUNC;
 void bb_perror_msg_and_die(const char *s, ...) __attribute__ ((noreturn, 
format (printf, 1, 2))) FAST_FUNC;
 void bb_simple_perror_msg_and_die(const char *s) NORETURN FAST_FUNC;
 void bb_herror_msg(const char *s, ...) __attribute__ ((format (printf, 1, 2))) 
FAST_FUNC;
+void bb_simple_herror_msg(const char *s) NORETURN FAST_FUNC;
 void bb_herror_msg_and_die(const char *s, ...) __attribute__ ((noreturn, 
format (printf, 1, 2))) FAST_FUNC;
+void bb_simple_herror_msg_and_die(const char *s) NORETURN FAST_FUNC;
 void bb_perror_nomsg_and_die(void) NORETURN FAST_FUNC;
 void bb_perror_nomsg(void) FAST_FUNC;
 void bb_verror_msg(const char *s, va_list p, const char *strerr) FAST_FUNC;
 void bb_die_memory_exhausted(void) NORETURN FAST_FUNC;
 void bb_logenv_override(void) FAST_FUNC;

+/* Override bb_error_msg() and related functions with macros that will
+ * substitute them for the equivalent bb_simple_error_msg() function when
+ * they are used with only a single parameter. Macro approach inspired by
+ * https://gustedt.wordpress.com/2010/06/08/detect-empty-macro-arguments and
+ * https://gustedt.wordpress.com/2010/06/03/default-arguments-for-c99
+ */
+#define _ARG16(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, 
_14, _15, ...) _15
+#define BB_MSG_KIND(...) _ARG16(__VA_ARGS__, , , , , , , , , , , , , , , 
_simple)
+#define _BB_MSG(name, kind, ...) bb##kind##name(__VA_ARGS__)
+#define BB_MSG(name, kind, ...) _BB_MSG(name, kind, __VA_ARGS__)
+#define bb_error_msg(...) BB_MSG(_error_msg, BB_MSG_KIND(__VA_ARGS__), 
__VA_ARGS__)
+#define bb_error_msg_and_die(...) BB_MSG(_error_msg_and_die, 
BB_MSG_KIND(__VA_ARGS__), __VA_ARGS__)
+#define bb_perror_msg(...) BB_MSG(_perror_msg, BB_MSG_KIND(__VA_ARGS__), 
__VA_ARGS__)
+#define bb_perror_msg_and_die(...) BB_MSG(_perror_msg_and_die, 
BB_MSG_KIND(__VA_ARGS__), __VA_ARGS__)
+
 /* We need to export XXX_main from libbusybox
  * only if we build "individual" binaries
  */
diff --git a/libbb/herror_msg.c b/libbb/herror_msg.c
index d041076..a7dd986 100644
--- a/libbb/herror_msg.c
+++ b/libbb/herror_msg.c
@@ -26,3 +26,13 @@ void FAST_FUNC bb_herror_msg_and_die(const char *s, ...)
        va_end(p);
        xfunc_die();
 }
+
+void FAST_FUNC bb_simple_herror_msg(const char *s)
+{
+       bb_herror_msg("%s", s);
+}
+
+void FAST_FUNC bb_simple_herror_msg_and_die(const char *s)
+{
+       bb_herror_msg_and_die("%s", s);
+}
diff --git a/libbb/verror_msg.c b/libbb/verror_msg.c
index 22c3035..155b28c 100644
--- a/libbb/verror_msg.c
+++ b/libbb/verror_msg.c
@@ -180,3 +180,13 @@ void FAST_FUNC bb_error_msg(const char *s, ...)
        bb_verror_msg(s, p, NULL);
        va_end(p);
 }
+
+void FAST_FUNC bb_simple_error_msg(const char *s)
+{
+       bb_error_msg("%s", s);
+}
+
+void FAST_FUNC bb_simple_error_msg_and_die(const char *s)
+{
+       bb_error_msg_and_die("%s", s);
+}
diff --git a/libbb/xgethostbyname.c b/libbb/xgethostbyname.c
index 89d0329..9446dab 100644
--- a/libbb/xgethostbyname.c
+++ b/libbb/xgethostbyname.c
@@ -12,6 +12,6 @@ struct hostent* FAST_FUNC xgethostbyname(const char *name)
 {
        struct hostent *retval = gethostbyname(name);
        if (!retval)
-               bb_herror_msg_and_die("%s", name);
+               bb_simple_herror_msg_and_die(name);
        return retval;
 }
diff --git a/miscutils/chat.c b/miscutils/chat.c
index 2dfe52c..574d514 100644
--- a/miscutils/chat.c
+++ b/miscutils/chat.c
@@ -307,7 +307,7 @@ int chat_main(int argc UNUSED_PARAM, char **argv)
                        } else if (DIR_SAY == key) {
                                // just print argument verbatim
                                // TODO: should we use full_write() to avoid 
unistd/stdio conflict?
-                               bb_error_msg("%s", arg);
+                               bb_simple_error_msg(arg);
                        }
                        // next, please!
                        argv++;
diff --git a/networking/arp.c b/networking/arp.c
index 177ab15..0fe4409 100644
--- a/networking/arp.c
+++ b/networking/arp.c
@@ -116,7 +116,7 @@ static int arp_del(char **args)
        /* Resolve the host name. */
        host = *args;
        if (ap->input(host, &sa) < 0) {
-               bb_herror_msg_and_die("%s", host);
+               bb_simple_herror_msg_and_die(host);
        }

        /* If a host has more than one address, use the correct one! */
@@ -173,7 +173,7 @@ static int arp_del(char **args)
                        if (strcmp(*args, "255.255.255.255") != 0) {
                                host = *args;
                                if (ap->input(host, &sa) < 0) {
-                                       bb_herror_msg_and_die("%s", host);
+                                       bb_simple_herror_msg_and_die(host);
                                }
                                memcpy(&req.arp_netmask, &sa, sizeof(struct 
sockaddr));
                                req.arp_flags |= ATF_NETMASK;
@@ -261,7 +261,7 @@ static int arp_set(char **args)

        host = *args++;
        if (ap->input(host, &sa) < 0) {
-               bb_herror_msg_and_die("%s", host);
+               bb_simple_herror_msg_and_die(host);
        }
        /* If a host has more than one address, use the correct one! */
        memcpy(&req.arp_pa, &sa, sizeof(struct sockaddr));
@@ -326,7 +326,7 @@ static int arp_set(char **args)
                        if (strcmp(*args, "255.255.255.255") != 0) {
                                host = *args;
                                if (ap->input(host, &sa) < 0) {
-                                       bb_herror_msg_and_die("%s", host);
+                                       bb_simple_herror_msg_and_die(host);
                                }
                                memcpy(&req.arp_netmask, &sa, sizeof(struct 
sockaddr));
                                flags |= ATF_NETMASK;
@@ -422,7 +422,7 @@ static int arp_show(char *name)
        if (name != NULL) {
                /* Resolve the host name. */
                if (ap->input(name, &sa) < 0) {
-                       bb_herror_msg_and_die("%s", name);
+                       bb_simple_herror_msg_and_die(name);
                }
                host = xstrdup(ap->sprint(&sa, 1));
        }
diff --git a/networking/tftp.c b/networking/tftp.c
index 4cd3918..0f56380 100644
--- a/networking/tftp.c
+++ b/networking/tftp.c
@@ -736,7 +736,7 @@ static int tftp_protocol(
        strcpy(G_error_pkt_str, bb_msg_read_error);
  send_err_pkt:
        if (G_error_pkt_str[0])
-               bb_error_msg("%s", G_error_pkt_str);
+               bb_simple_error_msg(G_error_pkt_str);
        G.error_pkt[1] = TFTP_ERROR;
        xsendto(socket_fd, G.error_pkt, 4 + 1 + strlen(G_error_pkt_str),
                        &peer_lsa->u.sa, peer_lsa->len);
diff --git a/networking/wget.c b/networking/wget.c
index 30c3392..80683f6 100644
--- a/networking/wget.c
+++ b/networking/wget.c
@@ -772,7 +772,7 @@ static FILE* prepare_ftp_session(FILE **dfpp, struct 
host_info *target, len_and_
 #endif

        if (ftpcmd(NULL, NULL, sfp) != 220)
-               bb_error_msg_and_die("%s", G.wget_buf);
+               bb_simple_error_msg_and_die(G.wget_buf);
                /* note: ftpcmd() sanitizes G.wget_buf, ok to print */

        /* Split username:password pair */
diff --git a/shell/hush.c b/shell/hush.c
index c777001..a5e1745 100644
--- a/shell/hush.c
+++ b/shell/hush.c
@@ -9998,7 +9998,7 @@ static int FAST_FUNC builtin_read(char **argv)
        }

        if ((uintptr_t)r > 1) {
-               bb_error_msg("%s", r);
+               bb_simple_error_msg(r);
                r = (char*)(uintptr_t)1;
        }

diff --git a/util-linux/acpid.c b/util-linux/acpid.c
index 4f491fa..eded6b0 100644
--- a/util-linux/acpid.c
+++ b/util-linux/acpid.c
@@ -148,7 +148,7 @@ static void process_event(const char *event)
        const char *args[] = { "run-parts", handler, NULL };

        // log the event
-       bb_error_msg("%s", event);
+       bb_simple_error_msg(event);

        // spawn handler
        // N.B. run-parts would require scripts to have #!/bin/sh
diff --git a/util-linux/fsck_minix.c b/util-linux/fsck_minix.c
index c4612f2..fc9aecc 100644
--- a/util-linux/fsck_minix.c
+++ b/util-linux/fsck_minix.c
@@ -321,7 +321,7 @@ static void die(const char *str)
 {
        if (termios_set)
                tcsetattr_stdin_TCSANOW(&sv_termios);
-       bb_error_msg_and_die("%s", str);
+       bb_simple_error_msg_and_die(str);
 }

 static void push_filename(const char *name)
diff --git a/util-linux/mount.c b/util-linux/mount.c
index fa2e7b1..41ce2fb 100644
--- a/util-linux/mount.c
+++ b/util-linux/mount.c
@@ -1292,7 +1292,7 @@ static NOINLINE int nfsmount(struct mntent *mp, unsigned 
long vfsflags, char *fi
        if (!inet_aton(hostname, &server_addr.sin_addr)) {
                hp = gethostbyname(hostname);
                if (hp == NULL) {
-                       bb_herror_msg("%s", hostname);
+                       bb_simple_herror_msg(hostname);
                        goto fail;
                }
                if (hp->h_length != (int)sizeof(struct in_addr)) {
@@ -1587,7 +1587,7 @@ static NOINLINE int nfsmount(struct mntent *mp, unsigned 
long vfsflags, char *fi
                } else {
                        hp = gethostbyname(mounthost);
                        if (hp == NULL) {
-                               bb_herror_msg("%s", mounthost);
+                               bb_simple_herror_msg(mounthost);
                                goto fail;
                        }
                        if (hp->h_length != (int)sizeof(struct in_addr)) {
--
2.7.4

The contents of this email and any attachment are confidential to the intended 
recipient(s). If you are not an intended recipient: (i) do not use, disclose, 
distribute, copy or publish this email or its contents; (ii) please contact the 
sender immediately; and (iii) delete this email. Origami Energy Limited 
(company number 8619644); Origami Storage Limited (company number 10436515) and 
OSSPV001 Limited (company number 10933403), each registered in England and each 
with a registered office at: Ashcombe Court, Woolsack Way, Godalming, GU7 1LQ.
_______________________________________________
busybox mailing list
busybox@busybox.net
http://lists.busybox.net/mailman/listinfo/busybox

Reply via email to