OSDN Git Service

Add local built-in
authormagicant <magicant@048f04df-13f5-43d7-8114-9f9ceecaec24>
Tue, 11 Dec 2018 14:57:15 +0000 (14:57 +0000)
committermagicant <magicant@048f04df-13f5-43d7-8114-9f9ceecaec24>
Tue, 11 Dec 2018 14:57:15 +0000 (14:57 +0000)
git-svn-id: svn+ssh://svn.sourceforge.jp/svnroot/yash/yash/trunk@3939 048f04df-13f5-43d7-8114-9f9ceecaec24

19 files changed:
NEWS
NEWS.ja
builtin.c
doc/Makefile.in
doc/_local.txt [new file with mode: 0644]
doc/_typeset.txt
doc/index.txt.in
doc/ja/Makefile.in
doc/ja/_local.txt [new file with mode: 0644]
doc/ja/_typeset.txt
doc/ja/index.txt.in
share/completion/local [new file with mode: 0644]
share/completion/typeset
tests/Makefile.in
tests/help-y.tst
tests/local-y.tst [new file with mode: 0644]
tests/typeset-y.tst
variable.c
variable.h

diff --git a/NEWS b/NEWS
index db193f9..2b7a399 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -11,6 +11,7 @@ History of Yash
 Yash 2.48
 
   +  The double-bracket command (the [[ ... ]] syntax)
+  +  The "local" built-in
   +  The '--le-predict-empty' option
   +  The prompt string now can be defined with the $YASH_PS...
      variables.
diff --git a/NEWS.ja b/NEWS.ja
index 0644b40..4e4ad72 100644 (file)
--- a/NEWS.ja
+++ b/NEWS.ja
@@ -11,6 +11,7 @@ Yash 更新履歴
 Yash 2.48
 
   +  二重ブラケットコマンド ([[ ... ]] 構文)
+  +  "local" 組込みコマンド
   +  --le-predict-empty オプション
   +  プロンプトを $YASH_PS... 変数で定義できるようにした
   =  コマンドライン推定機能はコマンドを打ち始める前には動作しないのを
index 9602e03..81161c9 100644 (file)
--- a/builtin.c
+++ b/builtin.c
@@ -1,6 +1,6 @@
 /* Yash: yet another shell */
 /* builtin.c: built-in commands */
-/* (C) 2007-2016 magicant */
+/* (C) 2007-2018 magicant */
 
 /* This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -125,6 +125,8 @@ void init_builtin(void)
            typeset_syntax, typeset_options);
     DEFBUILTIN("export", typeset_builtin, BI_SPECIAL, export_help,
            export_syntax, typeset_options);
+    DEFBUILTIN("local", typeset_builtin, BI_SEMISPECIAL, local_help,
+           local_syntax, local_options);
     DEFBUILTIN("readonly", typeset_builtin, BI_SPECIAL, readonly_help,
            readonly_syntax, typeset_options);
 #if YASH_ENABLE_ARRAY
index dca9395..ca9d5b6 100644 (file)
@@ -1,5 +1,5 @@
 # Makefile.in for the documentation of yash
-# (C) 2007-2014 magicant
+# (C) 2007-2018 magicant
 #
 # This program is free software: you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -43,7 +43,7 @@ INDEXTXT = index.txt
 # MAINTXTS must be in the contents order
 MAINTXTS = intro.txt invoke.txt syntax.txt params.txt expand.txt pattern.txt redir.txt exec.txt interact.txt job.txt builtin.txt lineedit.txt posix.txt faq.txt fgrammar.txt
 # BUILTINTXTS must be in the alphabetic order
-BUILTINTXTS = _alias.txt _array.txt _bg.txt _bindkey.txt _break.txt _cd.txt _colon.txt _command.txt _complete.txt _continue.txt _dirs.txt _disown.txt _dot.txt _echo.txt _eval.txt _exec.txt _exit.txt _export.txt _false.txt _fc.txt _fg.txt _getopts.txt _hash.txt _help.txt _history.txt _jobs.txt _kill.txt _popd.txt _printf.txt _pushd.txt _pwd.txt _read.txt _readonly.txt _return.txt _set.txt _shift.txt _suspend.txt _test.txt _times.txt _trap.txt _true.txt _type.txt _typeset.txt _ulimit.txt _umask.txt _unalias.txt _unset.txt _wait.txt
+BUILTINTXTS = _alias.txt _array.txt _bg.txt _bindkey.txt _break.txt _cd.txt _colon.txt _command.txt _complete.txt _continue.txt _dirs.txt _disown.txt _dot.txt _echo.txt _eval.txt _exec.txt _exit.txt _export.txt _false.txt _fc.txt _fg.txt _getopts.txt _hash.txt _help.txt _history.txt _jobs.txt _kill.txt _local.txt _popd.txt _printf.txt _pushd.txt _pwd.txt _read.txt _readonly.txt _return.txt _set.txt _shift.txt _suspend.txt _test.txt _times.txt _trap.txt _true.txt _type.txt _typeset.txt _ulimit.txt _umask.txt _unalias.txt _unset.txt _wait.txt
 # CONTENTSTXTS must be in the contents order
 CONTENTSTXTS = $(MAINTXTS) $(BUILTINTXTS)
 TXTS = $(MANTXT) $(INDEXTXT) $(CONTENTSTXTS)
diff --git a/doc/_local.txt b/doc/_local.txt
new file mode 100644 (file)
index 0000000..a067266
--- /dev/null
@@ -0,0 +1,26 @@
+= Local built-in
+:encoding: UTF-8
+:lang: en
+//:title: Yash manual - Local built-in
+
+The dfn:[local built-in] prints or sets local variables.
+
+[[syntax]]
+== Syntax
+
+- +local [-rxX] [{{name}}[={{value}}]...]+
+
+[[description]]
+== Description
+
+The local built-in is equivalent to the link:_typeset.html[typeset built-in]
+except that the +-f+ (+--functions+) and +-g+ (+--global+) options cannot be
+used.
+
+[[notes]]
+== Notes
+
+The local built-in is a link:builtin.html#types[semi-special built-in].
+In the POSIX standard, it is defined as a command with unspecified behavior.
+
+// vim: set filetype=asciidoc textwidth=78 expandtab:
index 9b3e433..8c74984 100644 (file)
@@ -100,8 +100,11 @@ The local variable will be set regardless of the +-g+ (+--global+) option.
 The typeset built-in is a link:builtin.html#types[semi-special built-in]. In
 the POSIX standard, it is defined as a command with unspecified behavior.
 
-The export and readonly built-ins are equivalent to the
-link:_typeset.html[typeset built-in] with the +-gx+ and +-gr+ options,
+The link:_export.html[export] and link:_readonly.html[readonly] built-ins are
+equivalent to the typeset built-in with the +-gx+ and +-gr+ options,
 respectively.
+The link:_local.html[local built-in] is equivalent to the typeset built-in
+except that the +-f+ (+--functions+) and +-g+ (+--global+) options cannot be
+used.
 
 // vim: set filetype=asciidoc textwidth=78 expandtab:
index 35803c5..ecc64d3 100644 (file)
@@ -52,6 +52,7 @@ built-in. (See link:builtin.html#types[Types of built-in commands])
 - link:_history.html[+history+] &#43;
 - link:_jobs.html[+jobs+] &#43;
 - link:_kill.html[+kill+] &#43;
+- link:_local.html[+local+] &#43;
 - link:_popd.html[+popd+] &#43;
 - link:_printf.html[+printf+]
 - link:_pushd.html[+pushd+] &#43;
@@ -122,6 +123,7 @@ built-in. (See link:builtin.html#types[Types of built-in commands])
 [role="list-group"]
 - link:_typeset.html[+typeset+]
 - link:_export.html[+export+] *
+- link:_local.html[+local+] &#43;
 - link:_readonly.html[+readonly+] *
 - link:_array.html[+array+]
 - link:_set.html[+set+] *
index 5e93bc4..53c5c0a 100644 (file)
@@ -1,5 +1,5 @@
 # Makefile.in for the documentation of yash
-# (C) 2007-2014 magicant
+# (C) 2007-2018 magicant
 #
 # This program is free software: you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -44,7 +44,7 @@ INDEXTXT = index.txt
 # MAINTXTS must be in the contents order
 MAINTXTS = intro.txt invoke.txt syntax.txt params.txt expand.txt pattern.txt redir.txt exec.txt interact.txt job.txt builtin.txt lineedit.txt posix.txt faq.txt fgrammar.txt
 # BUILTINTXTS must be in the alphabetic order
-BUILTINTXTS = _alias.txt _array.txt _bg.txt _bindkey.txt _break.txt _cd.txt _colon.txt _command.txt _complete.txt _continue.txt _dirs.txt _disown.txt _dot.txt _echo.txt _eval.txt _exec.txt _exit.txt _export.txt _false.txt _fc.txt _fg.txt _getopts.txt _hash.txt _help.txt _history.txt _jobs.txt _kill.txt _popd.txt _printf.txt _pushd.txt _pwd.txt _read.txt _readonly.txt _return.txt _set.txt _shift.txt _suspend.txt _test.txt _times.txt _trap.txt _true.txt _type.txt _typeset.txt _ulimit.txt _umask.txt _unalias.txt _unset.txt _wait.txt
+BUILTINTXTS = _alias.txt _array.txt _bg.txt _bindkey.txt _break.txt _cd.txt _colon.txt _command.txt _complete.txt _continue.txt _dirs.txt _disown.txt _dot.txt _echo.txt _eval.txt _exec.txt _exit.txt _export.txt _false.txt _fc.txt _fg.txt _getopts.txt _hash.txt _help.txt _history.txt _jobs.txt _kill.txt _local.txt _popd.txt _printf.txt _pushd.txt _pwd.txt _read.txt _readonly.txt _return.txt _set.txt _shift.txt _suspend.txt _test.txt _times.txt _trap.txt _true.txt _type.txt _typeset.txt _ulimit.txt _umask.txt _unalias.txt _unset.txt _wait.txt
 # CONTENTSTXTS must be in the contents order
 CONTENTSTXTS = $(MAINTXTS) $(BUILTINTXTS)
 TXTS = $(MANTXT) $(INDEXTXT) $(CONTENTSTXTS)
diff --git a/doc/ja/_local.txt b/doc/ja/_local.txt
new file mode 100644 (file)
index 0000000..dad0a2a
--- /dev/null
@@ -0,0 +1,24 @@
+= Local 組込みコマンド
+:encoding: UTF-8
+:lang: ja
+//:title: Yash マニュアル - Local 組込みコマンド
+
+dfn:[Local 組込みコマンド]はローカル変数を表示・設定します。
+
+[[syntax]]
+== 構文
+
+- +local [-rxX] [{{name}}[={{value}}]...]+
+
+[[description]]
+== 説明
+
+Local コマンドは link:_typeset.html[typeset コマンド]と同じですが +-f+ (+--functions+) および +-g+ (+--global+) オプションは使えません。
+
+[[notes]]
+== 補足
+
+Local コマンドは{zwsp}link:builtin.html#types[準特殊組込みコマンド]です。
+POSIX では local コマンドの動作は規定されていません。
+
+// vim: set filetype=asciidoc expandtab:
index 1fbec91..7821628 100644 (file)
@@ -80,6 +80,6 @@ dfn:[Typeset 組込みコマンド]は{zwsp}link:params.html#variables[変数]
 Typeset コマンドは{zwsp}link:builtin.html#types[準特殊組込みコマンド]です。
 POSIX では typeset コマンドの動作は規定されていません。
 
-link:_export.html[Export コマンド]は typeset コマンドに +-gx+ オプションを付けたものと同じです。{zwsp}link:_readonly.html[Readonly コマンド]は typeset コマンドに +-gr+ オプションを付けたものと同じです。
+link:_export.html[Export コマンド]は typeset コマンドに +-gx+ オプションを付けたものと同じです。{zwsp}link:_readonly.html[Readonly コマンド]は typeset コマンドに +-gr+ オプションを付けたものと同じです。{zwsp}link:_local.html[Local コマンド]は typeset と同じですが +-f+ (+--functions+) および +-g+ (+--global+) オプションは使えません。
 
 // vim: set filetype=asciidoc expandtab:
index 445ab1c..90057d7 100644 (file)
@@ -52,6 +52,7 @@ v{yashversion},
 - link:_history.html[+history+] &#43;
 - link:_jobs.html[+jobs+] &#43;
 - link:_kill.html[+kill+] &#43;
+- link:_local.html[+local+] &#43;
 - link:_popd.html[+popd+] &#43;
 - link:_printf.html[+printf+]
 - link:_pushd.html[+pushd+] &#43;
@@ -122,6 +123,7 @@ v{yashversion},
 [role="list-group"]
 - link:_typeset.html[+typeset+]
 - link:_export.html[+export+] *
+- link:_local.html[+local+] &#43;
 - link:_readonly.html[+readonly+] *
 - link:_array.html[+array+]
 - link:_set.html[+set+] *
diff --git a/share/completion/local b/share/completion/local
new file mode 100644 (file)
index 0000000..db3a024
--- /dev/null
@@ -0,0 +1,10 @@
+# (C) 2018 magicant
+
+# Completion script for the "local" built-in command.
+
+function completion/local {
+       command -f completion//reexecute typeset
+}
+
+
+# vim: set ft=sh ts=8 sts=8 sw=8 noet:
index 0b05120..6d947f1 100644 (file)
@@ -1,8 +1,8 @@
-# (C) 2010 magicant
+# (C) 2010-2018 magicant
 
 # Completion script for the "typeset" built-in command.
-# Completion function "completion/typeset" is used for the "export" and
-# "readonly" built-ins as well.
+# Completion function "completion/typeset" is used for the "export", "local"
+# and "readonly" built-ins as well.
 
 function completion/typeset {
 
@@ -17,9 +17,13 @@ function completion/typeset {
                "g --global; define global variables"
                ) #<#
        fi
-       if [ "${WORDS[1]}" != "export" ]; then
+       if [ "${WORDS[1]}" = "readonly" ] || [ "${WORDS[1]}" = "typeset" ]; then
                OPTIONS=("$OPTIONS" #>#
                "f --functions; define or print functions rather than variables"
+               ) #<#
+       fi
+       if [ "${WORDS[1]}" != "export" ]; then
+               OPTIONS=("$OPTIONS" #>#
                "x --export; export variables or print exported variables"
                ) #<#
        fi
index a75c49d..ea751ce 100644 (file)
@@ -28,7 +28,7 @@ LDFLAGS = @LDFLAGS@
 LDLIBS = @LDLIBS@
 SOURCES = checkfg.c resetsig.c
 POSIX_TEST_SOURCES = alias-p.tst andor-p.tst arith-p.tst async-p.tst bg-p.tst break-p.tst builtins-p.tst case-p.tst cd-p.tst cmdsub-p.tst command-p.tst comment-p.tst continue-p.tst dot-p.tst errexit-p.tst error-p.tst eval-p.tst exec-p.tst exit-p.tst export-p.tst fg-p.tst fnmatch-p.tst for-p.tst fsplit-p.tst function-p.tst getopts-p.tst grouping-p.tst if-p.tst input-p.tst job-p.tst kill1-p.tst kill2-p.tst kill3-p.tst kill4-p.tst lineno-p.tst nop-p.tst option-p.tst param-p.tst path-p.tst pipeline-p.tst ppid-p.tst quote-p.tst read-p.tst readonly-p.tst redir-p.tst return-p.tst set-p.tst shift-p.tst signal-p.tst simple-p.tst test-p.tst testtty-p.tst tilde-p.tst trap-p.tst umask-p.tst unset-p.tst until-p.tst wait-p.tst while-p.tst
-YASH_TEST_SOURCES = alias-y.tst andor-y.tst arith-y.tst array-y.tst async-y.tst bg-y.tst bindkey-y.tst brace-y.tst bracket-y.tst break-y.tst builtins-y.tst case-y.tst cd-y.tst cmdsub-y.tst command-y.tst complete-y.tst continue-y.tst dirstack-y.tst disown-y.tst dot-y.tst echo-y.tst errexit-y.tst error-y.tst errretur-y.tst eval-y.tst exec-y.tst exit-y.tst export-y.tst fc-y.tst fg-y.tst for-y.tst fsplit-y.tst function-y.tst getopts-y.tst grouping-y.tst hash-y.tst help-y.tst history-y.tst historyx-y.tst if-y.tst job-y.tst jobs-y.tst kill-y.tst lineno-y.tst option-y.tst param-y.tst pipeline-y.tst printf-y.tst prompt-y.tst pwd-y.tst quote-y.tst random-y.tst read-y.tst readonly-y.tst redir-y.tst return-y.tst set-y.tst settty-y.tst shift-y.tst signal1-y.tst signal2-y.tst simple-y.tst startup-y.tst suspend-y.tst test-y.tst tilde-y.tst times-y.tst trap-y.tst typeset-y.tst ulimit-y.tst umask-y.tst unset-y.tst until-y.tst wait-y.tst while-y.tst
+YASH_TEST_SOURCES = alias-y.tst andor-y.tst arith-y.tst array-y.tst async-y.tst bg-y.tst bindkey-y.tst brace-y.tst bracket-y.tst break-y.tst builtins-y.tst case-y.tst cd-y.tst cmdsub-y.tst command-y.tst complete-y.tst continue-y.tst dirstack-y.tst disown-y.tst dot-y.tst echo-y.tst errexit-y.tst error-y.tst errretur-y.tst eval-y.tst exec-y.tst exit-y.tst export-y.tst fc-y.tst fg-y.tst for-y.tst fsplit-y.tst function-y.tst getopts-y.tst grouping-y.tst hash-y.tst help-y.tst history-y.tst historyx-y.tst if-y.tst job-y.tst jobs-y.tst kill-y.tst lineno-y.tst local-y.tst option-y.tst param-y.tst pipeline-y.tst printf-y.tst prompt-y.tst pwd-y.tst quote-y.tst random-y.tst read-y.tst readonly-y.tst redir-y.tst return-y.tst set-y.tst settty-y.tst shift-y.tst signal1-y.tst signal2-y.tst simple-y.tst startup-y.tst suspend-y.tst test-y.tst tilde-y.tst times-y.tst trap-y.tst typeset-y.tst ulimit-y.tst umask-y.tst unset-y.tst until-y.tst wait-y.tst while-y.tst
 TEST_SOURCES = $(POSIX_TEST_SOURCES) $(YASH_TEST_SOURCES)
 TEST_RESULTS = $(TEST_SOURCES:.tst=.trs)
 RECHECK_LOGS = $(TEST_RESULTS)
index e7c5ef8..1398d80 100644 (file)
@@ -578,6 +578,25 @@ Try `man yash' for details.
 __OUT__
 #`
 
+test_oE -e 0 'help of local'
+help local
+__IN__
+local: set or print local variables
+
+Syntax:
+       local [-prxX] [name[=value]...]
+
+Options:
+       -p       --print
+       -r       --readonly
+       -x       --export
+       -X       --unexport
+                --help
+
+Try `man yash' for details.
+__OUT__
+#`
+
 (
 if ! testee -c 'command -bv popd' >/dev/null; then
     skip="true"
diff --git a/tests/local-y.tst b/tests/local-y.tst
new file mode 100644 (file)
index 0000000..500b595
--- /dev/null
@@ -0,0 +1,126 @@
+# local-y.tst: yash-specific test of the local built-in
+
+# Since "local" is an alias for "typeset", most tests in this file are
+# analogous to those in typeset-y.tst.
+
+test_oE -e 0 'local is a semi-special built-in'
+command -V local
+__IN__
+local: a semi-special built-in
+__OUT__
+
+test_oE -e 0 'defining variable in global namespace' -e
+local a=1
+echo $a
+__IN__
+1
+__OUT__
+
+test_oE -e 0 'defining local variable' -e
+f() {
+    local a=1
+    b=2
+    echo $a $b
+    a=3 b=4
+    echo $a $b
+}
+f
+echo ${a-unset} ${b-unset}
+__IN__
+1 2
+3 4
+unset 4
+__OUT__
+
+test_oE -e 0 'only local variables are printed by default (no option)' -e
+f() {       a=1; local; }
+g() { local a=1; local; }
+f
+echo ---
+g
+__IN__
+---
+local a=1
+__OUT__
+
+test_oE -e 0 'defining and printing local array (no option)' -e
+f() {
+    local a
+    a=(This is my array.)
+    printf '%s\n' "$a"
+    local
+}
+a=global
+f
+echo $a
+__IN__
+This
+is
+my
+array.
+a=(This is my array.)
+local a
+global
+__OUT__
+
+test_oE 'defining exported variables (-x)' -e
+f() {
+a=1
+local -x a b=2
+echo [$a] $b
+a=3
+echo $a $b
+sh -c 'echo $a $b'
+}
+a=a b=b
+f
+echo $a $b
+__IN__
+[] 2
+3 2
+3 2
+1 b
+__OUT__
+
+test_oE -e 0 'only local variables are printed by default (-p)' -e
+f() {       a=1; local -p; }
+g() { local a=1; local -p; }
+f
+echo ---
+g
+__IN__
+---
+local a=1
+__OUT__
+
+test_Oe -e 2 'invalid option -f'
+local -f
+__IN__
+local: `-f' is not a valid option
+__ERR__
+#'
+#`
+
+test_Oe -e 2 'invalid option -g'
+local -g
+__IN__
+local: `-g' is not a valid option
+__ERR__
+#'
+#`
+
+test_Oe -e 2 'invalid option --xxx'
+local --global
+__IN__
+local: `--global' is not a valid option
+__ERR__
+#'
+#`
+
+test_Oe -e 2 'specifying -x and -X at once'
+local -xX
+__IN__
+local: the -x option cannot be used with the -X option
+__ERR__
+
+# vim: set ft=sh ts=8 sts=4 sw=4 noet:
index 741985a..4e9016f 100644 (file)
@@ -91,6 +91,26 @@ typeset yash_typeset_test_b=2
 typeset yash_typeset_test_g=3
 __OUT__
 
+test_oE -e 0 'defining and printing local array (no option)' -e
+f() {
+    typeset a
+    a=(This is my array.)
+    printf '%s\n' "$a"
+    typeset
+}
+a=global
+f
+echo $a
+__IN__
+This
+is
+my
+array.
+a=(This is my array.)
+typeset a
+global
+__OUT__
+
 test_oE 'defining read-only variables (-r)' -e
 a=1
 typeset -r a b=2
@@ -159,7 +179,7 @@ typeset a=1
 typeset b=2
 __OUT__
 
-test_oE -e 0 'printing array variable (p)' -e
+test_oE -e 0 'printing array variable (-p)' -e
 a=() b=(1 '2  2' 3)
 typeset -x b
 typeset -p a b
index de33450..6c68a60 100644 (file)
@@ -1618,6 +1618,7 @@ const struct xgetopt_T typeset_options[] = {
 #endif
     { L'\0', NULL, 0, false, NULL, },
 };
+/* Note: `local_options' is defined as part of `typeset_options'. */
 
 /* The "typeset" built-in, which accepts the following options:
  *  -f: affect functions rather than variables
@@ -1628,6 +1629,7 @@ const struct xgetopt_T typeset_options[] = {
  *  -X: cancel exportation of variables
  * Equivalent built-ins:
  *  export:   typeset -gx
+ *  local:    typeset
  *  readonly: typeset -gr
  * The "set" built-in without any arguments is redirected to this built-in. */
 int typeset_builtin(int argc, void **argv)
@@ -1635,9 +1637,11 @@ int typeset_builtin(int argc, void **argv)
     bool function = false, global = false, print = false;
     bool readonly = false, export = false, unexport = false;
 
+    const struct xgetopt_T *options =
+       (ARGV(0)[0] == L'l' /*local*/) ? local_options : typeset_options;
     const struct xgetopt_T *opt;
     xoptind = 0;
-    while ((opt = xgetopt(argv, typeset_options, 0)) != NULL) {
+    while ((opt = xgetopt(argv, options, 0)) != NULL) {
        switch (opt->shortopt) {
            case L'f':  function = true;  break;
            case L'g':  global   = true;  break;
@@ -1661,6 +1665,9 @@ int typeset_builtin(int argc, void **argv)
            if (!unexport)
                export = true;
            break;
+       case L'l':
+           assert(wcscmp(ARGV(0), L"local") == 0);
+           break;
        case L'r':
            assert(wcscmp(ARGV(0), L"readonly") == 0);
            global = readonly = true;
@@ -1834,8 +1841,12 @@ void print_scalar(const wchar_t *name, bool namequote,
            format = (quotedvalue != NULL) ? "%ls %ls=%ls\n" : "%ls %ls\n";
            xprintf(format, argv0, name, quotedvalue);
            break;
+       case L'l':
+           assert(wcscmp(argv0, L"local") == 0);
+           goto typeset;
        case L't':
            assert(wcscmp(argv0, L"typeset") == 0);
+typeset:
            sb_init(&opts);
            if (var->v_type & VF_EXPORT)
                sb_ccat(&opts, 'x');
@@ -1891,8 +1902,12 @@ void print_array(
                    || wcscmp(argv0, L"readonly") == 0);
            xprintf("%ls %ls\n", argv0, name);
            break;
+       case L'l':
+           assert(wcscmp(argv0, L"local") == 0);
+           goto typeset;
        case L't':
            assert(wcscmp(argv0, L"typeset") == 0);
+typeset:
            sb_init(&opts);
            if (var->v_type & VF_EXPORT)
                sb_ccat(&opts, 'x');
@@ -1962,6 +1977,12 @@ const char export_help[] = Ngt(
 const char export_syntax[] = Ngt(
 "\texport [-prX] [name[=value]...]\n"
 );
+const char local_help[] = Ngt(
+"set or print local variables"
+);
+const char local_syntax[] = Ngt(
+"\tlocal [-prxX] [name[=value]...]\n"
+);
 const char readonly_help[] = Ngt(
 "make variables read-only"
 );
index cef1da0..af7e990 100644 (file)
@@ -1,6 +1,6 @@
 /* Yash: yet another shell */
 /* variable.h: deals with shell variables and parameters */
-/* (C) 2007-2016 magicant */
+/* (C) 2007-2018 magicant */
 
 /* This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -144,9 +144,11 @@ extern int typeset_builtin(int argc, void **argv)
     __attribute__((nonnull));
 #if YASH_ENABLE_HELP
 extern const char typeset_help[], typeset_syntax[], export_help[],
-       export_syntax[], readonly_help[], readonly_syntax[];
+       export_syntax[], local_help[], local_syntax[], readonly_help[],
+       readonly_syntax[];
 #endif
 extern const struct xgetopt_T typeset_options[];
+#define local_options (&typeset_options[2])
 
 extern int array_builtin(int argc, void **argv)
     __attribute__((nonnull));