Module Name: src Committed By: kre Date: Thu May 11 15:07:37 UTC 2017
Modified Files: src/bin/sh: parser.c Log Message: Fix some parser weirdness... ${#VAR:-foo} (or any other modifier on ${#VAR} is a syntax error. On the other hand ${##} is not, nor is ${##13} though they mean quite different things (the latter is an idiom everyone should learn, ... $# except we refuse to admit the possibility that it is 13... Even I cannot explain what ${#-foo} used to do, but it wasn't sane! (It should be just $# as $# is never unset, but ...) Shell syntax is truly a wondrous thing! To generate a diff of this commit: cvs rdiff -u -r1.126 -r1.127 src/bin/sh/parser.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/bin/sh/parser.c diff -u src/bin/sh/parser.c:1.126 src/bin/sh/parser.c:1.127 --- src/bin/sh/parser.c:1.126 Wed May 10 11:06:47 2017 +++ src/bin/sh/parser.c Thu May 11 15:07:37 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: parser.c,v 1.126 2017/05/10 11:06:47 kre Exp $ */ +/* $NetBSD: parser.c,v 1.127 2017/05/11 15:07:37 kre Exp $ */ /*- * Copyright (c) 1991, 1993 @@ -37,7 +37,7 @@ #if 0 static char sccsid[] = "@(#)parser.c 8.7 (Berkeley) 5/16/95"; #else -__RCSID("$NetBSD: parser.c,v 1.126 2017/05/10 11:06:47 kre Exp $"); +__RCSID("$NetBSD: parser.c,v 1.127 2017/05/11 15:07:37 kre Exp $"); #endif #endif /* not lint */ @@ -1748,10 +1748,34 @@ parsesub: { if (c == OPENBRACE) { c = pgetc_linecont(); if (c == '#') { - if ((c = pgetc()) == CLOSEBRACE) + if ((c = pgetc_linecont()) == CLOSEBRACE) c = '#'; - else + else if (is_name(c) || isdigit(c)) subtype = VSLENGTH; + else if (is_special(c)) { + /* + * ${##} is the length of ${#} + * ${##1} is ${#} with leading 1 gone + * + * this stuff is UGLY! + */ + if (pgetc_linecont() == CLOSEBRACE) { + pungetc(); + subtype = VSLENGTH; + } else { + static char cbuf[2]; + pungetc(); + cbuf[0] = c; + cbuf[1] = '\0'; + pushstring(cbuf, 1, NULL); + c = '#'; + subtype = 0; + } + } else { + pungetc(); + c = '#'; + subtype = 0; + } } else subtype = 0; @@ -1818,6 +1842,8 @@ parsesub: { } } } else { + if (subtype == VSLENGTH && c != /*{*/ '}') + synerror("no modifiers allowed with ${#var}"); pungetc(); } if (ISDBLQUOTE() || arinest)