Vladimir N. Oleynik writes:
authorEric Andersen <andersen@codepoet.org>
Tue, 29 Jul 2003 06:38:40 +0000 (06:38 -0000)
committerEric Andersen <andersen@codepoet.org>
Tue, 29 Jul 2003 06:38:40 +0000 (06:38 -0000)
Last patch have synced form Manuel Nova III xxreadtoken() function,
corrected (C) form dash debian/copyright, removed my small mistake
with IFS_BROKEN (thanks by Herbert), and synced cmdedit.c from
current CVS (removed libc5 support, your email correction, my (C) year
corertion).

shell/ash.c
shell/cmdedit.c

index 334dc22353277aee97e5eabc654cc42c3fd80b9e..f852b26d386d3d531ad87a567458e98103f6bd73 100644 (file)
@@ -5,6 +5,10 @@
  * Copyright (c) 1989, 1991, 1993, 1994
  *      The Regents of the University of California.  All rights reserved.
  *
+ * Copyright (c) 1997-2003 Herbert Xu <herbert@debian.org>
+ * was re-ported from NetBSD and debianized.
+ *
+ *
  * This code is derived from software contributed to Berkeley by
  * Kenneth Almquist.
  *
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  *
- * This version of ash is adapted from the source in Debian's ash 0.3.8-5
- * package.
- * Maintainer Herbert Xu <herbert@debian.org> (C) 1997-2002
  *
  * Modified by Vladimir Oleynik <dzo@simtreas.ru> to be used in busybox
  *
  *
- * Original copyright notice is retained at the end of this file.
+ * Original BSD copyright notice is retained at the end of this file.
  */
 
 /*
@@ -1485,8 +1486,11 @@ static const char defpathvar[] =
        "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin";
 #ifdef IFS_BROKEN
 static const char defifsvar[] = "IFS= \t\n";
-#endif
+#define defifs (defifsvar + 4)
+#else
 static const char defifs[] = " \t\n";
+#endif
+
 
 static struct var varinit[] = {
 #ifdef IFS_BROKEN
@@ -9848,6 +9852,89 @@ out:
  *  have parseword (readtoken1?) handle both words and redirection.]
  */
 
+#define NEW_xxreadtoken
+#ifdef NEW_xxreadtoken
+
+/* singles must be first! */
+static const char xxreadtoken_chars[7] = { '\n', '(', ')', '&', '|', ';', 0 };
+
+static const char xxreadtoken_tokens[] = {
+       TNL, TLP, TRP,          /* only single occurrence allowed */
+       TBACKGND, TPIPE, TSEMI, /* if single occurrence */
+       TEOF,                   /* corresponds to trailing nul */
+       TAND, TOR, TENDCASE,    /* if double occurrence */
+};
+
+#define xxreadtoken_doubles \
+       (sizeof(xxreadtoken_tokens) - sizeof(xxreadtoken_chars))
+#define xxreadtoken_singles \
+       (sizeof(xxreadtoken_chars) - xxreadtoken_doubles - 1)
+
+static int xxreadtoken()
+{
+       int c;
+
+       if (tokpushback) {
+               tokpushback = 0;
+               return lasttoken;
+       }
+       if (needprompt) {
+               setprompt(2);
+               needprompt = 0;
+       }
+       startlinno = plinno;
+       for (;;) {                      /* until token or start of word found */
+               c = pgetc_macro();
+
+               if ((c != ' ') && (c != '\t')
+#ifdef CONFIG_ASH_ALIAS
+                       && (c != PEOA)
+#endif
+                       ) {
+                       if (c == '#') {
+                               while ((c = pgetc()) != '\n' && c != PEOF);
+                               pungetc();
+                       } else if (c == '\\') {
+                               if (pgetc() != '\n') {
+                                       pungetc();
+                                       goto READTOKEN1;
+                               }
+                               startlinno = ++plinno;
+                               if (doprompt)
+                                       setprompt(2);
+                       } else {
+                               const char *p
+                                       = xxreadtoken_chars + sizeof(xxreadtoken_chars) - 1;
+
+                               if (c != PEOF) {
+                                       if (c == '\n') {
+                                               plinno++;
+                                               needprompt = doprompt;
+                                       }
+
+                                       p = strchr(xxreadtoken_chars, c);
+                                       if (p == NULL) {
+                                         READTOKEN1:
+                                               return readtoken1(c, BASESYNTAX, (char *) NULL, 0);
+                                       }
+
+                                       if (p - xxreadtoken_chars >= xxreadtoken_singles) {
+                                               if (pgetc() == *p) {    /* double occurrence? */
+                                                       p += xxreadtoken_doubles + 1;
+                                               } else {
+                                                       pungetc();
+                                               }
+                                       }
+                               }
+
+                               return lasttoken = xxreadtoken_tokens[p - xxreadtoken_chars];
+                       }
+               }
+       }
+}
+
+
+#else
 #define RETURN(token)   return lasttoken = token
 
 static int
@@ -9918,7 +10005,7 @@ breakloop:
        return readtoken1(c, BASESYNTAX, (char *)NULL, 0);
 #undef RETURN
 }
-
+#endif /* NEW_xxreadtoken */
 
 
 /*
@@ -10909,10 +10996,6 @@ redirect(union node *redir, int flags)
 }
 
 
-
-
-
-
 /*
  * Undo the effects of the last redirection.
  */
@@ -10962,7 +11045,6 @@ clearredir(int drop)
 }
 
 
-
 /*
  * Copy a file descriptor to be >= to.  Returns -1
  * if the source file descriptor is closed, EMPTY if there are no unused
@@ -11073,7 +11155,6 @@ binop:
 }
 
 
-
 static void
 shcmd(union node *cmd, FILE *fp)
 {
@@ -11422,7 +11503,6 @@ trapcmd(int argc, char **argv)
 }
 
 
-
 /*
  * Clear traps on a fork.
  */
@@ -11445,7 +11525,6 @@ clear_traps(void)
 }
 
 
-
 /*
  * Set the signal handler for the specified signal.  The routine figures
  * out what it should be set to.
@@ -11546,7 +11625,6 @@ ignoresig(int signo)
 }
 
 
-
 /*
  * Signal handler.
  */
@@ -11565,7 +11643,6 @@ onsig(int signo)
 }
 
 
-
 /*
  * Called to execute a trap.  Perhaps we should avoid entering new trap
  * handlers while we are executing a trap handler.
@@ -11591,12 +11668,10 @@ dotrap(void)
 }
 
 
-
 /*
  * Controls whether the shell is interactive or not.
  */
 
-
 void
 setinteractive(int on)
 {
@@ -11691,7 +11766,6 @@ exitshell(void)
        }
 #endif
 out:
-       out1c('\n');
        _exit(status);
        /* NOTREACHED */
 }
@@ -11780,7 +11854,6 @@ setvar(const char *name, const char *val, int flags)
 }
 
 
-
 /*
  * Same as setvar except that the variable and value are passed in
  * the first argument as name=value.  Since the first argument will
@@ -11830,7 +11903,6 @@ setvareq(char *s, int flags)
 }
 
 
-
 /*
  * Process a linked list of variable assignments.
  */
@@ -11866,7 +11938,6 @@ lookupvar(const char *name)
 }
 
 
-
 /*
  * Search the environment of a builtin command.
  */
@@ -11884,7 +11955,6 @@ bltinlookup(const char *name)
 }
 
 
-
 /*
  * Generate a list of variables satisfying the given conditions.
  */
@@ -11917,7 +11987,6 @@ listvars(int on, int off, char ***end)
 }
 
 
-
 /*
  * POSIX requires that 'set' (but not export or readonly) output the
  * variables in lexicographic order - by the locale's collating order (sigh).
@@ -12054,7 +12123,6 @@ localcmd(int argc, char **argv)
 
 
 
-
 /*
  * Called after a function returns.
  * Interrupts must be off.
@@ -12568,7 +12636,7 @@ ulimitcmd(int argc, char **argv)
 
                if (all || argptr[1])
                        error("too many arguments");
-               if (strcmp(p, "unlimited") == 0)
+               if (strncmp(p, "unlimited\n", 9) == 0)
                        val = RLIM_INFINITY;
                else {
                        val = (rlim_t) 0;
index 7170672671eb286b181fcd83671afdb0bf6bebfb..0ab1958038742d1e9312c41cc26da972def40164 100644 (file)
@@ -2,14 +2,14 @@
 /*
  * Termios command line History and Editting.
  *
- * Copyright (c) 1986-2001 may safely be consumed by a BSD or GPL license.
+ * Copyright (c) 1986-2003 may safely be consumed by a BSD or GPL license.
  * Written by:   Vladimir Oleynik <dzo@simtreas.ru>
  *
  * Used ideas:
  *      Adam Rogoyski    <rogoyski@cs.utexas.edu>
  *      Dave Cinege      <dcinege@psychosis.com>
  *      Jakub Jelinek (c) 1995
- *      Erik Andersen    <andersee@debian.org> (Majorly adjusted for busybox)
+ *      Erik Andersen    <andersen@codepoet.org> (Majorly adjusted for busybox)
  *
  * This code is 'as is' with no warranty.
  *
@@ -163,11 +163,6 @@ static int my_gid;
 
 #endif  /* CONFIG_FEATURE_COMMAND_TAB_COMPLETION */
 
-/* It seems that libc5 doesn't know what a sighandler_t is... */
-#if (__GLIBC__ <= 2) && (__GLIBC_MINOR__ < 1)
-typedef void (*sighandler_t) (int);
-#endif
-
 static void cmdedit_setwidth(int w, int redraw_flg);
 
 static void win_changed(int nsig)
@@ -264,6 +259,7 @@ static inline void out1str(const char *s)
        if ( s )
                fputs(s, stdout);
 }
+
 static inline void beep(void)
 {
        putchar('\007');