hush: fix a bug in argv restoration after sourcing a file
[oweals/busybox.git] / shell / ash.c
index 87f2127a1f491d81da431e2692a2bbe8cb94a0dd..efb4615db10cbf31ff80371089b5277776535411 100644 (file)
  *
  * Licensed under GPLv2 or later, see file LICENSE in this source tree.
  */
-
-/*
- * The following should be set to reflect the type of system you have:
- *      JOBS -> 1 if you have Berkeley job control, 0 otherwise.
- *      define SYSV if you are running under System V.
- *      define DEBUG=1 to compile in debugging ('set -o debug' to turn on)
- *      define DEBUG=2 to compile in and turn on debugging.
- *
- * When debugging is on (DEBUG is 1 and "set -o debug" was executed),
- * debugging info will be written to ./trace and a quit signal
- * will generate a core dump.
- */
-#define DEBUG 0
-/* Tweak debug output verbosity here */
-#define DEBUG_TIME 0
-#define DEBUG_PID 1
-#define DEBUG_SIG 1
-#define DEBUG_INTONOFF 0
-
-#define PROFILE 0
-
-#define JOBS ENABLE_ASH_JOB_CONTROL
-
-#include <setjmp.h>
-#include <fnmatch.h>
-#include <sys/times.h>
-#include <sys/utsname.h> /* for setting $HOSTNAME */
-
-#include "busybox.h" /* for applet_names */
-
-#if defined(__ANDROID_API__) && __ANDROID_API__ <= 24
-/* Bionic at least up to version 24 has no glob() */
-# undef  ENABLE_ASH_INTERNAL_GLOB
-# define ENABLE_ASH_INTERNAL_GLOB 1
-#endif
-
-#if !ENABLE_ASH_INTERNAL_GLOB
-# include <glob.h>
-#endif
-
-#include "unicode.h"
-#include "shell_common.h"
-#if ENABLE_SH_MATH_SUPPORT
-# include "math.h"
-#endif
-#if ENABLE_ASH_RANDOM_SUPPORT
-# include "random.h"
-#else
-# define CLEAR_RANDOM_T(rnd) ((void)0)
-#endif
-
-#include "NUM_APPLETS.h"
-#if NUM_APPLETS == 1
-/* STANDALONE does not make sense, and won't compile */
-# undef CONFIG_FEATURE_SH_STANDALONE
-# undef ENABLE_FEATURE_SH_STANDALONE
-# undef IF_FEATURE_SH_STANDALONE
-# undef IF_NOT_FEATURE_SH_STANDALONE
-# define ENABLE_FEATURE_SH_STANDALONE 0
-# define IF_FEATURE_SH_STANDALONE(...)
-# define IF_NOT_FEATURE_SH_STANDALONE(...) __VA_ARGS__
-#endif
-
-#ifndef PIPE_BUF
-# define PIPE_BUF 4096           /* amount of buffering in a pipe */
-#endif
-
-#if !BB_MMU
-# error "Do not even bother, ash will not run on NOMMU machine"
-#endif
-
 //config:config ASH
 //config:      bool "ash"
 //config:      default y
 //config:        shell (by Herbert Xu), which was created by porting the 'ash' shell
 //config:        (written by Kenneth Almquist) from NetBSD.
 //config:
+//config:# ash options
+//config:# note: Don't remove !NOMMU part in the next line; it would break
+//config:# menuconfig's indenting.
+//config:if !NOMMU && (ASH || SH_IS_ASH || BASH_IS_ASH)
+//config:
 //config:config ASH_OPTIMIZE_FOR_SIZE
 //config:      bool "Optimize for size instead of speed"
 //config:      default y
-//config:      depends on ASH
+//config:      depends on ASH || SH_IS_ASH || BASH_IS_ASH
 //config:      help
 //config:        Compile ash for reduced size at the price of speed.
 //config:
 //config:config ASH_INTERNAL_GLOB
 //config:      bool "Use internal glob() implementation"
-//config:      default n
-//config:      depends on ASH
+//config:      default y       # Y is bigger, but because of uclibc glob() bug, let Y be default for now
+//config:      depends on ASH || SH_IS_ASH || BASH_IS_ASH
 //config:      help
 //config:        Do not use glob() function from libc, use internal implementation.
 //config:        Use this if you are getting "glob.h: No such file or directory"
 //config:config ASH_RANDOM_SUPPORT
 //config:      bool "Pseudorandom generator and $RANDOM variable"
 //config:      default y
-//config:      depends on ASH
+//config:      depends on ASH || SH_IS_ASH || BASH_IS_ASH
 //config:      help
 //config:        Enable pseudorandom generator and dynamic variable "$RANDOM".
 //config:        Each read of "$RANDOM" will generate a new pseudorandom value.
 //config:config ASH_EXPAND_PRMT
 //config:      bool "Expand prompt string"
 //config:      default y
-//config:      depends on ASH
+//config:      depends on ASH || SH_IS_ASH || BASH_IS_ASH
 //config:      help
 //config:        "PS#" may contain volatile content, such as backquote commands.
 //config:        This option recreates the prompt string from the environment
 //config:config ASH_BASH_COMPAT
 //config:      bool "bash-compatible extensions"
 //config:      default y
-//config:      depends on ASH
+//config:      depends on ASH || SH_IS_ASH || BASH_IS_ASH
 //config:      help
 //config:        Enable bash-compatible extensions.
 //config:
 //config:config ASH_IDLE_TIMEOUT
 //config:      bool "Idle timeout variable"
 //config:      default n
-//config:      depends on ASH
+//config:      depends on ASH || SH_IS_ASH || BASH_IS_ASH
 //config:      help
 //config:        Enables bash-like auto-logout after $TMOUT seconds of idle time.
 //config:
 //config:config ASH_JOB_CONTROL
 //config:      bool "Job control"
 //config:      default y
-//config:      depends on ASH
+//config:      depends on ASH || SH_IS_ASH || BASH_IS_ASH
 //config:      help
 //config:        Enable job control in the ash shell.
 //config:
 //config:config ASH_ALIAS
 //config:      bool "Alias support"
 //config:      default y
-//config:      depends on ASH
+//config:      depends on ASH || SH_IS_ASH || BASH_IS_ASH
 //config:      help
 //config:        Enable alias support in the ash shell.
 //config:
 //config:config ASH_GETOPTS
 //config:      bool "Builtin getopt to parse positional parameters"
 //config:      default y
-//config:      depends on ASH
+//config:      depends on ASH || SH_IS_ASH || BASH_IS_ASH
 //config:      help
 //config:        Enable support for getopts builtin in ash.
 //config:
 //config:config ASH_BUILTIN_ECHO
 //config:      bool "Builtin version of 'echo'"
 //config:      default y
-//config:      depends on ASH
+//config:      depends on ASH || SH_IS_ASH || BASH_IS_ASH
 //config:      help
 //config:        Enable support for echo builtin in ash.
 //config:
 //config:config ASH_BUILTIN_PRINTF
 //config:      bool "Builtin version of 'printf'"
 //config:      default y
-//config:      depends on ASH
+//config:      depends on ASH || SH_IS_ASH || BASH_IS_ASH
 //config:      help
 //config:        Enable support for printf builtin in ash.
 //config:
 //config:config ASH_BUILTIN_TEST
 //config:      bool "Builtin version of 'test'"
 //config:      default y
-//config:      depends on ASH
+//config:      depends on ASH || SH_IS_ASH || BASH_IS_ASH
 //config:      help
 //config:        Enable support for test builtin in ash.
 //config:
 //config:config ASH_HELP
 //config:      bool "help builtin"
 //config:      default y
-//config:      depends on ASH
+//config:      depends on ASH || SH_IS_ASH || BASH_IS_ASH
 //config:      help
 //config:        Enable help builtin in ash.
 //config:
 //config:config ASH_CMDCMD
 //config:      bool "'command' command to override shell builtins"
 //config:      default y
-//config:      depends on ASH
+//config:      depends on ASH || SH_IS_ASH || BASH_IS_ASH
 //config:      help
 //config:        Enable support for the ash 'command' builtin, which allows
 //config:        you to run the specified command with the specified arguments,
 //config:
 //config:config ASH_MAIL
 //config:      bool "Check for new mail on interactive shells"
-//config:      default n
-//config:      depends on ASH
+//config:      default y
+//config:      depends on ASH || SH_IS_ASH || BASH_IS_ASH
 //config:      help
 //config:        Enable "check for new mail" function in the ash shell.
 //config:
+//config:endif # ash options
 
 //applet:IF_ASH(APPLET(ash, BB_DIR_BIN, BB_SUID_DROP))
-//applet:IF_FEATURE_SH_IS_ASH(APPLET_ODDNAME(sh, ash, BB_DIR_BIN, BB_SUID_DROP, sh))
-//applet:IF_FEATURE_BASH_IS_ASH(APPLET_ODDNAME(bash, ash, BB_DIR_BIN, BB_SUID_DROP, bash))
+//applet:IF_SH_IS_ASH(APPLET_ODDNAME(sh, ash, BB_DIR_BIN, BB_SUID_DROP, ash))
+//applet:IF_BASH_IS_ASH(APPLET_ODDNAME(bash, ash, BB_DIR_BIN, BB_SUID_DROP, ash))
 
 //kbuild:lib-$(CONFIG_ASH) += ash.o ash_ptr_hack.o shell_common.o
+//kbuild:lib-$(CONFIG_SH_IS_ASH) += ash.o ash_ptr_hack.o shell_common.o
+//kbuild:lib-$(CONFIG_BASH_IS_ASH) += ash.o ash_ptr_hack.o shell_common.o
 //kbuild:lib-$(CONFIG_ASH_RANDOM_SUPPORT) += random.o
 
+/*
+ * The following should be set to reflect the type of system you have:
+ *      JOBS -> 1 if you have Berkeley job control, 0 otherwise.
+ *      define SYSV if you are running under System V.
+ *      define DEBUG=1 to compile in debugging ('set -o debug' to turn on)
+ *      define DEBUG=2 to compile in and turn on debugging.
+ *
+ * When debugging is on (DEBUG is 1 and "set -o debug" was executed),
+ * debugging info will be written to ./trace and a quit signal
+ * will generate a core dump.
+ */
+#define DEBUG 0
+/* Tweak debug output verbosity here */
+#define DEBUG_TIME 0
+#define DEBUG_PID 1
+#define DEBUG_SIG 1
+#define DEBUG_INTONOFF 0
+
+#define PROFILE 0
+
+#define JOBS ENABLE_ASH_JOB_CONTROL
+
+#include <setjmp.h>
+#include <fnmatch.h>
+#include <sys/times.h>
+#include <sys/utsname.h> /* for setting $HOSTNAME */
+
+#include "busybox.h" /* for applet_names */
+
+#if defined(__ANDROID_API__) && __ANDROID_API__ <= 24
+/* Bionic at least up to version 24 has no glob() */
+# undef  ENABLE_ASH_INTERNAL_GLOB
+# define ENABLE_ASH_INTERNAL_GLOB 1
+#endif
+
+#if !ENABLE_ASH_INTERNAL_GLOB && defined(__UCLIBC__)
+# error uClibc glob() is buggy, use ASH_INTERNAL_GLOB.
+# error The bug is: for "$PWD"/<pattern> ash will escape e.g. dashes in "$PWD"
+# error with backslash, even ones which do not need to be: "/a-b" -> "/a\-b"
+# error glob() should unbackslash them and match. uClibc does not unbackslash,
+# error fails to match dirname, subsequently not expanding <pattern> in it.
+// Testcase:
+// if (glob("/etc/polkit\\-1", 0, NULL, &pglob)) - this returns 0 on uclibc, no bug
+// if (glob("/etc/polkit\\-1/*", 0, NULL, &pglob)) printf("uclibc bug!\n");
+#endif
+
+#if !ENABLE_ASH_INTERNAL_GLOB
+# include <glob.h>
+#endif
+
+#include "unicode.h"
+#include "shell_common.h"
+#if ENABLE_FEATURE_SH_MATH
+# include "math.h"
+#endif
+#if ENABLE_ASH_RANDOM_SUPPORT
+# include "random.h"
+#else
+# define CLEAR_RANDOM_T(rnd) ((void)0)
+#endif
+
+#include "NUM_APPLETS.h"
+#if NUM_APPLETS == 1
+/* STANDALONE does not make sense, and won't compile */
+# undef CONFIG_FEATURE_SH_STANDALONE
+# undef ENABLE_FEATURE_SH_STANDALONE
+# undef IF_FEATURE_SH_STANDALONE
+# undef IF_NOT_FEATURE_SH_STANDALONE
+# define ENABLE_FEATURE_SH_STANDALONE 0
+# define IF_FEATURE_SH_STANDALONE(...)
+# define IF_NOT_FEATURE_SH_STANDALONE(...) __VA_ARGS__
+#endif
+
+#ifndef PIPE_BUF
+# define PIPE_BUF 4096           /* amount of buffering in a pipe */
+#endif
+
+#if !BB_MMU
+# error "Do not even bother, ash will not run on NOMMU machine"
+#endif
+
 
 /* ============ Hash table sizes. Configurable. */
 
@@ -1273,6 +1291,8 @@ ash_msg_and_raise_error(const char *msg, ...)
 {
        va_list ap;
 
+       exitstatus = 2;
+
        va_start(ap, msg);
        ash_vmsg_and_raise(EXERROR, msg, ap);
        /* NOTREACHED */
@@ -2135,6 +2155,7 @@ lookupvar(const char *name)
        return NULL;
 }
 
+#if ENABLE_UNICODE_SUPPORT
 static void
 reinit_unicode_for_ash(void)
 {
@@ -2151,6 +2172,9 @@ reinit_unicode_for_ash(void)
                reinit_unicode(s);
        }
 }
+#else
+# define reinit_unicode_for_ash() ((void)0)
+#endif
 
 /*
  * Search the environment of a builtin command.
@@ -2732,7 +2756,7 @@ pwdcmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
 
 #define USE_SIT_FUNCTION ENABLE_ASH_OPTIMIZE_FOR_SIZE
 
-#if ENABLE_SH_MATH_SUPPORT
+#if ENABLE_FEATURE_SH_MATH
 # define SIT_ITEM(a,b,c,d) (a | (b << 4) | (c << 8) | (d << 12))
 #else
 # define SIT_ITEM(a,b,c,d) (a | (b << 4) | (c << 8))
@@ -3113,7 +3137,18 @@ static const uint8_t syntax_index_table[] ALIGN1 = {
 # endif
 };
 
+#if 1
 # define SIT(c, syntax) ((S_I_T[syntax_index_table[c]] >> ((syntax)*4)) & 0xf)
+#else /* debug version, caught one signed char bug */
+# define SIT(c, syntax) \
+       ({ \
+               if ((c) < 0 || (c) > (PEOF + ENABLE_ASH_ALIAS)) \
+                       bb_error_msg_and_die("line:%d c:%d", __LINE__, (c)); \
+               if ((syntax) < 0 || (syntax) > (2 + ENABLE_FEATURE_SH_MATH)) \
+                       bb_error_msg_and_die("line:%d c:%d", __LINE__, (c)); \
+               ((S_I_T[syntax_index_table[c]] >> ((syntax)*4)) & 0xf); \
+       })
+#endif
 
 #endif  /* !USE_SIT_FUNCTION */
 
@@ -4467,7 +4502,7 @@ cmdputs(const char *s)
                case CTLBACKQ:
                        str = "$(...)";
                        goto dostr;
-#if ENABLE_SH_MATH_SUPPORT
+#if ENABLE_FEATURE_SH_MATH
                case CTLARI:
                        str = "$((";
                        goto dostr;
@@ -5398,11 +5433,11 @@ redirect(union node *redir, int flags)
                        /* Careful to not accidentally "save"
                         * to the same fd as right side fd in N>&M */
                        int minfd = right_fd < 10 ? 10 : right_fd + 1;
+#if defined(F_DUPFD_CLOEXEC)
+                       i = fcntl(fd, F_DUPFD_CLOEXEC, minfd);
+#else
                        i = fcntl(fd, F_DUPFD, minfd);
-/* You'd expect copy to be CLOEXECed. Currently these extra "saved" fds
- * are closed in popredir() in the child, preventing them from leaking
- * into child. (popredir() also cleans up the mess in case of failures)
- */
+#endif
                        if (i == -1) {
                                i = errno;
                                if (i != EBADF) {
@@ -5417,6 +5452,9 @@ redirect(union node *redir, int flags)
  remember_to_close:
                                i = CLOSED;
                        } else { /* fd is open, save its copy */
+#if !defined(F_DUPFD_CLOEXEC)
+                               fcntl(i, F_SETFD, FD_CLOEXEC);
+#endif
                                /* "exec fd>&-" should not close fds
                                 * which point to script file(s).
                                 * Force them to be restored afterwards */
@@ -5527,7 +5565,7 @@ redirectsafe(union node *redir, int flags)
  * We have to deal with backquotes, shell variables, and file metacharacters.
  */
 
-#if ENABLE_SH_MATH_SUPPORT
+#if ENABLE_FEATURE_SH_MATH
 static arith_t
 ash_arith(const char *s)
 {
@@ -5615,7 +5653,7 @@ static struct arglist exparg;
 /*
  * Our own itoa().
  */
-#if !ENABLE_SH_MATH_SUPPORT
+#if !ENABLE_FEATURE_SH_MATH
 /* cvtnum() is used even if math support is off (to prepare $? values and such) */
 typedef long arith_t;
 # define ARITH_FMT "%ld"
@@ -5869,14 +5907,15 @@ memtodest(const char *p, size_t len, int syntax, int quotes)
        do {
                unsigned char c = *p++;
                if (c) {
-                       int n = SIT(c, syntax);
-                       if ((quotes & QUOTES_ESC)
-                        && ((n == CCTL)
-                           ||  (((quotes & EXP_FULL) || syntax != BASESYNTAX)
-                               && n == CBACK)
-                               )
-                       ) {
-                               USTPUTC(CTLESC, q);
+                       if (quotes & QUOTES_ESC) {
+                               int n = SIT(c, syntax);
+                               if (n == CCTL
+                                || (((quotes & EXP_FULL) || syntax != BASESYNTAX)
+                                    && n == CBACK
+                                   )
+                               ) {
+                                       USTPUTC(CTLESC, q);
+                               }
                        }
                } else if (!(quotes & QUOTES_KEEPNUL))
                        continue;
@@ -6127,7 +6166,7 @@ expbackq(union node *cmd, int flag)
                stackblock() + startloc));
 }
 
-#if ENABLE_SH_MATH_SUPPORT
+#if ENABLE_FEATURE_SH_MATH
 /*
  * Expand arithmetic expression.  Backup to start of expression,
  * evaluate, place result in (backed up) result, adjust string position.
@@ -6209,7 +6248,7 @@ argstr(char *p, int flags, struct strlist *var_str_list)
                CTLESC,
                CTLVAR,
                CTLBACKQ,
-#if ENABLE_SH_MATH_SUPPORT
+#if ENABLE_FEATURE_SH_MATH
                CTLENDARI,
 #endif
                '\0'
@@ -6245,7 +6284,7 @@ argstr(char *p, int flags, struct strlist *var_str_list)
                c = p[length];
                if (c) {
                        if (!(c & 0x80)
-                       IF_SH_MATH_SUPPORT(|| c == CTLENDARI)
+                       IF_FEATURE_SH_MATH(|| c == CTLENDARI)
                        ) {
                                /* c == '=' || c == ':' || c == CTLENDARI */
                                length++;
@@ -6325,7 +6364,7 @@ argstr(char *p, int flags, struct strlist *var_str_list)
                        expbackq(argbackq->n, flags | inquotes);
                        argbackq = argbackq->next;
                        goto start;
-#if ENABLE_SH_MATH_SUPPORT
+#if ENABLE_FEATURE_SH_MATH
                case CTLENDARI:
                        p--;
                        expari(flags | inquotes);
@@ -9244,7 +9283,7 @@ static int helpcmd(int, char **) FAST_FUNC;
 #if MAX_HISTORY
 static int historycmd(int, char **) FAST_FUNC;
 #endif
-#if ENABLE_SH_MATH_SUPPORT
+#if ENABLE_FEATURE_SH_MATH
 static int letcmd(int, char **) FAST_FUNC;
 #endif
 static int readcmd(int, char **) FAST_FUNC;
@@ -9282,9 +9321,9 @@ static const struct builtincmd builtintab[] = {
        { BUILTIN_SPEC_REG      ":"       , truecmd    },
 #if ENABLE_ASH_BUILTIN_TEST
        { BUILTIN_REGULAR       "["       , testcmd    },
-#if ENABLE_ASH_BASH_COMPAT
+# if ENABLE_ASH_BASH_COMPAT
        { BUILTIN_REGULAR       "[["      , testcmd    },
-#endif
+# endif
 #endif
 #if ENABLE_ASH_ALIAS
        { BUILTIN_REG_ASSG      "alias"   , aliascmd   },
@@ -9324,7 +9363,7 @@ static const struct builtincmd builtintab[] = {
        { BUILTIN_REGULAR       "jobs"    , jobscmd    },
        { BUILTIN_REGULAR       "kill"    , killcmd    },
 #endif
-#if ENABLE_SH_MATH_SUPPORT
+#if ENABLE_FEATURE_SH_MATH
        { BUILTIN_NOSPEC        "let"     , letcmd     },
 #endif
        { BUILTIN_ASSIGN        "local"   , localcmd   },
@@ -9561,11 +9600,13 @@ evalcommand(union node *cmd, int flags)
        }
 
        if (status) {
+ bail:
+               exitstatus = status;
+
                /* We have a redirection error. */
                if (spclbltin > 0)
                        raise_exception(EXERROR);
- bail:
-               exitstatus = status;
+
                goto out;
        }
 
@@ -9869,13 +9910,16 @@ preadfd(void)
                reinit_unicode_for_ash();
                nr = read_line_input(line_input_state, cmdedit_prompt, buf, IBUFSIZ, timeout);
                if (nr == 0) {
-                       /* Ctrl+C pressed */
+                       /* ^C pressed, "convert" to SIGINT */
+                       write(STDOUT_FILENO, "^C", 2);
                        if (trap[SIGINT]) {
                                buf[0] = '\n';
                                buf[1] = '\0';
                                raise(SIGINT);
                                return 1;
                        }
+                       exitstatus = 128 + SIGINT;
+                       bb_putchar('\n');
                        goto retry;
                }
                if (nr < 0) {
@@ -10048,7 +10092,7 @@ pgetc(void)
                return g_parsefile->lastc[--g_parsefile->unget];
 
        if (--g_parsefile->left_in_line >= 0)
-               c = (signed char)*g_parsefile->next_to_pgetc++;
+               c = (unsigned char)*g_parsefile->next_to_pgetc++;
        else
                c = preadbuffer();
 
@@ -11370,13 +11414,13 @@ readtoken1(int c, int syntax, char *eofmark, int striptabs)
        smallint quotef;
        smallint dblquote;
        smallint oldstyle;
-       smallint prevsyntax; /* syntax before arithmetic */
+       IF_FEATURE_SH_MATH(smallint prevsyntax;) /* syntax before arithmetic */
 #if ENABLE_ASH_EXPAND_PRMT
        smallint pssyntax;   /* we are expanding a prompt string */
 #endif
        int varnest;         /* levels of variables expansion */
-       int arinest;         /* levels of arithmetic expansion */
-       int parenlevel;      /* levels of parens in arithmetic */
+       IF_FEATURE_SH_MATH(int arinest;)    /* levels of arithmetic expansion */
+       IF_FEATURE_SH_MATH(int parenlevel;) /* levels of parens in arithmetic */
        int dqvarnest;       /* levels of variables expansion within double quotes */
 
        IF_ASH_BASH_COMPAT(smallint bash_dollar_squote = 0;)
@@ -11384,7 +11428,7 @@ readtoken1(int c, int syntax, char *eofmark, int striptabs)
        startlinno = g_parsefile->linno;
        bqlist = NULL;
        quotef = 0;
-       prevsyntax = 0;
+       IF_FEATURE_SH_MATH(prevsyntax = 0;)
 #if ENABLE_ASH_EXPAND_PRMT
        pssyntax = (syntax == PSSYNTAX);
        if (pssyntax)
@@ -11392,8 +11436,8 @@ readtoken1(int c, int syntax, char *eofmark, int striptabs)
 #endif
        dblquote = (syntax == DQSYNTAX);
        varnest = 0;
-       arinest = 0;
-       parenlevel = 0;
+       IF_FEATURE_SH_MATH(arinest = 0;)
+       IF_FEATURE_SH_MATH(parenlevel = 0;)
        dqvarnest = 0;
 
        STARTSTACKSTR(out);
@@ -11500,7 +11544,7 @@ readtoken1(int c, int syntax, char *eofmark, int striptabs)
                        }
                        USTPUTC(c, out);
                        break;
-#if ENABLE_SH_MATH_SUPPORT
+#if ENABLE_FEATURE_SH_MATH
                case CLP:       /* '(' in arithmetic */
                        parenlevel++;
                        USTPUTC(c, out);
@@ -11551,7 +11595,7 @@ readtoken1(int c, int syntax, char *eofmark, int striptabs)
        } /* for (;;) */
  endword:
 
-#if ENABLE_SH_MATH_SUPPORT
+#if ENABLE_FEATURE_SH_MATH
        if (syntax == ARISYNTAX)
                raise_error_syntax("missing '))'");
 #endif
@@ -11730,7 +11774,7 @@ parsesub: {
        } else if (c == '(') {
                /* $(command) or $((arith)) */
                if (pgetc_eatbnl() == '(') {
-#if ENABLE_SH_MATH_SUPPORT
+#if ENABLE_FEATURE_SH_MATH
                        PARSEARITH();
 #else
                        raise_error_syntax("you disabled math support for $((arith)) syntax");
@@ -11985,7 +12029,7 @@ parsebackq: {
        goto parsebackq_newreturn;
 }
 
-#if ENABLE_SH_MATH_SUPPORT
+#if ENABLE_FEATURE_SH_MATH
 /*
  * Parse an arithmetic expansion (indicate start of one and set state)
  */
@@ -13022,7 +13066,7 @@ timescmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
        return 0;
 }
 
-#if ENABLE_SH_MATH_SUPPORT
+#if ENABLE_FEATURE_SH_MATH
 /*
  * The let builtin. Partially stolen from GNU Bash, the Bourne Again SHell.
  * Copyright (C) 1987, 1989, 1991 Free Software Foundation, Inc.
@@ -13277,15 +13321,6 @@ init(void)
 //usage:#define ash_full_usage "\n\n"
 //usage:       "Unix shell interpreter"
 
-//usage:#if ENABLE_FEATURE_SH_IS_ASH
-//usage:# define sh_trivial_usage ash_trivial_usage
-//usage:# define sh_full_usage    ash_full_usage
-//usage:#endif
-//usage:#if ENABLE_FEATURE_BASH_IS_ASH
-//usage:# define bash_trivial_usage ash_trivial_usage
-//usage:# define bash_full_usage    ash_full_usage
-//usage:#endif
-
 /*
  * Process the shell command line arguments.
  */