summaryrefslogtreecommitdiffstats
path: root/bin
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
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')
-rw-r--r--bin/sh/expand.c9
-rw-r--r--bin/sh/parser.c25
-rw-r--r--bin/sh/parser.h8
3 files changed, 35 insertions, 7 deletions
diff --git a/bin/sh/expand.c b/bin/sh/expand.c
index 1bd7079..2f0b9fd 100644
--- a/bin/sh/expand.c
+++ b/bin/sh/expand.c
@@ -638,7 +638,13 @@ evalvar(char *p, int flag)
special = 1;
p = strchr(p, '=') + 1;
again: /* jump here after setting a variable with ${var=text} */
- if (special) {
+ if (varflags & VSLINENO) {
+ set = 1;
+ special = 0;
+ val = var;
+ p[-1] = '\0'; /* temporarily overwrite '=' to have \0
+ terminated string */
+ } else if (special) {
set = varisset(var, varflags & VSNUL);
val = NULL;
} else {
@@ -768,6 +774,7 @@ record:
default:
abort();
}
+ p[-1] = '='; /* recover overwritten '=' */
if (subtype != VSNORMAL) { /* skip to end of alternative */
int nesting = 1;
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:
diff --git a/bin/sh/parser.h b/bin/sh/parser.h
index 6b5687d..40dd8bd 100644
--- a/bin/sh/parser.h
+++ b/bin/sh/parser.h
@@ -45,9 +45,11 @@
#define CTLQUOTEMARK '\210'
/* variable substitution byte (follows CTLVAR) */
-#define VSTYPE 0x0f /* type of variable substitution */
-#define VSNUL 0x10 /* colon--treat the empty string as unset */
-#define VSQUOTE 0x80 /* inside double quotes--suppress splitting */
+#define VSTYPE 0x0f /* type of variable substitution */
+#define VSNUL 0x10 /* colon--treat the empty string as unset */
+#define VSLINENO 0x20 /* expansion of $LINENO, the line number \
+ follows immediately */
+#define VSQUOTE 0x80 /* inside double quotes--suppress splitting */
/* values of VSTYPE field */
#define VSNORMAL 0x1 /* normal variable: $var or ${var} */
OpenPOWER on IntegriCloud