summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--bin/sh/eval.c5
-rw-r--r--bin/sh/expand.c1
-rw-r--r--bin/sh/parser.c44
-rw-r--r--bin/sh/parser.h1
-rw-r--r--bin/sh/sh.14
-rw-r--r--tools/regression/bin/sh/execution/set-x3.09
6 files changed, 60 insertions, 4 deletions
diff --git a/bin/sh/eval.c b/bin/sh/eval.c
index 585f91e..92a18e4 100644
--- a/bin/sh/eval.c
+++ b/bin/sh/eval.c
@@ -745,8 +745,9 @@ evalcommand(union node *cmd, int flags, struct backcmd *backcmd)
/* Print the command if xflag is set. */
if (xflag) {
char sep = 0;
- const char *p;
- out2str(ps4val());
+ const char *p, *ps4;
+ ps4 = expandstr(ps4val());
+ out2str(ps4 != NULL ? ps4 : ps4val());
for (sp = varlist.list ; sp ; sp = sp->next) {
if (sep != 0)
out2c(' ');
diff --git a/bin/sh/expand.c b/bin/sh/expand.c
index 108a77c..aaa91ac 100644
--- a/bin/sh/expand.c
+++ b/bin/sh/expand.c
@@ -174,6 +174,7 @@ expandarg(union node *arg, struct arglist *arglist, int flag)
ifslastp = NULL;
argstr(arg->narg.text, flag);
if (arglist == NULL) {
+ STACKSTRNUL(expdest);
return; /* here document expanded */
}
STPUTC('\0', expdest);
diff --git a/bin/sh/parser.c b/bin/sh/parser.c
index 151970b..2fea1ec 100644
--- a/bin/sh/parser.c
+++ b/bin/sh/parser.c
@@ -2029,3 +2029,47 @@ getprompt(void *unused __unused)
ps[i] = '\0';
return (ps);
}
+
+
+const char *
+expandstr(char *ps)
+{
+ union node n;
+ struct jmploc jmploc;
+ struct jmploc *const savehandler = handler;
+ const int saveprompt = doprompt;
+ struct parsefile *const savetopfile = getcurrentfile();
+ struct parser_temp *const saveparser_temp = parser_temp;
+ const char *result = NULL;
+
+ if (!setjmp(jmploc.loc)) {
+ handler = &jmploc;
+ parser_temp = NULL;
+ setinputstring(ps, 1);
+ doprompt = 0;
+ readtoken1(pgetc(), DQSYNTAX, "\n\n", 0);
+ if (backquotelist != NULL)
+ error("Command substitution not allowed here");
+
+ n.narg.type = NARG;
+ n.narg.next = NULL;
+ n.narg.text = wordtext;
+ n.narg.backquote = backquotelist;
+
+ expandarg(&n, NULL, 0);
+ result = stackblock();
+ INTOFF;
+ }
+ handler = savehandler;
+ doprompt = saveprompt;
+ popfilesupto(savetopfile);
+ if (parser_temp != saveparser_temp) {
+ parser_temp_free_all();
+ parser_temp = saveparser_temp;
+ }
+ if (result != NULL) {
+ INTON;
+ } else if (exception == EXINT)
+ raise(SIGINT);
+ return result;
+}
diff --git a/bin/sh/parser.h b/bin/sh/parser.h
index e213e21..9a996d0 100644
--- a/bin/sh/parser.h
+++ b/bin/sh/parser.h
@@ -82,3 +82,4 @@ void fixredir(union node *, const char *, int);
int goodname(const char *);
int isassignment(const char *);
char *getprompt(void *);
+const char *expandstr(char *);
diff --git a/bin/sh/sh.1 b/bin/sh/sh.1
index 42e55d3..0ce07bd 100644
--- a/bin/sh/sh.1
+++ b/bin/sh/sh.1
@@ -32,7 +32,7 @@
.\" from: @(#)sh.1 8.6 (Berkeley) 5/4/95
.\" $FreeBSD$
.\"
-.Dd May 21, 2011
+.Dd June 9, 2011
.Dt SH 1
.Os
.Sh NAME
@@ -324,7 +324,7 @@ Useful for debugging.
Write each command
(preceded by the value of the
.Va PS4
-variable)
+variable subjected to parameter expansion and arithmetic expansion)
to standard error before it is executed.
Useful for debugging.
.El
diff --git a/tools/regression/bin/sh/execution/set-x3.0 b/tools/regression/bin/sh/execution/set-x3.0
new file mode 100644
index 0000000..1ca57ac
--- /dev/null
+++ b/tools/regression/bin/sh/execution/set-x3.0
@@ -0,0 +1,9 @@
+# $FreeBSD$
+
+key='must contain this'
+PS4='$key+ '
+{ r=`set -x; { :; } 2>&1 >/dev/null`; } 2>/dev/null
+case $r in
+*"$key"*) true ;;
+*) false ;;
+esac
OpenPOWER on IntegriCloud