bug-bash
[Top][All Lists]
Advanced

[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=()



reply via email to

[Prev in Thread] Current Thread [Next in Thread]