Bug #1434 ยป 0001-sh-1-Expand-LINENO-to-the-current-line-number.patch
bin/sh/expand.c | ||
---|---|---|
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 {
|
||
... | ... | |
default:
|
||
abort();
|
||
}
|
||
p[-1] = '='; /* recover overwritten '=' */
|
||
if (subtype != VSNORMAL) { /* skip to end of alternative */
|
||
int nesting = 1;
|
bin/sh/parser.c | ||
---|---|---|
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;
|
||
... | ... | |
/* 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;
|
||
return n;
|
||
} else {
|
||
tokpushback++;
|
||
... | ... | |
*/
|
||
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)) &&
|
||
... | ... | |
typeloc = out - stackblock();
|
||
USTPUTC(VSNORMAL, out);
|
||
subtype = VSNORMAL;
|
||
flags = 0;
|
||
if (c == '{') {
|
||
bracketed_name = 1;
|
||
c = pgetc();
|
||
... | ... | |
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 {
|
||
... | ... | |
c = pgetc();
|
||
}
|
||
}
|
||
flags = 0;
|
||
if (subtype == 0) {
|
||
switch (c) {
|
||
case ':':
|
||
flags = VSNUL;
|
||
flags |= VSNUL;
|
||
c = pgetc();
|
||
/*FALLTHROUGH*/
|
||
default:
|
bin/sh/parser.h | ||
---|---|---|
#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} */
|