diff options
author | stefanf <stefanf@FreeBSD.org> | 2008-05-15 19:55:27 +0000 |
---|---|---|
committer | stefanf <stefanf@FreeBSD.org> | 2008-05-15 19:55:27 +0000 |
commit | 91768cb1d914b246d9d97ff8f0f3d5f818bc2e25 (patch) | |
tree | ba1d6fa9c2d5b214b9146ad3e13330e205bd76b6 /bin/sh/parser.c | |
parent | a83fe39f55a7280bc3bdf3e078ac29c9ff845178 (diff) | |
download | FreeBSD-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.c | 25 |
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: |