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