summaryrefslogtreecommitdiffstats
path: root/bin/sh/parser.c
diff options
context:
space:
mode:
authorstefanf <stefanf@FreeBSD.org>2008-05-15 19:55:27 +0000
committerstefanf <stefanf@FreeBSD.org>2008-05-15 19:55:27 +0000
commit91768cb1d914b246d9d97ff8f0f3d5f818bc2e25 (patch)
treeba1d6fa9c2d5b214b9146ad3e13330e205bd76b6 /bin/sh/parser.c
parenta83fe39f55a7280bc3bdf3e078ac29c9ff845178 (diff)
downloadFreeBSD-src-91768cb1d914b246d9d97ff8f0f3d5f818bc2e25.zip
FreeBSD-src-91768cb1d914b246d9d97ff8f0f3d5f818bc2e25.tar.gz
Expand $LINENO to the current line number. This is required by SUSv3's "User
Portability Utilities" option. Often configure scripts generated by the autotools test if $LINENO works and refuse to use /bin/sh if not. Package test run by: pav
Diffstat (limited to 'bin/sh/parser.c')
-rw-r--r--bin/sh/parser.c25
1 files changed, 22 insertions, 3 deletions
diff --git a/bin/sh/parser.c b/bin/sh/parser.c
index fb9abc9..75b4cac 100644
--- a/bin/sh/parser.c
+++ b/bin/sh/parser.c
@@ -94,6 +94,7 @@ STATIC union node *redirnode;
STATIC struct heredoc *heredoc;
STATIC int quoteflag; /* set if (part of) last token was quoted */
STATIC int startlinno; /* line # where last token started */
+STATIC int funclinno; /* line # where the current function started */
/* XXX When 'noaliases' is set to one, no alias expansion takes place. */
static int noaliases = 0;
@@ -567,12 +568,14 @@ simplecmd(union node **rpp, union node *redir)
/* We have a function */
if (readtoken() != TRP)
synexpect(TRP);
+ funclinno = plinno;
#ifdef notdef
if (! goodname(n->narg.text))
synerror("Bad function name");
#endif
n->type = NDEFUN;
n->narg.next = command();
+ funclinno = 0;
goto checkneg;
} else {
tokpushback++;
@@ -1176,12 +1179,15 @@ parseredir: {
*/
parsesub: {
+ char buf[10];
int subtype;
int typeloc;
int flags;
char *p;
static const char types[] = "}-+?=";
- int bracketed_name = 0; /* used to handle ${[0-9]*} variables */
+ int bracketed_name = 0; /* used to handle ${[0-9]*} variables */
+ int i;
+ int linno;
c = pgetc();
if (c != '(' && c != '{' && (is_eof(c) || !is_name(c)) &&
@@ -1200,6 +1206,7 @@ parsesub: {
typeloc = out - stackblock();
USTPUTC(VSNORMAL, out);
subtype = VSNORMAL;
+ flags = 0;
if (c == '{') {
bracketed_name = 1;
c = pgetc();
@@ -1213,10 +1220,23 @@ parsesub: {
subtype = 0;
}
if (!is_eof(c) && is_name(c)) {
+ p = out;
do {
STPUTC(c, out);
c = pgetc();
} while (!is_eof(c) && is_in_name(c));
+ if (out - p == 6 && strncmp(p, "LINENO", 6) == 0) {
+ /* Replace the variable name with the
+ * current line number. */
+ linno = plinno;
+ if (funclinno != 0)
+ linno -= funclinno - 1;
+ snprintf(buf, sizeof(buf), "%d", linno);
+ STADJUST(-6, out);
+ for (i = 0; buf[i] != '\0'; i++)
+ STPUTC(buf[i], out);
+ flags |= VSLINENO;
+ }
} else if (is_digit(c)) {
if (bracketed_name) {
do {
@@ -1239,11 +1259,10 @@ parsesub: {
c = pgetc();
}
}
- flags = 0;
if (subtype == 0) {
switch (c) {
case ':':
- flags = VSNUL;
+ flags |= VSNUL;
c = pgetc();
/*FALLTHROUGH*/
default:
OpenPOWER on IntegriCloud