Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Re: Proof of concept: "static" parameter scope



On Sep 25, 10:15am, Peter Stephenson wrote:
} Subject: Re: Proof of concept: "static" parameter scope
}
} On Thu, 24 Sep 2015 19:23:05 -0700
} Bart Schaefer <schaefer@xxxxxxxxxxxxxxxx> wrote:
} > Modules can't declare keywords, so this isn't able to support the new
} > array assignment syntax used by "local" et al.  However, the entry point
} > is coded to match that call signature.
} 
} I think the biggest issue with fixing this is it's going to change the
} "features" interface to modules as we'll have to add a feature type that
} defines a typeset-style interface (and a corresponding reserved word,
} but I think we can tie the two together).

Or ... 


diff --git a/Doc/Zsh/mod_static.yo b/Doc/Zsh/mod_static.yo
index 4342a92..6b461e7 100644
--- a/Doc/Zsh/mod_static.yo
+++ b/Doc/Zsh/mod_static.yo
@@ -36,6 +36,11 @@ parameter.  This may change in the future.
 )
 enditem()
 
+The module also adds the option `tt(-S)' to the `tt(local)' builtin.
+Using `tt(local -S)' is equivalent to calling `tt(static)', but allows
+use of array assignment (parenthesized word list) syntax in the
+declaration.
+
 Parameters declared with tt(static) have the following properties:
 ifnzman()
 startitemize()
diff --git a/Src/Modules/param_static.c b/Src/Modules/param_static.c
index b6c2403..c5354b2 100644
--- a/Src/Modules/param_static.c
+++ b/Src/Modules/param_static.c
@@ -172,6 +172,13 @@ bin_static(char *nam, char **args, LinkList assigns, Options ops, int func)
     int from_typeset = 1;
     makestatic_error = 0;
 
+    if (!OPT_ISSET(ops, 'S'))
+	return bin_typeset(nam, args, assigns, ops, func);
+    else if (OPT_ISSET(ops, 'T')) {
+	zwarn("bad option: -T");
+	return 1;
+    }
+
     if (locallevel == 0) {
 	if (isset(WARNCREATEGLOBAL))
 	    zwarnnam(nam, "invalid local scope, using globals");
@@ -495,7 +502,7 @@ printstaticnode(HashNode hn, int printflags)
 
 static struct builtin bintab[] = {
     /* Copied almost verbatim from BUILTIN("local") */
-    BUILTIN("static", BINF_PLUSOPTS | BINF_MAGICEQUALS | BINF_PSPECIAL | BINF_ASSIGN, (HandlerFunc)bin_static, 0, -1, 0, "AE:%F:%HL:%R:%UZ:%ahi:%lprtux", NULL)
+    BUILTIN("static", BINF_PLUSOPTS | BINF_MAGICEQUALS | BINF_PSPECIAL | BINF_ASSIGN, (HandlerFunc)bin_static, 0, -1, 0, "AE:%F:%HL:%R:%SUZ:%ahi:%lprtux", "S")
 };
 
 static struct features module_features = {
@@ -506,16 +513,27 @@ static struct features module_features = {
     0
 };
 
+/* Same optstr as BUILTIN("local") but with 'S' added */
+static char *optstr_local = "AE:%F:%HL:%R:%STUZ:%ahi:%lprtux";
+static struct builtin save_local;
+
 /**/
 int
 setup_(UNUSED(Module m))
 {
+    HashNode hn = builtintab->getnode(builtintab, "local");
+
     /* Horrible, horrible hack */
     getparamnode = realparamtab->getnode;
     realparamtab->getnode = getstaticnode;
     realparamtab->getnode2 = getstaticnode2;
     realparamtab->printnode = printstaticnode;
 
+    /* Even more horrible hack */
+    save_local = *(Builtin)hn;
+    ((Builtin)hn)->handlerfunc = bintab[0].handlerfunc;
+    ((Builtin)hn)->optstr = optstr_local;
+
     return 0;
 }
 
@@ -546,6 +564,9 @@ boot_(Module m)
 int
 cleanup_(Module m)
 {
+    HashNode hn = builtintab->getnode(builtintab, "local");
+    *(Builtin)hn = save_local;
+    
     realparamtab->getnode = getparamnode;
     realparamtab->getnode2 = gethashnode2;
     realparamtab->printnode = printparamnode;
diff --git a/Test/V10static.ztst b/Test/V10static.ztst
index 11f54e0..cc69db7 100644
--- a/Test/V10static.ztst
+++ b/Test/V10static.ztst
@@ -50,8 +50,7 @@
  # Depends on zsh-5.0.9 typeset keyword
  typeset -a array_test=(top level)
  () {
-  static -a array_test
-  array_test=(in function)
+  local -Sa array_test=(in function)
   () {
    static array_test
    print $+array_test
@@ -107,7 +106,7 @@
   print ${(t)hash_test} ${(kv)hash_test}
  }
  outer () {
-  static -A hash_test; hash_test=(in function)
+  local -SA hash_test=(in function)
   typeset -p hash_test
   inner
  }
@@ -159,7 +158,7 @@ F:note "typeset" rather than "static" in output from outer
   $ZTST_testdir/../Src/zsh -fc 'print X $array_test'
  }
  () {
-  static -ax array_test; array_test=(whaat)
+  local -Sax array_test=(whaat)
   print Y $array_test
   $ZTST_testdir/../Src/zsh -fc 'print X $array_test'
   inner
@@ -195,7 +194,7 @@ F:note "typeset" rather than "static" in output from outer
 
  typeset -A hash_test=(top level)
  () {
-  static -A hash_test; hash_test=(in function)
+  local -SA hash_test=(in function)
   () {
    print X ${(kv)hash_test}
   }
@@ -209,7 +208,7 @@ F:note "typeset" rather than "static" in output from outer
 
  typeset -A hash_test=(top level)
  () {
-  static -A hash_test; hash_test=(in function)
+  local -SA hash_test=(in function)
   () {
    print X ${(kv)hash_test}
    hash_test[in]=deeper
@@ -224,8 +223,8 @@ F:note "typeset" rather than "static" in output from outer
 
  typeset -A hash_test=(top level)
  () {
-  static -a array_test; array_test=(in function)
-  static -A hash_test; hash_test=($array_test)
+  local -Sa array_test=(in function)
+  local -SA hash_test=($array_test)
   () {
    print X ${(kv)hash_test}
    hash_test=(even deeper)
@@ -241,7 +240,7 @@ F:note "typeset" rather than "static" in output from outer
 
  typeset -A hash_test=(top level)
  () {
-  static -A hash_test; hash_test=(in function)
+  local -SA hash_test=(in function)
   () {
    print X ${(kv)hash_test}
    unset hash_test



Messages sorted by: Reverse Date, Date, Thread, Author