Re: "printf %d ''" should diagnose the empty string

2025-02-10 Thread Phi Debian
On Sat, Feb 8, 2025 at 8:51 AM Robert Elz  wrote:

>
> There are a gazillion different ways of getting rid of the octal
> conversion "problem", one I prefer in cases where I know the value
> is 2 digits, always, but might be 0n for 0<=n<=9, is  $(( 1$x - 100 ))
>
> kre
>
>
 gazillion++
You say "I know the value is 2 digits" you forgot to say in base 10 but it
was kinda implicit in the thread, then a more general one not limited to 2
decimal digit accepting leading 0 you could simply do $((10#$i))

That really sez you expect a base 10, some more readable I think... (may be)


Re: "printf %d ''" should diagnose the empty string

2025-02-10 Thread Phi Debian
On Mon, Feb 10, 2025 at 1:15 PM Greg Wooledge  wrote:

Ha now we introduce signed (not obvious from original post)


> The following line noise is the best *general* answer we've found
> so far:
>
> $((${num%%[!+-]*}10#${num#[-+]}))


If 'best *general*' refer to the shortest line noise does

$((${i/?([-+])/&10#}))

Qualify for better than best ? :-) if so you may add in your web bible
don't forget to mention the inventor :-)

Nice and easy


Re: "printf %d ''" should diagnose the empty string

2025-02-10 Thread Greg Wooledge
On Mon, Feb 10, 2025 at 15:20:55 +0100, Phi Debian wrote:
> If 'best *general*' refer to the shortest line noise does
> 
> $((${i/?([-+])/&10#}))
> 
> Qualify for better than best ? :-) if so you may add in your web bible
> don't forget to mention the inventor :-)

Can you please explain *how* this is working in older bash versions?
According to the CHANGES file, the processing of `&' by patsub_replacement
is new in bash 5.2.  And yet:

hobbit:~$ bash-2.05b
bash-2.05b: /home/greg/.bashrc: line 95: syntax error in conditional 
expression: unexpected token `('
bash-2.05b: /home/greg/.bashrc: line 95: syntax error near `+(['
bash-2.05b: /home/greg/.bashrc: line 95: `if [[ $letters != +([A-Z]) ]]; 
then'
hobbit:~$ shopt | grep extglob
extglob off
hobbit:~$ var=-023
hobbit:~$ echo "$(( ${var/?([-+])/&10#} ))"
-19

So, not only is the & being respected, but the extended glob is also
working, despite extglob being visibly disabled.  Not to mention, this
version is decades older than the patsub_replacement feature, at least
according to the documentation we have.



Re: "printf %d ''" should diagnose the empty string

2025-02-10 Thread Chet Ramey

On 2/10/25 11:34 AM, Zachary Santer wrote:

On Mon, Feb 10, 2025 at 9:20 AM Phi Debian  wrote:


If 'best *general*' refer to the shortest line noise does

$((${i/?([-+])/&10#}))

Qualify for better than best ? :-)


And then this isn't even half as good:


There isn't a reward for brevity or obfuscation; say what you mean:

isnum2()
{
case "$1" in
[-+] | '')  return 1;;  # empty or bare `-' or `+'
[-+]*[!0-9]*)   return 1;;  # non-digit with leading sign
[-+]*)  return 0;;  # OK
*[!0-9]*)   return 1;;  # non-digit
*)  return 0;;  # OK
esac
}

It obviously doesn't handle 0x constants, but could be changed to.

--
``The lyf so short, the craft so long to lerne.'' - Chaucer
 ``Ars longa, vita brevis'' - Hippocrates
Chet Ramey, UTech, CWRUc...@case.eduhttp://tiswww.cwru.edu/~chet/


OpenPGP_signature.asc
Description: OpenPGP digital signature


Re: "printf %d ''" should diagnose the empty string

2025-02-10 Thread Chet Ramey

On 2/7/25 10:21 PM, Martin D Kealey wrote:

Hi Chet

We seem to have very similar opinions about strong backwards compatibility 
in theory, and yet somehow we keep butting heads on how that pans out in 
practice.


I'm concerned that the last ten years has seen a number of Linux 
distributions /stop/ including Bash by default, and it has ceased to be the 
language of choice for writing new scripts; for the most part that's now 
either Python, Node.js, or POSIX sh (dash).


I now wonder whether Bash has much of a future. Each breaking change pushes 
Bash ever closer to becoming an irrelevant anachronism. Conversely, changes 
that make it less error prone or easier to use somewhat pull it back from 
the brink of oblivion.


Taking another run up this hill, eh? This is very similar to

https://lists.gnu.org/archive/html/bug-bash/2023-11/msg00150.html

even down to the professed concern about bash becoming irrelevant.


My key point is that an empty string /meaning/ zero can arise quite 
ordinarily from /not/ treating zero as a special case.


There it is.



The proposed change in 5.3-alpha won't transform any broken programs into 
working ones, but it will break (at least a few) working programs. For example:


  * printf '%u\n' "${x##*(0)}"   # make sure x is not interpreted as octal


As long as you have extglob enabled somewhere to make this work.



It is irrelevant whether it is possible to rewrite this to avoid the 
proposed warning; what matters is that correctly working scripts will have 
to be audited (and potentially modified) if this change goes ahead. 


So if something worked only by chance -- not necessarily this, so we can
remove the emotion from the discussion -- and bash was changed to fix a
bug, or add a feature, it would be a problem if bash did that? It seems
like you only want the bugs fixed that don't break your code. Now, that's
fine -- self-interest is a powerful thing -- but it doesn't take into
account other users who want the bug fixed, does it?


I also think it is unreasonable to make printf inconsistent with other 
parts of Bash that /do/ (silently) allow empty to mean zero, including:


  * ${var:$empty:$length} or ${array[@]:$empty:$length};
  * $((empty));


This is not an arithmetic context like those. If you want the arguments to
printf %d to be treated as if they're in an arithmetic context, wrap them
in $(( ... )). (And note that the behavior of a missing expression in
$(( )) is a bash extension; the bash/mksh/ksh93 behavior is not shared by
the yash/ash-family shells).



Conversely, while we're looking at printf, why not produce warnings for:

  * negative arg for %u or %.*… precision;


No one warns on a negative arg for %u, and there's so much mixed behavior
with a negative precision argument that it's not worth warning about, since
POSIX explicitly says "A negative precision is taken as if the precision
were omitted."


  * spurious or repeated flags like %--9d (or %-*… with a negative width arg);


"A negative field width is taken as a '-' flag followed by a positive field
width."

and POSIX doesn't say anything about repeated flags being invalid, just
that zero or more flag characters may appear in any order.


  * the number of args to printf not being an whole multiple of the number
of required args;


Why warn about this? POSIX specifies the behavior in this case of missing
or extra args, and it's quite useful.



  * numeric overflow in $((expression)).


Bash doesn't warn about overflow anywhere.



For that matter, why /only/ a warning? If the point is to detect bugs in 
scripts, surely Bash should crash out, like errexit or nounset?


Because POSIX says

"If an argument operand cannot be completely converted into an internal
value appropriate to the corresponding conversion specification, a
diagnostic message shall be written to standard error and the utility shall
not exit with a zero exit status, but shall continue processing any
remaining operands and shall write the value accumulated at the time the
error was detected to standard output."

So if you're running in errexit mode you'll exit like you expect. I
encourage you to try something like

printf '%d\n' 12345xyz
echo after: $?

when running with errexit enabled and not.


If that's not the intent, please publish the rationale that separates the 
allowed and prohibited cases.


You should be able to figure that out from this discussion.




Of course, that's not the only reason why I think that adding this warning 
would be the wrong approach:


Right up front the manual says:

  * /Bash is intended to be a conformant implementation of the Shell and
Utilities portion of the IEEE POSIX specification (IEEE Standard 1003.1)./

This proposed change would appear to contradict this intent, since it makes 
the default mode less conformant,


https://lists.gnu.org/archive/html/bug-bash/2024-11/msg00156.html

POSIX says :


  *


Re: "printf %d ''" should diagnose the empty string

2025-02-10 Thread Zachary Santer
Once again left a dumb mistake in my bash snippet.

On Mon, Feb 10, 2025 at 11:34 AM Zachary Santer  wrote:
>
> And then this isn't even half as good:
>
int_regex='^([+-]?)0*([[:digit:]]+)$'
> if [[ ${var} =~ ${int_regex} ]]; then
>   var="${BASH_REMATCH[1]}${BASH_REMATCH[2]}"
> else
>   printf '%s\n' "Argument '${var}' is not a valid integer" >&2
> fi



Re: "printf %d ''" should diagnose the empty string

2025-02-10 Thread Greg Wooledge
On Mon, Feb 10, 2025 at 17:32:24 +0100, Phi Debian wrote:
> On Mon, Feb 10, 2025 at 3:43 PM Greg Wooledge  wrote:
> 
> >
> > Can you please explain *how* this is working in older bash versions?
> >
> 
> I forgot to mention 'best on modern bash' :-),
> as well as you forgot to mention
> 
> 'The following line noise is the best *general* answer we've found
> so far: with dyno bash'

No, I've shown that it *is* working in older versions of bash, and I'm
asking *why*.

As far as I can tell by reading the CHANGES file, it shouldn't work.

But it does.



Re: "printf %d ''" should diagnose the empty string

2025-02-10 Thread Phi Debian
On Mon, Feb 10, 2025 at 6:44 PM Greg Wooledge  wrote:

>
>
> No, I've shown that it *is* working in older versions of bash, and I'm
> asking *why*.
>
> As far as I can tell by reading the CHANGES file, it shouldn't work.
>
> But it does.
>

Jeez, sorry about that, my 'fast reading' parser skipped the 'why', and I
admit I don't know why.


Re: "printf %d ''" should diagnose the empty string

2025-02-10 Thread Zachary Santer
On Mon, Feb 10, 2025 at 9:20 AM Phi Debian  wrote:
>
> If 'best *general*' refer to the shortest line noise does
>
> $((${i/?([-+])/&10#}))
>
> Qualify for better than best ? :-)

And then this isn't even half as good:

int_regex='([+-]?)0*([[:digit:]]+)'
if [[ ${var} =~ ${int_regex} ]]; then
  var="${BASH_REMATCH[1]}${BASH_REMATCH[2]}"
else
  printf '%s\n' "Argument '${var}' is not a valid integer" >&2
fi



Re: "printf %d ''" should diagnose the empty string

2025-02-10 Thread Phi Debian
On Mon, Feb 10, 2025 at 3:43 PM Greg Wooledge  wrote:

>
> Can you please explain *how* this is working in older bash versions?
>

I forgot to mention 'best on modern bash' :-),
as well as you forgot to mention

'The following line noise is the best *general* answer we've found
so far: with dyno bash'
:-)


Re: "printf %d ''" should diagnose the empty string

2025-02-10 Thread Zachary Santer
On Mon, Feb 10, 2025 at 11:48 AM Chet Ramey  wrote:
>
> On 2/10/25 11:34 AM, Zachary Santer wrote:
> > On Mon, Feb 10, 2025 at 9:20 AM Phi Debian  wrote:
> >>
> >> If 'best *general*' refer to the shortest line noise does
> >>
> >> $((${i/?([-+])/&10#}))
> >>
> >> Qualify for better than best ? :-)
> >
> > And then this isn't even half as good:
>
> There isn't a reward for brevity or obfuscation; say what you mean:
>
> isnum2()
> {
> case "$1" in
> [-+] | '')  return 1;;  # empty or bare `-' or `+'
> [-+]*[!0-9]*)   return 1;;  # non-digit with leading sign
> [-+]*)  return 0;;  # OK
> *[!0-9]*)   return 1;;  # non-digit
> *)  return 0;;  # OK
> esac
> }
>
> It obviously doesn't handle 0x constants, but could be changed to.

I question whether that's less obfuscated than mine, but it definitely
doesn't remove leading zeros from the variable for easier use
elsewhere in the script.



Re: "printf %d ''" should diagnose the empty string

2025-02-10 Thread Greg Wooledge
On Mon, Feb 10, 2025 at 09:50:01 +0100, Phi Debian wrote:
> On Sat, Feb 8, 2025 at 8:51 AM Robert Elz  wrote:
> > There are a gazillion different ways of getting rid of the octal
> > conversion "problem", one I prefer in cases where I know the value
> > is 2 digits, always, but might be 0n for 0<=n<=9, is  $(( 1$x - 100 ))
> >
>  gazillion++
> You say "I know the value is 2 digits" you forgot to say in base 10 but it
> was kinda implicit in the thread, then a more general one not limited to 2
> decimal digit accepting leading 0 you could simply do $((10#$i))

This issue comes up all the time.

Both of these solutions have limitations on what kind of input they'll
accept.  Robert's only works on two-digit unsigned inputs.  Phi's
works only on unsigned inputs of any length.

hobbit:~$ var=-023
hobbit:~$ echo "$((1$var - 100))"
-118
hobbit:~$ echo "$((10#$var))"
bash: 10#: invalid integer constant (error token is "10#")

The following line noise is the best *general* answer we've found
so far:

$((${num%%[!+-]*}10#${num#[-+]}))

See:







Re: filedescriptor leakage, potential crash

2025-02-10 Thread Chet Ramey

On 2/7/25 9:47 PM, Martin D Kealey wrote:

Funny the bugs one finds when reading the source code to a program... I was
looking at the usage of INPUT_REDIRECT and TRANSLATE_REDIRECT in
execute_null_command() and thought “why compare against 8 values, when by
re-ordering enum r_instruction in command.h, a simple range check would
suffice?” Which led me down a rabbit hole. Why *only* those particular
redirections?


Thanks for the report.

--
``The lyf so short, the craft so long to lerne.'' - Chaucer
 ``Ars longa, vita brevis'' - Hippocrates
Chet Ramey, UTech, CWRUc...@case.eduhttp://tiswww.cwru.edu/~chet/


OpenPGP_signature.asc
Description: OpenPGP digital signature


Re: "printf %d ''" should diagnose the empty string

2025-02-10 Thread Phi Debian
On Mon, Feb 10, 2025 at 5:48 PM Chet Ramey  wrote:

>
> There isn't a reward for brevity or obfuscation; say what you mean:
>
> isnum2()
> {
> case "$1" in
> [-+] | '')  return 1;;  # empty or bare `-' or `+'
> [-+]*[!0-9]*)   return 1;;  # non-digit with leading sign
> [-+]*)  return 0;;  # OK
> *[!0-9]*)   return 1;;  # non-digit
> *)  return 0;;  # OK
> esac
> }
>
> It obviously doesn't handle 0x constants, but could be changed to.
>

I think the point was to convert what would be seen as an octal literal by
$((...)) to something that is 10# with leading zeroes, basically date
output but not limited to.

i.e make $((i)) understand that i is signed leading 0 base 10


$ echo $BASH_VERSION
5.2.21(1)-release
$ shopt -s extglob
$ i=0012  ; echo "$((i)) $((${i/?([-+])/&10#}))"
10 12
$ i=+0012  ; echo "$((i)) $((${i/?([-+])/&10#}))"
10 12
$ i=-0012  ; echo "$((i)) $((${i/?([-+])/&10#}))"
-10 -12

As you see it does exactly what I mean, and cherry on the pie, you can even
fix 'i' for ever with
((i=${i/?([-+])/&10#}))

Now if the problem is to define is_num as a predicate, (not what I was
adressing) you noticed that you omitted 0x, but not only that but all the
base# that brings a far more complex function :-)







> --
> ``The lyf so short, the craft so long to lerne.'' - Chaucer
>  ``Ars longa, vita brevis'' - Hippocrates
> Chet Ramey, UTech, CWRUc...@case.eduhttp://tiswww.cwru.edu/~chet/
>


Re: "printf %d ''" should diagnose the empty string

2025-02-10 Thread Andreas Schwab
On Feb 10 2025, Greg Wooledge wrote:

> No, I've shown that it *is* working in older versions of bash, and I'm
> asking *why*.

Does it?  If it did, it should have printed -23, not -19.

-- 
Andreas Schwab, SUSE Labs, sch...@suse.de
GPG Key fingerprint = 0196 BAD8 1CE9 1970 F4BE  1748 E4D4 88E3 0EEA B9D7
"And now for something completely different."



Re: "printf %d ''" should diagnose the empty string

2025-02-10 Thread Phi Debian
On Mon, Feb 10, 2025 at 7:06 PM Andreas Schwab  wrote:

> On Feb 10 2025, Greg Wooledge wrote:
>
> > No, I've shown that it *is* working in older versions of bash, and I'm
> > asking *why*.
>
> Does it?  If it did, it should have printed -23, not -19.
>
> --
> Andreas Schwab, SUSE Labs, sch...@suse.de
> GPG Key fingerprint = 0196 BAD8 1CE9 1970 F4BE  1748 E4D4 88E3 0EEA B9D7
> "And now for something completely different."
>
>   Yes modern bash git it right not the dyno one :-)

$ echo $BASH_VERSION
5.2.21(1)-release
$ i=-0023  ; echo "$((i)) $((${i/?([-+])/&10#}))"
-19 -23


Re: "printf %d ''" should diagnose the empty string

2025-02-10 Thread Lawrence Velázquez
On Mon, Feb 10, 2025, at 1:05 PM, Andreas Schwab wrote:
> On Feb 10 2025, Greg Wooledge wrote:
>
>> No, I've shown that it *is* working in older versions of bash, and I'm
>> asking *why*.
>
> Does it?  If it did, it should have printed -23, not -19.

Yeah, it doesn't work.  The pattern ?([-+]) matches any character
followed by either a - or + in parentheses, so the substitution
doesn't actually replace anything, and -023 is treated as octal.

bash-3.2$ echo "$(( -023 ))"
-19

-- 
vq



Re: "printf %d ''" should diagnose the empty string

2025-02-10 Thread Phi Debian
On Mon, Feb 10, 2025 at 5:34 PM Zachary Santer  wrote:

>
> int_regex='([+-]?)0*([[:digit:]]+)'
> if [[ ${var} =~ ${int_regex} ]]; then
>   var="${BASH_REMATCH[1]}${BASH_REMATCH[2]}"
> else
>   printf '%s\n' "Argument '${var}' is not a valid integer" >&2
> fi
>

The error message should be 'not a valid signed decimal with leading zeros
constant'


Re: "printf %d ''" should diagnose the empty string

2025-02-10 Thread Chet Ramey

On 2/10/25 2:24 PM, Phi Debian wrote:



On Mon, Feb 10, 2025 at 5:48 PM Chet Ramey > wrote



There isn't a reward for brevity or obfuscation; say what you mean:

isnum2()
{
         case "$1" in
         [-+] | '')      return 1;;      # empty or bare `-' or `+'
         [-+]*[!0-9]*)   return 1;;      # non-digit with leading sign
         [-+]*)          return 0;;      # OK
         *[!0-9]*)       return 1;;      # non-digit
         *)              return 0;;      # OK
         esac
}

It obviously doesn't handle 0x constants, but could be changed to.


Would you  accept this one then, should be general enough, faster too, and 
explicit, really mean what is accepted as num literal


It's not a question of me `accepting' anything. It was simply a plea for
clarity. This will give you bash's idea of a number. If you disagree with
that, you'll have to expand on it.


$ echo $BASH_VERSION
5.2.21(1)-release
$ function isanum
{ (($1)) || (($1==0))  && return 0
   return 1
}  >/dev/null 2>&1


You might want to check for an empty string first, or a missing argument,
depending on your view about whether or not an empty string is equivalent
to 0.


--
``The lyf so short, the craft so long to lerne.'' - Chaucer
 ``Ars longa, vita brevis'' - Hippocrates
Chet Ramey, UTech, CWRUc...@case.eduhttp://tiswww.cwru.edu/~chet/


OpenPGP_signature.asc
Description: OpenPGP digital signature


Re: "printf %d ''" should diagnose the empty string

2025-02-10 Thread Zachary Santer
On Mon, Feb 10, 2025 at 2:43 PM Lawrence Velázquez  wrote:
>
> This accepts many valid expressions, not just literals.
>
> phi() {
> (($1)) || (($1==0))
> }

phi 'i[$( date >&2 )]'

Whoopsie-daisy.
https://mywiki.wooledge.org/BashPitfalls#read_num.3B_echo_.24.28.28num.2B-1.29.29



Re: "printf %d ''" should diagnose the empty string

2025-02-10 Thread Lawrence Velázquez
On Mon, Feb 10, 2025, at 2:24 PM, Phi Debian wrote:
> On Mon, Feb 10, 2025 at 5:48 PM Chet Ramey  wrote
>
>>
>> There isn't a reward for brevity or obfuscation; say what you mean:
>>
>> isnum2()
>> {
>> case "$1" in
>> [-+] | '')  return 1;;  # empty or bare `-' or `+'
>> [-+]*[!0-9]*)   return 1;;  # non-digit with leading sign
>> [-+]*)  return 0;;  # OK
>> *[!0-9]*)   return 1;;  # non-digit
>> *)  return 0;;  # OK
>> esac
>> }
>>
>> It obviously doesn't handle 0x constants, but could be changed to.
>>
>
> Would you  accept this one then, should be general enough, faster too, and
> explicit, really mean what is accepted as num literal
>
> $ echo $BASH_VERSION
> 5.2.21(1)-release
> $ function isanum
> { (($1)) || (($1==0))  && return 0
>   return 1
> }  >/dev/null 2>&1

This accepts many valid expressions, not just literals.

% cat /tmp/isnum.bash
chet() {
case $1 in
[-+] | '') return 1 ;;
[-+]*[!0-9]*) return 1 ;;
[-+]*) return 0 ;;
*[!0-9]*) return 1 ;;
*) return 0 ;;
esac
}

phi() {
(($1)) || (($1==0))
}

chet '1+2'
printf 'chet 1+2 -> %s\n' "$?"

phi '1+2'
printf 'phi 1+2 -> %s\n' "$?"

% bash /tmp/isnum.bash
chet 1+2 -> 1
phi 1+2 -> 0

-- 
vq



Re: "printf %d ''" should diagnose the empty string

2025-02-10 Thread Phi Debian
On Mon, Feb 10, 2025 at 5:48 PM Chet Ramey  wrote

>
> There isn't a reward for brevity or obfuscation; say what you mean:
>
> isnum2()
> {
> case "$1" in
> [-+] | '')  return 1;;  # empty or bare `-' or `+'
> [-+]*[!0-9]*)   return 1;;  # non-digit with leading sign
> [-+]*)  return 0;;  # OK
> *[!0-9]*)   return 1;;  # non-digit
> *)  return 0;;  # OK
> esac
> }
>
> It obviously doesn't handle 0x constants, but could be changed to.
>

Would you  accept this one then, should be general enough, faster too, and
explicit, really mean what is accepted as num literal

$ echo $BASH_VERSION
5.2.21(1)-release
$ function isanum
{ (($1)) || (($1==0))  && return 0
  return 1
}  >/dev/null 2>&1

$ isanum 0 && echo yes || echo no
yes
$ isanum 1 && echo yes || echo no
yes
$ isanum 010 && echo yes || echo no
yes
$ isanum -010 && echo yes || echo no
yes
$ isanum 0x10 && echo yes || echo no
yes
$ isanum +0x10 && echo yes || echo no
yes
$ isanum 64#I_like_this_one && echo yes || echo no
yes
$ isanum '' && echo yes || echo no
no
$ isanum '+' && echo yes || echo no
no
$ zero=0
$ one=1
$ isanum zero && echo yes || echo no
yes
$ isanum one && echo yes || echo no
yes
$ isanum '' && echo yes || echo no
no
$ isanum '+' && echo yes || echo no
$ bad=4#j
$ isanum bad && echo yes || echo no
no

Look good to me ...


Re: "printf %d ''" should diagnose the empty string

2025-02-10 Thread microsuxx
a bit unrelated .. cheap numbers filter ..

gimme_num( ) { declare -n b=BASH_REMATCH\[1] ; local o m=[0-9,.] s=$n i t ;
t="(-?$m+)" ; unset -v o ; for n ; do unset -v i ; while [[ $n =~ $t ]] ;
do n=${n/"$b"} i= o+=$b$s ; done ; [[ -v i ]] && o+=$s ; done ; [[ -v o ]]
&& printf %s "$o" ; }

gimme_num ' ab3.44 cd---.99 ' cd cd 77.7.77

3.44
-.99

77.7.77

On Mon, Feb 10, 2025, 11:14 PM Phi Debian  wrote:

> On Mon, Feb 10, 2025 at 11:10 PM Greg Wooledge  wrote:
>
> >
> > hobbit:~$ phi 029
> > bash: ((: 029: value too great for base (error token is "029")
> > bash: ((: 029: value too great for base (error token is "029")
> >
> > So we come full circle.
> >
>
> Nope phi() is not mine and doesn't remove the error message, see my prev
> post about nuking $(()) syntax error
>
> 029 is not a number
>
> my latest post gives
>
> $ isanum  029  && echo y || echo n
> n
>


Re: "printf %d ''" should diagnose the empty string

2025-02-10 Thread Greg Wooledge
On Mon, Feb 10, 2025 at 23:13:33 +0100, Phi Debian wrote:
> 029 is not a number

Many people would disagree.  Of course, it depends on the needs of the
script that's being written -- that's why the wiki page offers so many
different answers.

In my experience, it's pretty rare for a script to *want* to treat
zero-padded numeric input as octal.



Re: "printf %d ''" should diagnose the empty string

2025-02-10 Thread Phi Debian
I admit the function was mis-named, should be isanumexpr

As @chet noted this attempt was not too bad just need a little $1 check
before pursuing the idea of letting the bash scanner do the job for
complicated valid number (any base)

I come up with this one

function isanum
{ [[ "$1" =~ ^[+-]?[0-9][0-9a-zA-Z#@_]*$ ]] || return 1
  (($1)) || (($1==0))  && return 0
  return 1
}  >/dev/null 2>&1

$ isanum  1+1  && echo y || echo n
n
$ isanum  'i[$( date >&2 )]'  && echo y || echo n
n
$ isanum  64#yo  && echo y || echo n
y
$ isanum  -1  && echo y || echo n
y
$ isanum  yo  && echo y || echo n
n
$ isanum  ''  && echo y || echo n
n
$ isanum  0  && echo y || echo n
y

This time the 1st =~ do accept only number characters at large, the
complexity of deciding which [:letter:]@_ is ledgit for a given base is
differed to $(())

Getting closer to the perfect isanum() :-)

Note the I have a full one based only on regex =~ it is real ugly so that's
why I prefere de let $(()) do the scan, specially if one day it accept 0b
as base (unlikely but who knows. This code would still work.

Again modern bash.

Note too that I use function redirection because I got no idea how to nuke
$(( )) syntax error message


Re: "printf %d ''" should diagnose the empty string

2025-02-10 Thread Phi Debian
On Mon, Feb 10, 2025 at 11:10 PM Greg Wooledge  wrote:

>
> hobbit:~$ phi 029
> bash: ((: 029: value too great for base (error token is "029")
> bash: ((: 029: value too great for base (error token is "029")
>
> So we come full circle.
>

Nope phi() is not mine and doesn't remove the error message, see my prev
post about nuking $(()) syntax error

029 is not a number

my latest post gives

$ isanum  029  && echo y || echo n
n


Re: "printf %d ''" should diagnose the empty string

2025-02-10 Thread Phi Debian
On Mon, Feb 10, 2025 at 11:46 PM microsuxx  wrote:

> a bit unrelated .. cheap numbers filter ..
>
> gimme_num( ) { declare -n b=BASH_REMATCH\[1] ; local o m=[0-9,.] s=$n i t ;
> t="(-?$m+)" ; unset -v o ; for n ; do unset -v i ; while [[ $n =~ $t ]] ;
> do n=${n/"$b"} i= o+=$b$s ; done ; [[ -v i ]] && o+=$s ; done ; [[ -v o ]]
> && printf %s "$o" ; }
>
> gimme_num ' ab3.44 cd---.99 ' cd cd 77.7.77
>
> 3.44
> -.99
>
> 77.7.77
>
>
Rejected
$ gimme_num '0x10'
 0x10xx
$ gimme_num '64#yo'
64xx
$ gimme_num '0x10'
0#yo10#yo#yo

gimme_num should be renamed random_string()