Author: jilles
Date: Sun Mar 13 20:02:39 2011
New Revision: 219623
URL: http://svn.freebsd.org/changeset/base/219623

Log:
  sh: Fix some parameter expansion variants ${#...}.
  
  These already worked: $# ${#} ${##} ${#-} ${#?}
  These now work as well: ${#+word} ${#-word} ${##word} ${#%word}
  
  There is an ambiguity in the standard with ${#?}: it could be the length of
  $? or it could be $# giving an error in the (impossible) case that it is not
  set. We continue to use the former interpretation as it seems more useful.

Added:
  head/tools/regression/bin/sh/expansion/plus-minus8.0   (contents, props 
changed)
  head/tools/regression/bin/sh/expansion/trim7.0   (contents, props changed)
Modified:
  head/bin/sh/parser.c

Modified: head/bin/sh/parser.c
==============================================================================
--- head/bin/sh/parser.c        Sun Mar 13 20:01:00 2011        (r219622)
+++ head/bin/sh/parser.c        Sun Mar 13 20:02:39 2011        (r219623)
@@ -1447,6 +1447,7 @@ parsesub: {
        int bracketed_name = 0; /* used to handle ${[0-9]*} variables */
        int linno;
        int length;
+       int c1;
 
        c = pgetc();
        if (c != '(' && c != '{' && (is_eof(c) || !is_name(c)) &&
@@ -1473,15 +1474,9 @@ parsesub: {
                if (c == '{') {
                        bracketed_name = 1;
                        c = pgetc();
-                       if (c == '#') {
-                               if ((c = pgetc()) == '}')
-                                       c = '#';
-                               else
-                                       subtype = VSLENGTH;
-                       }
-                       else
-                               subtype = 0;
+                       subtype = 0;
                }
+varname:
                if (!is_eof(c) && is_name(c)) {
                        length = 0;
                        do {
@@ -1511,19 +1506,35 @@ parsesub: {
                                STPUTC(c, out);
                                c = pgetc();
                        }
-               } else {
-                       if (! is_special(c)) {
-                               subtype = VSERROR;
-                               if (c == '}')
-                                       pungetc();
-                               else if (c == '\n' || c == PEOF)
-                                       synerror("Unexpected end of line in 
substitution");
-                               else
-                                       USTPUTC(c, out);
-                       } else {
-                               USTPUTC(c, out);
+               } else if (is_special(c)) {
+                       c1 = c;
+                       c = pgetc();
+                       if (subtype == 0 && c1 == '#') {
+                               subtype = VSLENGTH;
+                               if (strchr(types, c) == NULL && c != ':' &&
+                                   c != '#' && c != '%')
+                                       goto varname;
+                               c1 = c;
                                c = pgetc();
+                               if (c1 != '}' && c == '}') {
+                                       pungetc();
+                                       c = c1;
+                                       goto varname;
+                               }
+                               pungetc();
+                               c = c1;
+                               c1 = '#';
+                               subtype = 0;
                        }
+                       USTPUTC(c1, out);
+               } else {
+                       subtype = VSERROR;
+                       if (c == '}')
+                               pungetc();
+                       else if (c == '\n' || c == PEOF)
+                               synerror("Unexpected end of line in 
substitution");
+                       else
+                               USTPUTC(c, out);
                }
                if (subtype == 0) {
                        switch (c) {

Added: head/tools/regression/bin/sh/expansion/plus-minus8.0
==============================================================================
--- /dev/null   00:00:00 1970   (empty, because file is newly added)
+++ head/tools/regression/bin/sh/expansion/plus-minus8.0        Sun Mar 13 
20:02:39 2011        (r219623)
@@ -0,0 +1,5 @@
+# $FreeBSD$
+
+set -- 1 2 3 4 5 6 7 8 9 10 11 12 13
+[ "${#+hi}" = hi ] || echo '${#+hi} wrong'
+[ "${#-hi}" = 13 ] || echo '${#-hi} wrong'

Added: head/tools/regression/bin/sh/expansion/trim7.0
==============================================================================
--- /dev/null   00:00:00 1970   (empty, because file is newly added)
+++ head/tools/regression/bin/sh/expansion/trim7.0      Sun Mar 13 20:02:39 
2011        (r219623)
@@ -0,0 +1,16 @@
+# $FreeBSD$
+
+set -- 1 2 3 4 5 6 7 8 9 10 11 12 13
+[ "${##1}" = 3 ] || echo '${##1} wrong'
+[ "${###1}" = 3 ] || echo '${###1} wrong'
+[ "${###}" = 13 ] || echo '${###} wrong'
+[ "${#%3}" = 1 ] || echo '${#%3} wrong'
+[ "${#%%3}" = 1 ] || echo '${#%%3} wrong'
+[ "${#%%}" = 13 ] || echo '${#%%} wrong'
+set --
+[ "${##0}" = "" ] || echo '${##0} wrong'
+[ "${###0}" = "" ] || echo '${###0} wrong'
+[ "${###}" = 0 ] || echo '${###} wrong'
+[ "${#%0}" = "" ] || echo '${#%0} wrong'
+[ "${#%%0}" = "" ] || echo '${#%%0} wrong'
+[ "${#%%}" = 0 ] || echo '${#%%} wrong'
_______________________________________________
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