[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Claim `declare' as a special command in manual?
From: |
Eduardo A . Bustamante López |
Subject: |
Re: Claim `declare' as a special command in manual? |
Date: |
Wed, 8 Nov 2017 07:48:34 -0600 |
User-agent: |
NeoMutt/20170609 (1.8.3) |
On Wed, Nov 08, 2017 at 12:20:23PM +0800, Clark Wang wrote:
[...]
> It seems to me bash internally parses the `declare' command specially and
> (logically) convert `declare -a arr=()' to two statements `declare -a arr'
> and `arr=()'.
There is indeed special treatment for assignment builtins in the parser:
dualbus@ubuntu:~/src/gnu/bash$ ack -H -C3 ASSIGNMENT_BUILTIN parse.y
parse.y
5222- {
5223- struct builtin *b;
5224- b = builtin_address_internal (token, 0);
5225: if (b && (b->flags & ASSIGNMENT_BUILTIN))
5226- parser_state |= PST_ASSIGNOK;
5227- else if (STREQ (token, "eval") || STREQ (token, "let"))
5228- parser_state |= PST_ASSIGNOK;
> So does it make sense to move `declare' out of the SHELL BUILTIN COMMANDS
> and put it in a separate section? Or at least explicitly state that
> `declare' is special?
But is it only `declare' that is special?
According to:
dualbus@ubuntu:~/src/gnu/bash$ ack -H ASSIGNMENT_BUILTIN builtins.h
builtins.h
45:#define ASSIGNMENT_BUILTIN 0x10 /* This builtin takes assignment
statements. */
A builtin is an assignment builtin if builtin->flags has the ASSIGNMENT_BUILTIN
bit enabled.
You can see which builtins are assignment builtins by looking at
builtins/mkbuiltins.c:
dualbus@ubuntu:~/src/gnu/bash$ ack -H -C3 'char \*assignment_builtins'
builtins/mkbuiltins.c
builtins/mkbuiltins.c
154-};
155-
156-/* The builtin commands that take assignment statements as arguments. */
157:char *assignment_builtins[] =
158-{
159- "alias", "declare", "export", "local", "readonly", "typeset",
160- (char *)NULL
Now, there's a slight complication. Loadable builtins are also subject to this
special treatment. That is, you can define a new loadable builtin which is an
assignment builtin. Which means that if you only document the 6 builtins above
in the manual, the information will not be complete.
I think the proper approach would be to mention in the manual that there are
"assignment builtins", and that you can see the complete list with `enable
-<something>'
As a side note, this special treatment does lead to some weirdness around
shadowing assignment builtins with functions, or using them with the `builtin'
builtin:
dualbus@ubuntu:~$ typeset -fp declare
-bash: typeset: declare: not found
dualbus@ubuntu:~$ declare a=()
dualbus@ubuntu:~$ typeset -p a
declare -a a=()
dualbus@ubuntu:~$ builtin declare b=()
-bash: syntax error near unexpected token `('
dualbus@ubuntu:~$ typeset -p b
-bash: typeset: b: not found
dualbus@ubuntu:~$ declare() { builtin declare "$@"; }
dualbus@ubuntu:~$ declare b=()
dualbus@ubuntu:~$ typeset -p b
declare -a b=()
dualbus@ubuntu:~$ declare() { echo nope "$@"; }
dualbus@ubuntu:~$ declare c=()
nope c
dualbus@ubuntu:~$ typeset -p c
declare -a c=()