emersion / mrsh

A minimal POSIX shell
MIT License
494 stars 35 forks source link

Add support for hex literals in arithmetic expressions #179

Open alexdowad opened 3 years ago

alexdowad commented 3 years ago

Dear mrsh people,

Love your code! 😍💻 I'm a person who needs to learn shell scripting for work. Tried reading the POSIX spec, found some parts difficult to understand, decided to look at an implementation for more clarity, read some of BusyBox ash, later found mrsh and am having a much better time with it.

Here's a small contribution back. Tried to follow your coding style; please let me know if I missed anything.

alexdowad commented 3 years ago

Hmm. Test failure on Arch Linux only, on a test script which doesn't appear related to this change... the build log output also doesn't seem to show what is wrong about the output...

alexdowad commented 3 years ago

OK, well, I see what is causing the failure now.

The reference shell on Arch Linux is doing tilde expansion different from the reference shells on other platforms. It's from this part of test/word.sh:

a=~/foo:~/bar:~/baz
echo $a

On the other platforms, the reference shells expand that to /home/build/foo:/home/build/bar:/home/build/baz. But on Arch Linux, the reference shell only expands it to /home/build/foo:~/bar:~/baz.

alexdowad commented 3 years ago

@YerinAlexey Thanks for the review.

By the way, when I started modifying this code, I found a comment saying that 0b prefixes should also be supported. But I have found that dash doesn't accept 0b numeric literals, so if mrsh does so, then dash can't be used as a 'reference shell'.

Maybe that comment should just be deleted? Or is dash violating POSIX by not accepting 0b literals?

YerinAlexey commented 3 years ago

Or is dash violating POSIX by not accepting 0b literals?

No, I don't think so.

Spec doesn't mention binary constants (that's where b in 0b is for):

Next, the shell shall treat this as an arithmetic expression and substitute the value of the expression. The arithmetic expression shall be processed according to the rules given in Arithmetic Precision and Operations , with the following exceptions:

  • Only signed long integer arithmetic is required.
  • Only the decimal-constant, octal-constant, and hexadecimal-constant constants specified in the ISO C standard, Section 6.4.4.1 are required to be recognized as constants.
  • The sizeof() operator and the prefix and postfix "++" and "--" operators are not required.

Ref: https://pubs.opengroup.org/onlinepubs/009604499/utilities/xcu_chap02.html#tag_02_06_04