Author: jilles
Date: Fri Jan 24 16:40:51 2014
New Revision: 261125
URL: http://svnweb.freebsd.org/changeset/base/261125

Log:
  sh: Solve the alias recursion problem in a less hackish way.
  
  Add the space to avoid alias recursion when the alias is expanded, not when
  it is added.
  
  As a result, displaying an alias via command -v, command -V or type no
  longer erroneously appends a space. Adjust the tests so they now require
  this bug to be absent.

Modified:
  head/bin/sh/alias.c
  head/bin/sh/input.c
  head/bin/sh/tests/builtins/command3.0.stdout
  head/bin/sh/tests/builtins/command5.0.stdout
  head/bin/sh/tests/builtins/command6.0.stdout

Modified: head/bin/sh/alias.c
==============================================================================
--- head/bin/sh/alias.c Fri Jan 24 15:34:22 2014        (r261124)
+++ head/bin/sh/alias.c Fri Jan 24 16:40:51 2014        (r261125)
@@ -68,18 +68,7 @@ setalias(const char *name, const char *v
                if (equal(name, ap->name)) {
                        INTOFF;
                        ckfree(ap->val);
-                       /* See HACK below. */
-#ifdef notyet
                        ap->val = savestr(val);
-#else
-                       {
-                       size_t len = strlen(val);
-                       ap->val = ckmalloc(len + 2);
-                       memcpy(ap->val, val, len);
-                       ap->val[len] = ' ';
-                       ap->val[len+1] = '\0';
-                       }
-#endif
                        INTON;
                        return;
                }
@@ -88,34 +77,7 @@ setalias(const char *name, const char *v
        INTOFF;
        ap = ckmalloc(sizeof (struct alias));
        ap->name = savestr(name);
-       /*
-        * XXX - HACK: in order that the parser will not finish reading the
-        * alias value off the input before processing the next alias, we
-        * dummy up an extra space at the end of the alias.  This is a crock
-        * and should be re-thought.  The idea (if you feel inclined to help)
-        * is to avoid alias recursions.  The mechanism used is: when
-        * expanding an alias, the value of the alias is pushed back on the
-        * input as a string and a pointer to the alias is stored with the
-        * string.  The alias is marked as being in use.  When the input
-        * routine finishes reading the string, it marks the alias not
-        * in use.  The problem is synchronization with the parser.  Since
-        * it reads ahead, the alias is marked not in use before the
-        * resulting token(s) is next checked for further alias sub.  The
-        * H A C K is that we add a little fluff after the alias value
-        * so that the string will not be exhausted.  This is a good
-        * idea ------- ***NOT***
-        */
-#ifdef notyet
        ap->val = savestr(val);
-#else /* hack */
-       {
-       size_t len = strlen(val);
-       ap->val = ckmalloc(len + 2);
-       memcpy(ap->val, val, len);
-       ap->val[len] = ' ';     /* fluff */
-       ap->val[len+1] = '\0';
-       }
-#endif
        ap->flag = 0;
        ap->next = *app;
        *app = ap;
@@ -207,14 +169,8 @@ comparealiases(const void *p1, const voi
 static void
 printalias(const struct alias *a)
 {
-       char *p;
-
        out1fmt("%s=", a->name);
-       /* Don't print the space added above. */
-       p = a->val + strlen(a->val) - 1;
-       *p = '\0';
        out1qstr(a->val);
-       *p = ' ';
        out1c('\n');
 }
 

Modified: head/bin/sh/input.c
==============================================================================
--- head/bin/sh/input.c Fri Jan 24 15:34:22 2014        (r261124)
+++ head/bin/sh/input.c Fri Jan 24 16:40:51 2014        (r261125)
@@ -226,7 +226,14 @@ preadbuffer(void)
        int more;
        char savec;
 
-       if (parsefile->strpush) {
+       while (parsefile->strpush) {
+               /*
+                * Add a space to the end of an alias to ensure that the
+                * alias remains in use while parsing its last word.
+                * This avoids alias recursions.
+                */
+               if (parsenleft == -1 && parsefile->strpush->ap != NULL)
+                       return ' ';
                popstring();
                if (--parsenleft >= 0)
                        return (*parsenextc++);

Modified: head/bin/sh/tests/builtins/command3.0.stdout
==============================================================================
--- head/bin/sh/tests/builtins/command3.0.stdout        Fri Jan 24 15:34:22 
2014        (r261124)
+++ head/bin/sh/tests/builtins/command3.0.stdout        Fri Jan 24 16:40:51 
2014        (r261125)
@@ -4,4 +4,4 @@ true
 fun
 break
 if
-alias foo='bar '
+alias foo=bar

Modified: head/bin/sh/tests/builtins/command5.0.stdout
==============================================================================
--- head/bin/sh/tests/builtins/command5.0.stdout        Fri Jan 24 15:34:22 
2014        (r261124)
+++ head/bin/sh/tests/builtins/command5.0.stdout        Fri Jan 24 16:40:51 
2014        (r261125)
@@ -5,4 +5,4 @@ fun is a shell function
 break is a special shell builtin
 if is a shell keyword
 { is a shell keyword
-foo is an alias for bar 
+foo is an alias for bar

Modified: head/bin/sh/tests/builtins/command6.0.stdout
==============================================================================
--- head/bin/sh/tests/builtins/command6.0.stdout        Fri Jan 24 15:34:22 
2014        (r261124)
+++ head/bin/sh/tests/builtins/command6.0.stdout        Fri Jan 24 16:40:51 
2014        (r261125)
@@ -4,4 +4,4 @@ fun is a shell function
 break is a special shell builtin
 if is a shell keyword
 { is a shell keyword
-foo is an alias for bar 
+foo is an alias for bar
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to