about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog3
-rw-r--r--README23
-rw-r--r--Src/parse.c16
-rw-r--r--Test/E02xtrace.ztst22
4 files changed, 53 insertions, 11 deletions
diff --git a/ChangeLog b/ChangeLog
index 8f39d7263..f1dadc9d0 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,8 @@
 2020-03-22  Daniel Shahaf  <d.s@daniel.shahaf.name>
 
+	* 45583/0009: README, Src/parse.c, Test/E02xtrace.ztst: Add
+	end-of-options guard support to 'function -T'.
+
 	* 45583/0008: Doc/Zsh/grammar.yo, README, Src/exec.c,
 	Src/parse.c, Test/E02xtrace.ztst: Add the 'function -T' syntax.
 
diff --git a/README b/README
index ae4f788bc..d08440ce1 100644
--- a/README
+++ b/README
@@ -43,12 +43,23 @@ name of an external command.  Now it may also be a shell function.  Normal
 command word precedece rules apply, so if you have a function and a command
 with the same name, the function will be used.
 
-The syntax "function -T { ... }" used to define a function named "-T".
-It now defines an anonymous function with single-level tracing enabled ---
-same as "function f { ... }; functions -T f; f", but without naming the
-function.  The syntax "function -T foo { ... }" is similarly affected: it
-now defines a function "foo" with tracing enabled; previously it defined
-two functions, named "-T" and "foo" (see the MULTI_FUNC_DEF option).
+The "function" reserved word, used to define functions, gained a new -T option.
+That affects syntaxes such as:
+
+1. "function -T { ... }".  It used to define a function named "-T".  It
+now defines and executes an anonymous function with single-level tracing
+enabled --- same as "function f { ... }; functions -T f; f", but without
+naming the function.
+
+2. "function -T foo { ... }".  It used to define two functions, named "-T"
+and "foo" (see the MULTI_FUNC_DEF option).  It now defines a function
+"foo" with tracing enabled.
+
+3. "function -- { ... }".  It used to define a function named "--".  It
+now defines and executes an anonymous function.  The "--" is taken to be
+an end-of-options guard (same as "ls --").
+
+The sh-compatible function definition syntax, "f() { ... }", is unchanged.
 
 Incompatibilities since 5.7.1
 -----------------------------
diff --git a/Src/parse.c b/Src/parse.c
index 0342ee1f8..08919b2da 100644
--- a/Src/parse.c
+++ b/Src/parse.c
@@ -1680,10 +1680,18 @@ par_funcdef(int *cmplx)
     p = ecadd(0);
     ecadd(0); /* p + 1 */
 
-    if (tok == STRING && tokstr[0] == Dash &&
-	tokstr[1] == 'T' && !tokstr[2]) {
-	++do_tracing;
-	zshlex();
+    /* Consume an initial (-T), (--), or (-T --).
+     * Anything else is a literal function name.
+     */
+    if (tok == STRING && tokstr[0] == Dash) {
+	if (tokstr[1] == 'T' && !tokstr[2]) {
+	    ++do_tracing;
+	    zshlex();
+	}
+	if (tok == STRING && tokstr[0] == Dash &&
+	    tokstr[1] == Dash && !tokstr[2]) {
+	    zshlex();
+	}
     }
 
     while (tok == STRING) {
diff --git a/Test/E02xtrace.ztst b/Test/E02xtrace.ztst
index d72b2d000..8b9cc89a8 100644
--- a/Test/E02xtrace.ztst
+++ b/Test/E02xtrace.ztst
@@ -199,9 +199,29 @@
 ?+f:0> echo traced named function
 >traced named function
 
- function -T -T { echo trace function literally named "-T" }
+ function -T -- -T { echo trace function literally named "-T" }
  -T
+ function -T -- { echo trace anonymous function }
+ functions -- -- # no output
 0:define traced function: parse test
 ?+-T:0> echo trace function literally named -T
 >trace function literally named -T
+?+(anon):0> echo trace anonymous function
+>trace anonymous function
+
+ function -- g { echo g }
+ g
+ function -- { echo anonymous }
+ functions -- -- # no output
+0:function end-of-"options" syntax, #1
+>g
+>anonymous
+
+ function -- -T { echo runs }
+ functions -- -- # no output
+ echo the definition didn\'t execute it
+ -T
+0:function end-of-"options" syntax, #2
+>the definition didn't execute it
+>runs