• R/O
  • SSH
  • HTTPS

yash: Commit


Commit MetaInfo

Revision4208 (tree)
Zeit2022-09-28 22:40:36
Autormagicant

Log Message

Require $PATH search for substitutive built-ins

This commit recategorizes regular built-ins into substitutive built-ins
and extension built-ins in order to remove the use of the words "regular
built-ins," which have been used in a different meaning than mentioned
in POSIX.

To minimize the behavioral differences caused by enabling the POSIXly-
correct mode, substitutive built-ins now require a corresponding
external program when running them except for the "array" built-in which
now is an extension built-in and is completely ignored in the POSIXly-
correct mode.

Ändern Zusammenfassung

Diff

--- yash/trunk/NEWS (revision 4207)
+++ yash/trunk/NEWS (revision 4208)
@@ -16,6 +16,13 @@
1616 "semi-special" built-ins are now categorized in either of the new
1717 categories "mandatory" and "elective". The "command" and "type"
1818 built-ins now report the new categories of such built-ins.
19+ = The shell now requires a corresponding external executable to
20+ exist in $PATH when running a built-in that works like a standard
21+ external utility even when the POSIXly-correct mode is inactive.
22+ Such built-ins are now categorized as "substitutive" built-ins.
23+ = The "array" built-in is now completely ignored in the POSIXly-
24+ correct mode. The built-in, formerly a regular built-in, is now
25+ categorized as an "extension" built-in.
1926
2027 ----------------------------------------------------------------------
2128 Yash 2.53 (2022-08-23)
--- yash/trunk/builtin.c (revision 4207)
+++ yash/trunk/builtin.c (revision 4208)
@@ -130,7 +130,7 @@
130130 DEFBUILTIN("readonly", typeset_builtin, BI_SPECIAL, readonly_help,
131131 readonly_syntax, typeset_options);
132132 #if YASH_ENABLE_ARRAY
133- DEFBUILTIN("array", array_builtin, BI_REGULAR, array_help, array_syntax,
133+ DEFBUILTIN("array", array_builtin, BI_EXTENSION, array_help, array_syntax,
134134 array_options);
135135 #endif
136136 DEFBUILTIN("unset", unset_builtin, BI_SPECIAL, unset_help, unset_syntax,
@@ -209,15 +209,18 @@
209209
210210 /* defined in "builtins/printf.c" */
211211 #if YASH_ENABLE_PRINTF
212- DEFBUILTIN("echo", echo_builtin, BI_REGULAR, echo_help, echo_syntax, NULL);
213- DEFBUILTIN("printf", printf_builtin, BI_REGULAR, printf_help, printf_syntax,
214- help_option);
212+ DEFBUILTIN("echo", echo_builtin, BI_SUBSTITUTIVE, echo_help, echo_syntax,
213+ NULL);
214+ DEFBUILTIN("printf", printf_builtin, BI_SUBSTITUTIVE, printf_help,
215+ printf_syntax, help_option);
215216 #endif
216217
217218 /* defined in "builtins/test.c" */
218219 #if YASH_ENABLE_TEST
219- DEFBUILTIN("test", test_builtin, BI_REGULAR, test_help, test_syntax, NULL);
220- DEFBUILTIN("[", test_builtin, BI_REGULAR, test_help, test_syntax, NULL);
220+ DEFBUILTIN("test", test_builtin, BI_SUBSTITUTIVE, test_help, test_syntax,
221+ NULL);
222+ DEFBUILTIN("[", test_builtin, BI_SUBSTITUTIVE, test_help, test_syntax,
223+ NULL);
221224 #endif
222225
223226 /* defined in "lineedit/complete.c" */
@@ -508,11 +511,12 @@
508511 while ((kv = ht_next(&builtins, &i)).key != NULL) {
509512 le_candgentype_T type;
510513 switch (((const builtin_T *) kv.value)->type) {
511- case BI_SPECIAL: type = CGT_SBUILTIN; break;
512- case BI_MANDATORY: type = CGT_MBUILTIN; break;
513- case BI_ELECTIVE: type = CGT_LBUILTIN; break;
514- case BI_REGULAR: type = CGT_RBUILTIN; break;
515- default: assert(false);
514+ case BI_SPECIAL: type = CGT_SBUILTIN; break;
515+ case BI_MANDATORY: type = CGT_MBUILTIN; break;
516+ case BI_ELECTIVE: type = CGT_LBUILTIN; break;
517+ case BI_EXTENSION: type = CGT_XBUILTIN; break;
518+ case BI_SUBSTITUTIVE: type = CGT_UBUILTIN; break;
519+ default: assert(false);
516520 }
517521 if (!(compopt->type & type))
518522 continue;
--- yash/trunk/builtin.h (revision 4207)
+++ yash/trunk/builtin.h (revision 4208)
@@ -26,10 +26,11 @@
2626 __attribute__((nonnull));
2727
2828 typedef enum builtintype_T {
29- BI_SPECIAL, // built-ins defined in POSIX XCU 2.14
30- BI_MANDATORY, // built-ins listed in POSIX XCU 1.6
31- BI_ELECTIVE, // built-ins listed in POSIX XCU 2.9.1
32- BI_REGULAR, // built-ins that substitute external utilities
29+ BI_SPECIAL, // built-ins defined in POSIX XCU 2.14
30+ BI_MANDATORY, // built-ins listed in POSIX XCU 1.6
31+ BI_ELECTIVE, // built-ins listed in POSIX XCU 2.9.1
32+ BI_EXTENSION, // built-ins not mentioned in POSIX
33+ BI_SUBSTITUTIVE, // built-ins that substitute external utilities
3334 } builtintype_T;
3435
3536 typedef struct builtin_T {
--- yash/trunk/doc/_array.txt (revision 4207)
+++ yash/trunk/doc/_array.txt (revision 4208)
@@ -78,6 +78,7 @@
7878 == Notes
7979
8080 The array built-in is not defined in the POSIX standard.
81+Yash implements the built-in as an link:builtin.html#types[extension].
8182
8283 The command +array {{name}} {{value}}...+ is equivalent to the assignment
8384 +{{name}}=({{value}}...)+.
--- yash/trunk/doc/_complete.txt (revision 4207)
+++ yash/trunk/doc/_complete.txt (revision 4208)
@@ -83,7 +83,7 @@
8383 +-b+::
8484 +--builtin-command+::
8585 link:builtin.html[Built-in commands].
86-(same as +--special-builtin --mandatory-builtin --elective-builtin --regular-builtin+)
86+(same as +--special-builtin --mandatory-builtin --elective-builtin --extension-builtin --substitutive-builtin+)
8787
8888 +-c+::
8989 +--command+::
@@ -103,6 +103,9 @@
103103 +--executable-file+::
104104 Executable regular files.
105105
106++--extension-builtin+::
107+link:builtin.html#types[Extension built-in commands].
108+
106109 +--external-command+::
107110 External commands.
108111
@@ -142,7 +145,7 @@
142145 Normal link:syntax.html#aliases[aliases].
143146
144147 +--regular-builtin+::
145-link:builtin.html#types[Regular built-in commands].
148+Obsolete synonym for +--extension-builtin --substitutive-builtin+.
146149
147150 +--running-job+::
148151 link:job.html#jobid[Job IDs] of jobs that are being executed.
@@ -162,6 +165,9 @@
162165 +--stopped-job+::
163166 link:job.html#jobid[Job IDs] of jobs that are suspended.
164167
168++--substitutive-builtin+::
169+link:builtin.html#types[Substitutive built-in commands].
170+
165171 +-u+::
166172 +--username+::
167173 Users' log-in names.
--- yash/trunk/doc/builtin.txt (revision 4207)
+++ yash/trunk/doc/builtin.txt (revision 4208)
@@ -35,11 +35,16 @@
3535 built-ins in the link:posix.html[POSIXly-correct mode] because POSIX only
3636 reserves their names without defining their behavior.
3737
38-dfn:[Regular built-in commands] are less important built-in commands including
39-commands that can be implemented as external commands or are not listed in
40-POSIX. In the POSIXly-correct mode, a regular built-in is executed only when
41-a corresponding external command is link:exec.html#search[found in PATH].
38+An dfn:[extension built-in command] is a built-in that is not mentioned in
39+POSIX. Like an elective built-in, it can be executed without an external
40+command when the link:posix.html[POSIXly-correct mode] is off. However, when
41+the POSIXly-correct mode is on, the shell works as if the built-in does not
42+exist.
4243
44+dfn:[Substitutive built-in commands] work on behalf of external commands
45+link:exec.html#search[found in PATH]. These built-ins improve execution speed
46+by bypassing invocation overheads for external programs.
47+
4348 [[argsyntax]]
4449 == Syntax of command arguments
4550
--- yash/trunk/doc/exec.txt (revision 4207)
+++ yash/trunk/doc/exec.txt (revision 4208)
@@ -137,9 +137,9 @@
137137 function is determined as the executed command.
138138 . If the command name is a link:builtin.html#types[mandatory or elective
139139 built-in], the built-in is determined as the executed command.
140-. If the command name is a link:builtin.html#types[regular built-in], the
141- built-in is determined as the executed command unless the shell is in the
142- link:posix.html[POSIXly-correct mode].
140+. If the command name is an link:builtin.html#types[extension built-in] and
141+ the shell is not in the link:posix.html[POSIXly-correct mode], the built-in
142+ is determined as the executed command.
143143 . The shell searches the PATH for a executed command:
144144 +
145145 --
@@ -152,8 +152,8 @@
152152 to the command name.
153153 If such a file is found:
154154
155-- If the command name is the name of a built-in, the built-in is determined as
156- the executed command.
155+- If the command name is the name of a link:builtin.html#types[substitutive
156+ built-in], the built-in is determined as the executed command.
157157 - Otherwise, the file is determined as the executed command.
158158 (The file will be executed as an external command.)
159159
--- yash/trunk/doc/index.txt.in (revision 4207)
+++ yash/trunk/doc/index.txt.in (revision 4208)
@@ -18,8 +18,8 @@
1818 == Built-ins
1919
2020 Parenthesized letters indicate the link:builtin.html#types[types of built-in
21-commands]: (S) for special, (M) mandatory, and (L) elective.
22-Regular built-ins are not marked.
21+commands]: (S) for special, (M) mandatory, (L) elective, and (X) extension.
22+Substitutive built-ins are not marked.
2323
2424 [[alpha-order]]
2525 === All built-ins in alphabetic order
@@ -29,7 +29,7 @@
2929 - link:_colon.html[+:+ (colon)] (S)
3030 - link:_test.html[+[+ (bracket)]
3131 - link:_alias.html[+alias+] (M)
32-- link:_array.html[+array+]
32+- link:_array.html[+array+] (X)
3333 - link:_bg.html[+bg+] (M)
3434 - link:_bindkey.html[+bindkey+] (L)
3535 - link:_break.html[+break+] (S)
@@ -126,7 +126,7 @@
126126 - link:_export.html[+export+] (S)
127127 - link:_local.html[+local+] (L)
128128 - link:_readonly.html[+readonly+] (S)
129-- link:_array.html[+array+]
129+- link:_array.html[+array+] (X)
130130 - link:_set.html[+set+] (S)
131131 - link:_shift.html[+shift+] (S)
132132 - link:_read.html[+read+] (M)
--- yash/trunk/doc/ja/_array.txt (revision 4207)
+++ yash/trunk/doc/ja/_array.txt (revision 4208)
@@ -63,6 +63,7 @@
6363 == 補足
6464
6565 POSIX には array コマンドに関する規定はありません。
66+Yash ではこれを{zwsp}link:builtin.html#types[拡張組込みコマンド]として実装しています。
6667
6768 +array {{配列名}} [{{値}}...]+ の形式の array コマンドは変数代入を用いて +{{配列名}}=({{値}}...)+ と書くこともできます。
6869
--- yash/trunk/doc/ja/_complete.txt (revision 4207)
+++ yash/trunk/doc/ja/_complete.txt (revision 4208)
@@ -60,7 +60,7 @@
6060
6161 +-b+::
6262 +--builtin-command+::
63-link:builtin.html[組込みコマンド] (+--special-builtin --mandatory-builtin --elective-builtin --regular-builtin+ に同じ)
63+link:builtin.html[組込みコマンド] (+--special-builtin --mandatory-builtin --elective-builtin --extension-builtin --substitutive-builtin+ に同じ)
6464
6565 +-c+::
6666 +--command+::
@@ -79,6 +79,9 @@
7979 +--executable-file+::
8080 実行可能ファイル
8181
82++--extension-builtin+::
83+link:builtin.html#types[拡張組込みコマンド]
84+
8285 +--external-command+::
8386 外部コマンド
8487
@@ -118,7 +121,8 @@
118121 通常の (グローバルでない) link:syntax.html#aliases[エイリアス]
119122
120123 +--regular-builtin+::
121-通常の{zwsp}link:builtin.html[組込みコマンド]
124+後方互換性のために残されている古いオプション。
125++--extension-builtin --substitutive-builtin+ に同じ。
122126
123127 +--running-job+::
124128 実行中のジョブの{zwsp}link:job.html#jobid[ジョブ ID]
@@ -139,6 +143,9 @@
139143 +--stopped-job+::
140144 停止中のジョブの{zwsp}link:job.html#jobid[ジョブ ID]
141145
146++--substitutive-builtin+::
147+link:builtin.html#types[代替組込みコマンド]
148+
142149 +-u+::
143150 +--username+::
144151 ユーザのログイン名
--- yash/trunk/doc/ja/builtin.txt (revision 4207)
+++ yash/trunk/doc/ja/builtin.txt (revision 4208)
@@ -20,8 +20,10 @@
2020 dfn:[必須組込みコマンド]と{zwsp}dfn:[任意組込みコマンド]は外部コマンドの存在に関係なく実行される点では特殊組込みコマンドと同様ですが、{zwsp}link:exec.html#function[関数]で上書き可能な点が異なります。
2121 必須組込みコマンドは常に利用可能ですが、任意組込みコマンドは POSIX では名前しか定義されていないため link:posix.html[POSIX 準拠モード]では使えません。
2222
23-外部コマンドとして実装可能な組込みコマンドや POSIX に規定されていない組込みコマンドを含む、重要度の低い組込みコマンドはdfn:[通常の組込みコマンド]です。POSIX 準拠モードでは、通常の組込みコマンドは対応する外部コマンドが link:exec.html#search[+PATH+ 変数の検索]で見つかった場合のみ実行されます。
23+dfn:[拡張組込みコマンド]は POSIX で言及されていないコマンドです。任意組込みコマンドと同様に、{zwsp}link:posix.html[POSIX 準拠モード]が無効の時は外部コマンドに関係なく使用できますが、POSIX 準拠モードが有効な時は拡張組込みコマンドは存在しないものとして扱われます。
2424
25+dfn:[代替組込みコマンド]は link:exec.html#search[+PATH+ 変数の検索]で見つかった外部コマンドの代わりに実行される組込みコマンドです。外部コマンドを起動するオーバーヘッドを回避して実行速度を向上します。
26+
2527 [[argsyntax]]
2628 == コマンドの引数の構文
2729
--- yash/trunk/doc/ja/exec.txt (revision 4207)
+++ yash/trunk/doc/ja/exec.txt (revision 4208)
@@ -61,11 +61,11 @@
6161 . コマンド名が{zwsp}link:builtin.html#types[特殊組込みコマンド]ならば、その組込みコマンドが実行すべきコマンドとして特定されます。
6262 . コマンド名と同じ名前の<<function,関数>>が存在すれば、その関数が実行すべきコマンドとして特定されます。
6363 . コマンド名が{zwsp}link:builtin.html#types[必須組込みコマンドまたは任意組込みコマンド]ならば、その組込みコマンドが実行すべきコマンドとして特定されます。
64-. コマンド名が{zwsp}link:builtin.html#types[通常の組込みコマンド]ならば、その組込みコマンドが実行すべきコマンドとして特定されます。(link:posix.html[POSIX 準拠モード]のときを除く)
64+. コマンド名が{zwsp}link:builtin.html#types[拡張組込みコマンド]ならば、その組込みコマンドが実行すべきコマンドとして特定されます。(link:posix.html[POSIX 準拠モード]のときを除く)
6565 . link:params.html#sv-path[+PATH+ 変数]の値に従って、実行すべき外部コマンドを検索しそのパス名を特定します。
6666 +
6767 --
68-+PATH+ 変数の値は、いくつかのディレクトリのパス名をコロン (+:+) で区切ったものとみなされます (空のパス名はシェルの作業ディレクトリを表しているものとみなします)。それらの各ディレクトリについて順に、ディレクトリの中にコマンド名と同じ名前の実行可能な通常のファイルがあるか調査します。そのようなファイルがあれば、そのファイルが実行すべき外部コマンドとして特定されます (ただし、コマンド名と同じ名前の組込みコマンドがあれば、代わりにその組込みコマンドが実行すべきコマンドとして特定されます)。どのディレクトリにもそのようなファイルが見つからなければ、実行すべきコマンドは見つからなかったものとみなされます。
68++PATH+ 変数の値は、いくつかのディレクトリのパス名をコロン (+:+) で区切ったものとみなされます (空のパス名はシェルの作業ディレクトリを表しているものとみなします)。それらの各ディレクトリについて順に、ディレクトリの中にコマンド名と同じ名前の実行可能な通常のファイルがあるか調査します。そのようなファイルがあれば、そのファイルが実行すべき外部コマンドとして特定されます (ただし、コマンド名と同じ名前の代替組込みコマンドがあれば、代わりにその組込みコマンドが実行すべきコマンドとして特定されます)。どのディレクトリにもそのようなファイルが見つからなければ、実行すべきコマンドは見つからなかったものとみなされます。
6969 --
7070
7171 外部コマンドの検索が成功しパス名が特定できた場合、そのパス名が絶対パスならば、シェルはそのパス名を記憶し、再び同じコマンドを実行する際に検索の手間を省きます。ただし、再びコマンドを実行しようとした際に、記憶しているパス名に実行可能ファイルが見当たらない場合は、検索をやり直します。シェルが記憶しているパス名は link:_hash.html[hash 組込みコマンド]で管理できます。
--- yash/trunk/doc/ja/index.txt.in (revision 4207)
+++ yash/trunk/doc/ja/index.txt.in (revision 4208)
@@ -18,7 +18,7 @@
1818 == 組込みコマンド
1919
2020 括弧書きの文字は{zwsp}link:builtin.html#types[組込みコマンドの種類]を表します。
21-(S) は特殊組込みコマンド、(M) は必須組込みコマンド、(L) は任意組込みコマンド、無印は通常の組込みコマンドです。
21+(S) は特殊組込みコマンド、(M) は必須組込みコマンド、(L) は任意組込みコマンド、(X) は拡張組込みコマンド、無印は代替組込みコマンドです。
2222
2323 [[alpha-order]]
2424 === 組込みコマンド一覧 (アルファベット順)
@@ -28,7 +28,7 @@
2828 - link:_colon.html[+:+ (コロン)] (S)
2929 - link:_test.html[+[+ (括弧)]
3030 - link:_alias.html[+alias+] (M)
31-- link:_array.html[+array+]
31+- link:_array.html[+array+] (X)
3232 - link:_bg.html[+bg+] (M)
3333 - link:_bindkey.html[+bindkey+] (L)
3434 - link:_break.html[+break+] (S)
@@ -125,7 +125,7 @@
125125 - link:_export.html[+export+] (S)
126126 - link:_local.html[+local+] (L)
127127 - link:_readonly.html[+readonly+] (S)
128-- link:_array.html[+array+]
128+- link:_array.html[+array+] (X)
129129 - link:_set.html[+set+] (S)
130130 - link:_shift.html[+shift+] (S)
131131 - link:_read.html[+read+] (M)
--- yash/trunk/doc/ja/posix.txt (revision 4207)
+++ yash/trunk/doc/ja/posix.txt (revision 4208)
@@ -32,8 +32,7 @@
3232 - +&lt;&amp;+ および +&gt;&amp;+ link:redir.html#dup[リダイレクト]演算子の対象となるファイル記述子はそれぞれ読み込み可能および書き込み可能でなければなりません。
3333 - link:redir.html#socket[ソケットリダイレクト]・{zwsp}link:redir.html#here[ヒアストリング]・{zwsp}link:redir.html#pipe[パイプリダイレクト]・{zwsp}link:redir.html#process[プロセスリダイレクト]は使用できません。
3434 - link:exec.html#simple[単純コマンドの実行]時、コマンドが見つからなくても link:params.html#sv-command_not_found_handler[+COMMAND_NOT_FOUND_HANDLER+ 変数]の値は実行しません。
35-- link:builtin.html#types[任意組込みコマンド]は実行できません。
36-- link:exec.html#search[コマンドの検索]において{zwsp}link:builtin.html#types[通常の組込みコマンド]は対応する外部コマンドがないと見つかりません。
35+- link:builtin.html#types[任意組込みコマンドおよび拡張組込みコマンド]は実行できません。
3736 - いくつかの{zwsp}link:builtin.html[組込みコマンド]で特定のオプションが使えなくなるなど挙動が変わります。特に、長いオプションは使えなくなります。
3837 - link:interact.html[対話モード]でないとき、{zwsp}link:builtin.html#types[特殊組込みコマンド]のオプションやオペランドの使い方が間違っているとシェルは直ちに終了します。また特殊組込みコマンドで代入エラーやリダイレクトエラーが発生したときも直ちに終了します。
3938 - link:interact.html[対話モード]のプロンプトを出す前に link:params.html#sv-prompt_command[+PROMPT_COMMAND+ 変数]の値を実行しません。{zwsp}link:params.html#sv-ps1[+PS1+ 変数]・{zwsp}link:params.html#sv-ps2[+PS2+ 変数]・{zwsp}link:params.html#sv-ps4[+PS4+ 変数]の値の解釈の仕方が違います。{zwsp}link:params.html#sv-yash_ps1[+YASH_PS1+] など +YASH_+ で始まる名前のプロンプト変数は使用されません。
--- yash/trunk/doc/posix.txt (revision 4207)
+++ yash/trunk/doc/posix.txt (revision 4208)
@@ -78,10 +78,7 @@
7878 search does not trigger execution of the
7979 link:params.html#sv-command_not_found_handler[+COMMAND_NOT_FOUND_HANDLER+
8080 variable].
81-- link:builtin.html#types[Elective built-ins] cannot be executed.
82-- In link:exec.html#search[command search], a link:builtin.html#types[regular
83- built-in] needs to have a corresponding external command for the built-in to
84- be found.
81+- link:builtin.html#types[Elective and extension built-ins] cannot be executed.
8582 - Some link:builtin.html[built-ins] behave differently.
8683 Especially, long command-line options (as well as some others) cannot be
8784 used.
--- yash/trunk/exec.c (revision 4207)
+++ yash/trunk/exec.c (revision 4208)
@@ -97,7 +97,8 @@
9797 CT_SPECIALBUILTIN,
9898 CT_MANDATORYBUILTIN,
9999 CT_ELECTIVEBUILTIN,
100- CT_REGULARBUILTIN,
100+ CT_EXTENSIONBUILTIN,
101+ CT_SUBSTITUTIVEBUILTIN,
101102 CT_FUNCTION,
102103 } cmdtype_T;
103104
@@ -869,8 +870,8 @@
869870 * `name' and `wname' must contain the same string value.
870871 * If the SCT_ALL flag is not set:
871872 * * a function whose name contains a slash cannot be found
872- * * a regular built-in cannot be found in the POSIXly correct mode if the
873- * SCT_EXTERNAL flag is not set either.
873+ * * a substitutive built-in cannot be found if the SCT_EXTERNAL flag is not
874+ * set either.
874875 * If the SCT_EXTERNAL flag is set, the SCT_CHECK flag is not set, and `name'
875876 * contains a slash, the external command of the given `name' is always found.
876877 */
@@ -910,11 +911,18 @@
910911 ci->type = CT_ELECTIVEBUILTIN;
911912 ci->ci_builtin = bi->body;
912913 return;
914+ case BI_EXTENSION:
915+ if (posixly_correct) {
916+ bi = NULL;
917+ break;
918+ } else {
919+ ci->type = CT_EXTENSIONBUILTIN;
920+ ci->ci_builtin = bi->body;
921+ return;
922+ }
913923 case BI_SPECIAL:
914924 assert(false);
915- case BI_REGULAR:
916- if (!posixly_correct)
917- goto regular_builtin;
925+ case BI_SUBSTITUTIVE:
918926 break;
919927 }
920928 }
@@ -936,9 +944,8 @@
936944 cmdpath = get_command_path(name, false);
937945 if (cmdpath != NULL) {
938946 if (bi != NULL) {
939-regular_builtin:
940- assert(bi->type == BI_REGULAR);
941- ci->type = CT_REGULARBUILTIN;
947+ assert(bi->type == BI_SUBSTITUTIVE);
948+ ci->type = CT_SUBSTITUTIVEBUILTIN;
942949 ci->ci_builtin = bi->body;
943950 } else {
944951 ci->type = CT_EXTERNALPROGRAM;
@@ -1034,7 +1041,8 @@
10341041 /* falls thru! */
10351042 case CT_SPECIALBUILTIN:
10361043 case CT_MANDATORYBUILTIN:
1037- case CT_REGULARBUILTIN:
1044+ case CT_EXTENSIONBUILTIN:
1045+ case CT_SUBSTITUTIVEBUILTIN:
10381046 yash_error_message_count = 0;
10391047
10401048 const wchar_t *savecbn = current_builtin_name;
@@ -2467,7 +2475,11 @@
24672475 msgfmt = humanfriendly ? gt("%s: an elective built-in\n") : "%s\n";
24682476 xprintf(msgfmt, name);
24692477 break;
2470- case CT_REGULARBUILTIN:;
2478+ case CT_EXTENSIONBUILTIN:
2479+ msgfmt = humanfriendly ? gt("%s: an extension built-in\n") : "%s\n";
2480+ xprintf(msgfmt, name);
2481+ break;
2482+ case CT_SUBSTITUTIVEBUILTIN:;
24712483 const char *cmdpath;
24722484 if (type & SCT_STDPATH)
24732485 cmdpath = get_command_path_default(name);
@@ -2475,8 +2487,8 @@
24752487 cmdpath = get_command_path(name, false);
24762488 if (humanfriendly) {
24772489 msgfmt = (cmdpath == NULL)
2478- ? Ngt("%s: a regular built-in (not found in $PATH)\n")
2479- : Ngt("%s: a regular built-in at %s\n");
2490+ ? Ngt("%s: a substitutive built-in (not found in $PATH)\n")
2491+ : Ngt("%s: a substitutive built-in for %s\n");
24802492 xprintf(gt(msgfmt), name, cmdpath);
24812493 } else {
24822494 xprintf("%s\n", (cmdpath == NULL) ? name : cmdpath);
--- yash/trunk/lineedit/complete.c (revision 4207)
+++ yash/trunk/lineedit/complete.c (revision 4208)
@@ -1376,6 +1376,7 @@
13761376 { L'-', L"dirstack-index", OPTARG_NONE, true, NULL, },
13771377 { L'-', L"elective-builtin", OPTARG_NONE, true, NULL, },
13781378 { L'-', L"executable-file", OPTARG_NONE, true, NULL, },
1379+ { L'-', L"extension-builtin", OPTARG_NONE, true, NULL, },
13791380 { L'-', L"external-command", OPTARG_NONE, true, NULL, },
13801381 { L'f', L"file", OPTARG_NONE, true, NULL, },
13811382 { L'-', L"finished-job", OPTARG_NONE, true, NULL, },
@@ -1401,6 +1402,7 @@
14011402 { L'-', L"signal", OPTARG_NONE, true, NULL, },
14021403 { L'-', L"special-builtin", OPTARG_NONE, true, NULL, },
14031404 { L'-', L"stopped-job", OPTARG_NONE, true, NULL, },
1405+ { L'-', L"substitutive-builtin", OPTARG_NONE, true, NULL, },
14041406 { L'S', L"suffix", OPTARG_REQUIRED, true, NULL, },
14051407 { L'u', L"username", OPTARG_NONE, true, NULL, },
14061408 { L'v', L"variable", OPTARG_NONE, true, NULL, },
@@ -1473,7 +1475,15 @@
14731475 case L'x':
14741476 switch (opt->longopt[2]) {
14751477 case L'e': cgtype |= CGT_EXECUTABLE; break;
1476- case L't': cgtype |= CGT_EXTCOMMAND; break;
1478+ case L't':
1479+ assert(opt->longopt[3] == L'e');
1480+ switch (opt->longopt[4]) {
1481+ case L'n':
1482+ cgtype |= CGT_XBUILTIN; break;
1483+ case L'r':
1484+ cgtype |= CGT_EXTCOMMAND; break;
1485+ }
1486+ break;
14771487 default: assert(false);
14781488 }
14791489 break;
@@ -1497,7 +1507,9 @@
14971507 case L'n': cgtype |= CGT_NALIAS; break;
14981508 case L'r':
14991509 switch (opt->longopt[1]) {
1500- case L'e': cgtype |= CGT_RBUILTIN; break;
1510+ case L'e':
1511+ cgtype |= CGT_XBUILTIN | CGT_UBUILTIN;
1512+ break;
15011513 case L'u': cgtype |= CGT_RUNNING; break;
15021514 default: assert(false);
15031515 }
@@ -1511,6 +1523,7 @@
15111523 case L'i': cgtype |= CGT_SIGNAL; break;
15121524 case L'p': cgtype |= CGT_SBUILTIN; break;
15131525 case L't': cgtype |= CGT_STOPPED; break;
1526+ case L'u': cgtype |= CGT_UBUILTIN; break;
15141527 default: assert(false);
15151528 }
15161529 break;
--- yash/trunk/lineedit/complete.h (revision 4207)
+++ yash/trunk/lineedit/complete.h (revision 4208)
@@ -134,28 +134,30 @@
134134 CGT_SBUILTIN = 1 << 3, // special builtin
135135 CGT_MBUILTIN = 1 << 4, // mandatory builtin
136136 CGT_LBUILTIN = 1 << 5, // elective builtin
137- CGT_RBUILTIN = 1 << 6, // regular builtin
138- CGT_BUILTIN = CGT_SBUILTIN | CGT_MBUILTIN | CGT_LBUILTIN | CGT_RBUILTIN,
139- CGT_EXTCOMMAND = 1 << 7, // external command
140- CGT_FUNCTION = 1 << 8, // function
137+ CGT_XBUILTIN = 1 << 6, // extension builtin
138+ CGT_UBUILTIN = 1 << 7, // substitutive builtin
139+ CGT_BUILTIN = CGT_SBUILTIN | CGT_MBUILTIN | CGT_LBUILTIN | CGT_XBUILTIN |
140+ CGT_UBUILTIN,
141+ CGT_EXTCOMMAND = 1 << 8, // external command
142+ CGT_FUNCTION = 1 << 9, // function
141143 CGT_COMMAND = CGT_BUILTIN | CGT_EXTCOMMAND | CGT_FUNCTION,
142- CGT_KEYWORD = 1 << 9, // shell keyword
143- CGT_NALIAS = 1 << 10, // non-global alias
144- CGT_GALIAS = 1 << 11, // global alias
144+ CGT_KEYWORD = 1 << 10, // shell keyword
145+ CGT_NALIAS = 1 << 11, // non-global alias
146+ CGT_GALIAS = 1 << 12, // global alias
145147 CGT_ALIAS = CGT_NALIAS | CGT_GALIAS,
146- CGT_SCALAR = 1 << 12, // scalar variable
147- CGT_ARRAY = 1 << 13, // array variable
148+ CGT_SCALAR = 1 << 13, // scalar variable
149+ CGT_ARRAY = 1 << 14, // array variable
148150 CGT_VARIABLE = CGT_SCALAR | CGT_ARRAY,
149- CGT_RUNNING = 1 << 14, // running job
150- CGT_STOPPED = 1 << 15, // stopped job
151- CGT_DONE = 1 << 16, // finished job
151+ CGT_RUNNING = 1 << 15, // running job
152+ CGT_STOPPED = 1 << 16, // stopped job
153+ CGT_DONE = 1 << 17, // finished job
152154 CGT_JOB = CGT_RUNNING | CGT_STOPPED | CGT_DONE,
153- CGT_SIGNAL = 1 << 17, // signal name
154- CGT_LOGNAME = 1 << 18, // login user name
155- CGT_GROUP = 1 << 19, // group name
156- CGT_HOSTNAME = 1 << 20, // host name
157- CGT_BINDKEY = 1 << 21, // line-editing command name
158- CGT_DIRSTACK = 1 << 22, // directory stack entry
155+ CGT_SIGNAL = 1 << 18, // signal name
156+ CGT_LOGNAME = 1 << 19, // login user name
157+ CGT_GROUP = 1 << 20, // group name
158+ CGT_HOSTNAME = 1 << 21, // host name
159+ CGT_BINDKEY = 1 << 22, // line-editing command name
160+ CGT_DIRSTACK = 1 << 23, // directory stack entry
159161 } le_candgentype_T;
160162 typedef struct le_comppattern_T {
161163 struct le_comppattern_T *next;
--- yash/trunk/po/ja.po (revision 4207)
+++ yash/trunk/po/ja.po (revision 4208)
@@ -8,8 +8,8 @@
88 msgstr ""
99 "Project-Id-Version: yash 2.54\n"
1010 "Report-Msgid-Bugs-To: http://osdn.jp/projects/yash/forums/\n"
11-"POT-Creation-Date: 2022-09-26 14:34+0900\n"
12-"PO-Revision-Date: 2022-09-26 14:38+0900\n"
11+"POT-Creation-Date: 2022-09-27 00:48+0900\n"
12+"PO-Revision-Date: 2022-09-27 23:31+0900\n"
1313 "Last-Translator: WATANABE Yuki <magicant@users.osdn.me>\n"
1414 "Language-Team: Japanese\n"
1515 "Language: ja\n"
@@ -119,12 +119,12 @@
119119 msgid "arithmetic: `%lc' is not a valid number or operator"
120120 msgstr "数式展開:「%lc」は有効な数値や演算子ではありません"
121121
122-#: builtin.c:249
122+#: builtin.c:252
123123 #, c-format
124124 msgid "the -%lc option cannot be used with the -%lc option"
125125 msgstr "-%lc オプションは -%lc オプションとは一緒に使えません"
126126
127-#: builtin.c:275
127+#: builtin.c:278
128128 #, c-format
129129 msgid "this command requires an operand"
130130 msgid_plural "this command requires %zu operands"
@@ -132,27 +132,27 @@
132132
133133 #. TRANSLATORS: This message is printed when a command that takes no
134134 #. * operand was invoked with some operands.
135-#: builtin.c:288
135+#: builtin.c:291
136136 msgid "no operand is expected"
137137 msgstr "このコマンドはオペランドを受け付けません"
138138
139139 #. TRANSLATORS: This message is printed when a command was invoked with
140140 #. * the wrong number of operands.
141-#: builtin.c:292
141+#: builtin.c:295
142142 msgid "too many operands are specified"
143143 msgstr "オペランドの数が多すぎます"
144144
145-#: builtin.c:344 yash.c:391
145+#: builtin.c:347 yash.c:391
146146 msgid "Try `man yash' for details.\n"
147147 msgstr "詳しくは: man yash\n"
148148
149-#: builtin.c:359
149+#: builtin.c:362
150150 #, c-format
151151 msgid "no such built-in `%ls'"
152152 msgstr "「%ls」というような組込みコマンドはありません"
153153
154154 #. TRANSLATORS: This is printed before syntax info of a built-in.
155-#: builtin.c:367
155+#: builtin.c:370
156156 #, c-format
157157 msgid ""
158158 "Syntax:\n"
@@ -162,39 +162,39 @@
162162 "%s\n"
163163
164164 #. TRANSLATORS: This text is printed before a list of options.
165-#: builtin.c:386 builtin.c:406
165+#: builtin.c:389 builtin.c:409
166166 msgid "Options:\n"
167167 msgstr "オプション:\n"
168168
169-#: builtin.c:546
169+#: builtin.c:550
170170 msgid "do nothing"
171171 msgstr "何もしない"
172172
173-#: builtin.c:549
173+#: builtin.c:553
174174 msgid "\t: [...]\n"
175175 msgstr "\t: [...]\n"
176176
177-#: builtin.c:553
177+#: builtin.c:557
178178 msgid "do nothing successfully"
179179 msgstr "何もせず成功を返す"
180180
181-#: builtin.c:556
181+#: builtin.c:560
182182 msgid "\ttrue\n"
183183 msgstr "\ttrue\n"
184184
185-#: builtin.c:560
185+#: builtin.c:564
186186 msgid "do nothing unsuccessfully"
187187 msgstr "何もせず失敗を返す"
188188
189-#: builtin.c:563
189+#: builtin.c:567
190190 msgid "\tfalse\n"
191191 msgstr "\tfalse\n"
192192
193-#: builtin.c:588
193+#: builtin.c:592
194194 msgid "print usage of built-in commands"
195195 msgstr "組込みコマンドの使い方を表示する"
196196
197-#: builtin.c:591
197+#: builtin.c:595
198198 msgid "\thelp [built-in...]\n"
199199 msgstr "\thelp [組込みコマンド...]\n"
200200
@@ -235,7 +235,7 @@
235235 msgstr "「%ls」は有効な数値ではありません"
236236
237237 #: builtins/printf.c:694 builtins/test.c:585 builtins/test.c:591
238-#: builtins/ulimit.c:229 exec.c:1863 exec.c:1936 history.c:1721 sig.c:1429
238+#: builtins/ulimit.c:229 exec.c:1871 exec.c:1944 history.c:1721 sig.c:1429
239239 #: variable.c:2137 variable.c:2197 variable.c:2236 variable.c:2420 yash.c:631
240240 #, c-format
241241 msgid "`%ls' is not a valid integer"
@@ -267,8 +267,8 @@
267267 msgid "`%ls' is not a unary operator"
268268 msgstr "「%ls」は単項演算子ではありません"
269269
270-#: builtins/test.c:188 builtins/test.c:656 builtins/test.c:664 exec.c:2072
271-#: exec.c:2216 exec.c:2225 history.c:1499 lineedit/keymap.c:476 path.c:1274
270+#: builtins/test.c:188 builtins/test.c:656 builtins/test.c:664 exec.c:2080
271+#: exec.c:2224 exec.c:2233 history.c:1499 lineedit/keymap.c:476 path.c:1274
272272 #: path.c:1341 strbuf.c:566 strbuf.c:589
273273 msgid "unexpected error"
274274 msgstr "想定外のエラーです"
@@ -389,77 +389,77 @@
389389 "\tulimit -a [-H|-S]\n"
390390 "\tulimit [-H|-S] [-efilnqrstuvx] [制限]\n"
391391
392-#: exec.c:612
392+#: exec.c:613
393393 msgid "cannot open a pipe"
394394 msgstr "パイプを開けません"
395395
396-#: exec.c:1014 exec.c:2240 exec.c:2453
396+#: exec.c:1021 exec.c:2248 exec.c:2461
397397 #, c-format
398398 msgid "no such command `%s'"
399399 msgstr "「%s」というようなコマンドはありません"
400400
401-#: exec.c:1028
401+#: exec.c:1035
402402 #, c-format
403403 msgid "%ls: non-portable built-in is not supported in the POSIXly-correct mode"
404404 msgstr "%ls: POSIX 準拠モードでは使えません"
405405
406-#: exec.c:1083
406+#: exec.c:1091
407407 #, c-format
408408 msgid "cannot execute command `%s'"
409409 msgstr "コマンド「%s」を実行できません"
410410
411-#: exec.c:1084
411+#: exec.c:1092
412412 #, c-format
413413 msgid "cannot execute command `%s' (%s)"
414414 msgstr "コマンド「%s」(%s) を実行できません"
415415
416-#: exec.c:1142
416+#: exec.c:1150
417417 #, c-format
418418 msgid "cannot invoke a new shell to execute script `%s'"
419419 msgstr "スクリプト「%s」を実行するための新しいシェルを起動できません"
420420
421-#: exec.c:1492
421+#: exec.c:1500
422422 msgid "cannot make a child process"
423423 msgstr "子プロセスを生成できません"
424424
425-#: exec.c:1560 exec.c:1582
425+#: exec.c:1568 exec.c:1590
426426 msgid "cannot open a pipe for the command substitution"
427427 msgstr "コマンド置換のためのパイプを開けません"
428428
429-#: exec.c:1619
429+#: exec.c:1627
430430 msgid "command substitution"
431431 msgstr "コマンド置換"
432432
433-#: exec.c:1873
433+#: exec.c:1881
434434 msgid "cannot be used in the interactive mode"
435435 msgstr "対話モードでは使えません"
436436
437-#: exec.c:1883
437+#: exec.c:1891
438438 msgid "return from a function or script"
439439 msgstr "関数やスクリプトから抜ける"
440440
441-#: exec.c:1886
441+#: exec.c:1894
442442 msgid "\treturn [-n] [exit_status]\n"
443443 msgstr "\treturn [-n] [終了ステータス]\n"
444444
445-#: exec.c:1918
445+#: exec.c:1926
446446 msgid "not in an iteration"
447447 msgstr "反復実行の途中ではありません"
448448
449-#: exec.c:1939
449+#: exec.c:1947
450450 #, c-format
451451 msgid "%u is not a positive integer"
452452 msgstr "%u は正の整数ではありません"
453453
454-#: exec.c:1949
454+#: exec.c:1957
455455 msgid "not in a loop"
456456 msgstr "ループの途中ではありません"
457457
458-#: exec.c:1968
458+#: exec.c:1976
459459 msgid "exit a loop"
460460 msgstr "ループを抜ける"
461461
462-#: exec.c:1971
462+#: exec.c:1979
463463 msgid ""
464464 "\tbreak [count]\n"
465465 "\tbreak -i\n"
@@ -467,11 +467,11 @@
467467 "\tbreak [深さ]\n"
468468 "\tbreak -i\n"
469469
470-#: exec.c:1976
470+#: exec.c:1984
471471 msgid "continue a loop"
472472 msgstr "ループの先頭に戻る"
473473
474-#: exec.c:1979
474+#: exec.c:1987
475475 msgid ""
476476 "\tcontinue [count]\n"
477477 "\tcontinue -i\n"
@@ -479,104 +479,109 @@
479479 "\tcontinue [深さ]\n"
480480 "\tcontinue -i\n"
481481
482-#: exec.c:2019
482+#: exec.c:2027
483483 msgid "evaluate arguments as a command"
484484 msgstr "引数をコマンドとして実行する"
485485
486-#: exec.c:2022
486+#: exec.c:2030
487487 msgid "\teval [-i] [argument...]\n"
488488 msgstr "\teval [-i] [引数...]\n"
489489
490-#: exec.c:2081
490+#: exec.c:2089
491491 #, c-format
492492 msgid "file `%s' was not found in $YASH_LOADPATH"
493493 msgstr "ファイル「%s」は $YASH_LOADPATH 内に見つかりませんでした"
494494
495-#: exec.c:2091
495+#: exec.c:2099
496496 #, c-format
497497 msgid "file `%s' was not found in $PATH"
498498 msgstr "ファイル「%s」は $PATH 内に見つかりませんでした"
499499
500-#: exec.c:2103 redir.c:276 yash.c:206
500+#: exec.c:2111 redir.c:276 yash.c:206
501501 #, c-format
502502 msgid "cannot open file `%s'"
503503 msgstr "ファイル「%s」を開けません"
504504
505-#: exec.c:2142
505+#: exec.c:2150
506506 msgid "read a file and execute commands"
507507 msgstr "ファイルをスクリプトとして実行する"
508508
509-#: exec.c:2145
509+#: exec.c:2153
510510 msgid "\t. [-AL] file [argument...]\n"
511511 msgstr "\t. [-AL] ファイル [引数...]\n"
512512
513-#: exec.c:2193 yash.c:618
513+#: exec.c:2201 yash.c:618
514514 #, c-format
515515 msgid "You have a stopped job!"
516516 msgid_plural "You have %zu stopped jobs!"
517517 msgstr[0] "停止中のジョブが %zu 個あります!"
518518
519-#: exec.c:2197
519+#: exec.c:2205
520520 msgid " Use the -f option to exec anyway.\n"
521521 msgstr " それでも exec するには -f オプションを付けてください。\n"
522522
523-#: exec.c:2287
523+#: exec.c:2295
524524 msgid "replace the shell process with an external command"
525525 msgstr "シェルのプロセスを外部コマンドに変える"
526526
527-#: exec.c:2290
527+#: exec.c:2298
528528 msgid "\texec [-cf] [-a name] [command [argument...]]\n"
529529 msgstr "\texec [-cf] [-a 名前] [コマンド [引数...]]\n"
530530
531-#: exec.c:2350
531+#: exec.c:2358
532532 msgid "the -a or -k option must be used with the -v option"
533533 msgstr "-a および -k オプションは -v オプションと一緒にしか使えません"
534534
535-#: exec.c:2430
535+#: exec.c:2438
536536 #, c-format
537537 msgid "%ls: a shell keyword\n"
538538 msgstr "%ls: シェルの予約語\n"
539539
540-#: exec.c:2459
540+#: exec.c:2467
541541 #, c-format
542542 msgid "%s: a special built-in\n"
543543 msgstr "%s: 特殊組込みコマンド\n"
544544
545-#: exec.c:2463
545+#: exec.c:2471
546546 #, c-format
547547 msgid "%s: a mandatory built-in\n"
548548 msgstr "%s: 必須組込みコマンド\n"
549549
550-#: exec.c:2467
550+#: exec.c:2475
551551 #, c-format
552552 msgid "%s: an elective built-in\n"
553553 msgstr "%s: 任意組込みコマンド\n"
554554
555-#: exec.c:2478
555+#: exec.c:2479
556556 #, c-format
557-msgid "%s: a regular built-in (not found in $PATH)\n"
558-msgstr "%s: 通常の組込みコマンド ($PATH 内に存在せず)\n"
557+msgid "%s: an extension built-in\n"
558+msgstr "%s: 拡張組込みコマンド\n"
559559
560-#: exec.c:2479
560+#: exec.c:2490
561561 #, c-format
562-msgid "%s: a regular built-in at %s\n"
563-msgstr "%s: 通常の組込みコマンド (%s)\n"
562+msgid "%s: a substitutive built-in (not found in $PATH)\n"
563+msgstr "%s: 代替組込みコマンド ($PATH 内に存在せず)\n"
564564
565-#: exec.c:2486
565+#: exec.c:2491
566566 #, c-format
567+msgid "%s: a substitutive built-in for %s\n"
568+msgstr "%s: 代替組込みコマンド (%s)\n"
569+
570+#: exec.c:2498
571+#, c-format
567572 msgid "%s: a function\n"
568573 msgstr "%s: 関数\n"
569574
570-#: exec.c:2536
575+#: exec.c:2548
571576 #, c-format
572577 msgid "%s: an external command at %s\n"
573578 msgstr "%s: 外部コマンド (%s)\n"
574579
575-#: exec.c:2544
580+#: exec.c:2556
576581 msgid "execute or identify a command"
577582 msgstr "コマンドを実行または特定する"
578583
579-#: exec.c:2547
584+#: exec.c:2559
580585 msgid ""
581586 "\tcommand [-befp] command [argument...]\n"
582587 "\tcommand -v|-V [-abefkp] command...\n"
@@ -584,23 +589,23 @@
584589 "\tcommand [-befp] コマンド [引数...]\n"
585590 "\tcommand -v|-V [-abefkp] コマンド...\n"
586591
587-#: exec.c:2552
592+#: exec.c:2564
588593 msgid "identify a command"
589594 msgstr "コマンドを特定する"
590595
591-#: exec.c:2555
596+#: exec.c:2567
592597 msgid "\ttype command...\n"
593598 msgstr "\ttype コマンド...\n"
594599
595-#: exec.c:2593
600+#: exec.c:2605
596601 msgid "cannot get the time data"
597602 msgstr "時間情報を取得できません"
598603
599-#: exec.c:2610
604+#: exec.c:2622
600605 msgid "print CPU time usage"
601606 msgstr "消費 CPU 時間を表示する"
602607
603-#: exec.c:2613
608+#: exec.c:2625
604609 msgid "\ttimes\n"
605610 msgstr "\ttimes\n"
606611
@@ -890,25 +895,25 @@
890895 "\tdisown [ジョブ...]\n"
891896 "\tdisown -a\n"
892897
893-#: lineedit/complete.c:1522
898+#: lineedit/complete.c:1535
894899 #, c-format
895900 msgid "more than one -%lc option is specified"
896901 msgstr "-%lc が二回以上指定されています"
897902
898-#: lineedit/complete.c:1534
903+#: lineedit/complete.c:1547
899904 msgid "the complete built-in can be used during command line completion only"
900905 msgstr "complete 組込みコマンドはコマンドライン補完の最中にしか使えません"
901906
902-#: lineedit/complete.c:1547
907+#: lineedit/complete.c:1560
903908 #, c-format
904909 msgid "the specified prefix `%ls' does not match the target word `%ls'"
905910 msgstr "指定された接頭辞「%ls」は補完対象「%ls」に適合しません"
906911
907-#: lineedit/complete.c:1595
912+#: lineedit/complete.c:1608
908913 msgid "generate completion candidates"
909914 msgstr "補完候補を生成する"
910915
911-#: lineedit/complete.c:1598
916+#: lineedit/complete.c:1611
912917 msgid ""
913918 "\tcomplete [-A pattern] [-R pattern] [-T] [-P prefix] [-S suffix] \\\n"
914919 "\t [-abcdfghjkuv] [[-O] [-D description] words...]\n"
Show on old repository browser