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
This commit is contained in:
Stefan Farfeleder 2008-05-15 19:55:27 +00:00
parent a64b9907e1
commit b71085aacf
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=179022
3 changed files with 35 additions and 7 deletions

View File

@ -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;

View File

@ -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:

View File

@ -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} */