Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 9 Jun 2011 23:12:23 +0000 (UTC)
From:      Jilles Tjoelker <jilles@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r222907 - in head: bin/sh tools/regression/bin/sh/execution
Message-ID:  <201106092312.p59NCNqY098685@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: jilles
Date: Thu Jun  9 23:12:23 2011
New Revision: 222907
URL: http://svn.freebsd.org/changeset/base/222907

Log:
  sh: Do parameter expansion before printing PS4 (set -x).
  
  The function name expandstr() and the general idea of doing this kind of
  expansion by treating the text as a here document without end marker is from
  dash.
  
  All variants of parameter expansion and arithmetic expansion also work (the
  latter is not required by POSIX but it does not take extra code and many
  other shells also allow it).
  
  Command substitution is prevented because I think it causes too much code to
  be re-entered (for example creating an unbounded recursion of trace lines).
  
  Unfortunately, our LINENO is somewhat crude, otherwise PS4='$LINENO+ ' would
  be quite useful.

Added:
  head/tools/regression/bin/sh/execution/set-x3.0   (contents, props changed)
Modified:
  head/bin/sh/eval.c
  head/bin/sh/expand.c
  head/bin/sh/parser.c
  head/bin/sh/parser.h
  head/bin/sh/sh.1

Modified: head/bin/sh/eval.c
==============================================================================
--- head/bin/sh/eval.c	Thu Jun  9 22:52:57 2011	(r222906)
+++ head/bin/sh/eval.c	Thu Jun  9 23:12:23 2011	(r222907)
@@ -745,8 +745,9 @@ evalcommand(union node *cmd, int flags, 
 	/* 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(' ');

Modified: head/bin/sh/expand.c
==============================================================================
--- head/bin/sh/expand.c	Thu Jun  9 22:52:57 2011	(r222906)
+++ head/bin/sh/expand.c	Thu Jun  9 23:12:23 2011	(r222907)
@@ -174,6 +174,7 @@ expandarg(union node *arg, struct arglis
 	ifslastp = NULL;
 	argstr(arg->narg.text, flag);
 	if (arglist == NULL) {
+		STACKSTRNUL(expdest);
 		return;			/* here document expanded */
 	}
 	STPUTC('\0', expdest);

Modified: head/bin/sh/parser.c
==============================================================================
--- head/bin/sh/parser.c	Thu Jun  9 22:52:57 2011	(r222906)
+++ head/bin/sh/parser.c	Thu Jun  9 23:12:23 2011	(r222907)
@@ -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;
+}

Modified: head/bin/sh/parser.h
==============================================================================
--- head/bin/sh/parser.h	Thu Jun  9 22:52:57 2011	(r222906)
+++ head/bin/sh/parser.h	Thu Jun  9 23:12:23 2011	(r222907)
@@ -82,3 +82,4 @@ void fixredir(union node *, const char *
 int goodname(const char *);
 int isassignment(const char *);
 char *getprompt(void *);
+const char *expandstr(char *);

Modified: head/bin/sh/sh.1
==============================================================================
--- head/bin/sh/sh.1	Thu Jun  9 22:52:57 2011	(r222906)
+++ head/bin/sh/sh.1	Thu Jun  9 23:12:23 2011	(r222907)
@@ -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

Added: head/tools/regression/bin/sh/execution/set-x3.0
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/tools/regression/bin/sh/execution/set-x3.0	Thu Jun  9 23:12:23 2011	(r222907)
@@ -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



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201106092312.p59NCNqY098685>