Re: bottom of ${BASH_LINENO[*]} stack is always '0'

2023-02-22 Thread Eduardo Bustamante
On Tue, Feb 21, 2023 at 2:58 PM bill-auger  wrote:
>
> the bottom of the ${BASH_LINENO[*]} stack is always '0'; and the
> array never contains the line number of the actual call site, as
> ${LINENO} does - is that expected behavior?
>
> im not sure if this is a bug or not - it seems like a bug to me
> though - the '0' value is meaningless and useless, yes?

It may make more sense if you consider that BASH_LINENO is meant to
supplement the FUNCNAME and BASH_SOURCE arrays. It doesn't seem quite
useful on its own.

>From the manual:

| BASH_LINENO
|An array variable whose members are the line numbers in
source files where each corresponding member of FUNCNAME was invoked.
${BASH_LINENO[$i]} is the line number in the
|source  file  (${BASH_SOURCE[$i+1]}) where ${FUNCNAME[$i]}
was called (or ${BASH_LINENO[$i-1]} if referenced within another shell
function).  Use LINENO to obtain the cur‐
|rent line number.

| BASH_SOURCE
|An  array  variable  whose  members  are  the source
filenames where the corresponding shell function names in the FUNCNAME
array variable are defined.  The shell function
|${FUNCNAME[$i]} is defined in the file ${BASH_SOURCE[$i]} and
called from ${BASH_SOURCE[$i+1]}.

| FUNCNAME
|An array variable containing the names of all shell functions
currently in the execution call stack.  The element with index 0 is
the name of any currently-executing shell
|function.  The bottom-most element (the one with the highest
index) is "main".  This variable exists only when a shell function is
executing.  Assignments to FUNCNAME have
|no effect.  If FUNCNAME is unset, it loses its special
properties, even if it is subsequently reset.
|
|This variable can be used with BASH_LINENO and BASH_SOURCE.
Each element of FUNCNAME has corresponding elements in BASH_LINENO and
BASH_SOURCE to describe the call stack.
|For instance, ${FUNCNAME[$i]} was called from the file
${BASH_SOURCE[$i+1]} at line number ${BASH_LINENO[$i]}.  The caller
builtin displays the current  call  stack  using
|this information.

With a call stack that looks like this

f2 <- called by -- f1

You'd expect to see the following: FUNCNAME=([0]="f2" [1]="f1" [2]="main")

Notice that 'main' is the bottom of the stack. This is not an actual
function, but a name given to the main shell script, i.e. the script
that sources and/or calls other functions. As 'main'
does not correspond to an actual line on a script, I think it's
appropriate for its line number to be 0. It might as well be -1, '',
or any other value that does not map to a real piece of code.

My guess as to why 'main' is in FUNCNAME -- and therefore its "line
number" in BASH_LINENO -- is that it allows you to determine which
shell script is the main script. That'd be 'foo' in the following
example:

$ cat foo
source bar

$ cat bar
f() {
  declare -p BASH_SOURCE FUNCNAME BASH_LINENO
}
f

$ bash foo
declare -a BASH_SOURCE=([0]="bar" [1]="bar" [2]="foo")
declare -a FUNCNAME=([0]="f" [1]="source" [2]="main")
declare -a BASH_LINENO=([0]="4" [1]="1" [2]="0")



bottom of ${BASH_LINENO[*]} stack is always '0'

2023-02-21 Thread bill-auger
the bottom of the ${BASH_LINENO[*]} stack is always '0'; and the
array never contains the line number of the actual call site, as
${LINENO} does - is that expected behavior?

im not sure if this is a bug or not - it seems like a bug to me
though - the '0' value is meaningless and useless, yes?


$ cat ./bash_lineno.sh 
#!/bin/bash

echo "[LOC_${LINENO} ]: ${BASH_LINENO[@]}"

f1()
{
  echo "[LOC_${LINENO} ]: ${BASH_LINENO[@]}"
  f2 # LOC_8
}

f2()
{
  echo "[LOC_${LINENO}]: ${BASH_LINENO[@]}"
}

f1 # LOC_16

echo "[LOC_${LINENO}]: ${BASH_LINENO[@]}"


$ ./bash_lineno.sh
[LOC_3 ]: 0
[LOC_7 ]: 16 0
[LOC_13]: 8 16 0
[LOC_18]: 0


$ bash --version
GNU bash, version 5.1.16(1)-release (x86_64-pc-linux-gnu)