Skip to content

Commit 213dad9

Browse files
committed
Merge branch 'github-pull-8'
Add quote_grep_regexp and quote_grep_regexp_variable functions, as well as the latest changes from for-master branch. Link: #8 Signed-off-by: Alexey Gladkov <legion@kernel.org>
2 parents ff8c043 + c17d8e2 commit 213dad9

32 files changed

+380
-67
lines changed

.github/workflows/lint.yml

Lines changed: 28 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -7,24 +7,6 @@ on:
77
branches: [ master, for-master ]
88

99
jobs:
10-
lint-shell:
11-
runs-on: ubuntu-latest
12-
steps:
13-
- uses: actions/checkout@v4
14-
- name: "install tools"
15-
run: sudo apt-get -y -qq install shellcheck
16-
- name: "shellcheck"
17-
run: make verify
18-
19-
check-docs:
20-
runs-on: ubuntu-latest
21-
steps:
22-
- uses: actions/checkout@v4
23-
- name: "install tools"
24-
run: sudo apt-get -y -qq install scdoc
25-
- name: "make docs"
26-
run: make man
27-
2810
check-commits:
2911
runs-on: ubuntu-latest
3012
steps:
@@ -52,32 +34,42 @@ jobs:
5234
exit 1
5335
fi
5436
55-
check-dash:
37+
lint-shell:
5638
runs-on: ubuntu-latest
57-
needs: [ lint-shell ]
5839
steps:
5940
- uses: actions/checkout@v4
60-
- name: "install tools"
61-
run: sudo apt-get -y -qq install dash bash mksh
62-
- name: "unittests"
63-
run: make check CHECK_SHELL=/bin/dash V=1
41+
- run: sudo apt-get -y -qq install shellcheck
42+
- run: make verify
6443

65-
check-bash:
44+
check-docs:
6645
runs-on: ubuntu-latest
67-
needs: [ lint-shell ]
6846
steps:
6947
- uses: actions/checkout@v4
70-
- name: "install tools"
71-
run: sudo apt-get -y -qq install dash bash mksh
72-
- name: "unittests"
73-
run: make check CHECK_SHELL=/bin/bash V=1
48+
- run: sudo apt-get -y -qq install scdoc
49+
- run: make man
7450

75-
check-mksh:
51+
check-shells:
7652
runs-on: ubuntu-latest
77-
needs: [ lint-shell ]
53+
needs:
54+
- lint-shell
55+
strategy:
56+
fail-fast: false
57+
matrix:
58+
include:
59+
- name: dash
60+
pkgs: dash
61+
62+
- name: bash
63+
pkgs: bash
64+
65+
- name: mksh
66+
pkgs: mksh
67+
68+
- name: lksh
69+
pkgs: mksh
70+
71+
name: "check with ${{ matrix.name }}"
7872
steps:
7973
- uses: actions/checkout@v4
80-
- name: "install tools"
81-
run: sudo apt-get -y -qq install dash bash mksh
82-
- name: "unittests"
83-
run: make check CHECK_SHELL=/bin/mksh V=1
74+
- run: sudo apt-get -y -qq install ${{ matrix.pkgs }}
75+
- run: make check V=1 CHECK_SHELL=/bin/${{ matrix.name }}

Documentation/int64_max.md

Lines changed: 184 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,184 @@
1+
# Maximum Int64 Number
2+
3+
Many shell implementations support 64-bit numbers, but there is a problem with
4+
parsing their maximum values. Some shell implementations handle this
5+
differently.
6+
7+
It is notable that the behavior differs between dash and ash from busybox.
8+
9+
## Agenda
10+
11+
* zsh - zsh (5.9) - UNIX Shell similar to the Korn shell (https://www.zsh.org/)
12+
* dash - dash (0.5.12) - Debian Almquist Shell (https://git.kernel.org/pub/scm/utils/dash/dash.git)
13+
* bash - bash (5.3_p3) - GNU Bourne-Again Shell (https://git.savannah.gnu.org/cgit/bash.git)
14+
* ksh - loksh (7.7) - Linux port of OpenBSD's ksh (https://github.com/dimkr/loksh/)
15+
* lksh - mksh (59c) - MirBSD Korn Shell (https://mbsd.evolvis.org/mksh.htm)
16+
* ash - busybox (1.36.1) - Tiny utilities for small and embedded systems (https://busybox.net/)
17+
18+
## Value Calculation
19+
20+
```sh
21+
$ for sh in zsh dash bash ksh lksh "busybox ash"; do $sh -c 'printf "OUT: %4s: %d\n" "$0" $(( 1 << 62 ))'; done
22+
OUT: zsh: 4611686018427387904
23+
OUT: dash: 4611686018427387904
24+
OUT: bash: 4611686018427387904
25+
OUT: ksh: 4611686018427387904
26+
OUT: lksh: 4611686018427387904
27+
OUT: ash: 4611686018427387904
28+
29+
$ for sh in zsh dash bash ksh lksh "busybox ash"; do $sh -c 'printf "OUT: %4s: %s\n" "$0" $(( 1 << 63 ))'; done
30+
OUT: zsh: -9223372036854775808
31+
OUT: dash: -9223372036854775808
32+
OUT: bash: -9223372036854775808
33+
OUT: ksh: -9223372036854775808
34+
OUT: lksh: -9223372036854775808
35+
OUT: ash: -9223372036854775808
36+
37+
$ for sh in zsh dash bash ksh lksh "busybox ash"; do $sh -c 'printf "OUT: %4s: %x\n" "$0" $(( 1 << 63 ))'; done
38+
zsh:1: number truncated after 18 digits: 9223372036854775808
39+
OUT: zsh: f333333333333334
40+
OUT: dash: 8000000000000000
41+
OUT: bash: 8000000000000000
42+
OUT: ksh: 8000000000000000
43+
OUT: lksh: 8000000000000000
44+
OUT: ash: 8000000000000000
45+
```
46+
47+
```sh
48+
$ for sh in zsh dash bash ksh lksh "busybox ash"; do $sh -c 'printf "OUT: %4s: %s\n" "$0" $(( 0x7fffffffffffffff + 1 ))'; done
49+
OUT: zsh: -9223372036854775808
50+
OUT: dash: -9223372036854775808
51+
OUT: bash: -9223372036854775808
52+
OUT: ksh: -9223372036854775808
53+
OUT: lksh: -9223372036854775808
54+
OUT: ash: -9223372036854775808
55+
56+
$ for sh in zsh dash bash ksh lksh "busybox ash"; do $sh -c 'printf "OUT: %4s: %x\n" "$0" $(( 0x7fffffffffffffff + 1 ))'; done
57+
zsh:1: number truncated after 18 digits: 9223372036854775808
58+
OUT: zsh: f333333333333334
59+
OUT: dash: 8000000000000000
60+
OUT: bash: 8000000000000000
61+
OUT: ksh: 8000000000000000
62+
OUT: lksh: 8000000000000000
63+
OUT: ash: 8000000000000000
64+
65+
$ for sh in zsh dash bash ksh lksh "busybox ash"; do $sh -c 'printf "OUT: %4s: %x\n" "$0" $(( 0x7fffffffffffffff + 2 ))'; done
66+
OUT: zsh: 8000000000000001
67+
OUT: dash: 8000000000000001
68+
OUT: bash: 8000000000000001
69+
OUT: ksh: 8000000000000001
70+
OUT: lksh: 8000000000000001
71+
OUT: ash: 8000000000000001
72+
73+
$ for sh in zsh dash bash ksh lksh "busybox ash"; do $sh -c 'printf "OUT: %4s: %x\n" "$0" $(( 0x7fffffffffffffff + 3 ))'; done
74+
OUT: zsh: 8000000000000002
75+
OUT: dash: 8000000000000002
76+
OUT: bash: 8000000000000002
77+
OUT: ksh: 8000000000000002
78+
OUT: lksh: 8000000000000002
79+
OUT: ash: 8000000000000002
80+
81+
$ for sh in zsh dash bash ksh lksh "busybox ash"; do $sh -c 'printf "OUT: %4s: %x\n" "$0" $(( 0x7fffffffffffffff + 0x7fffffffffffffff + 1 ))'; done
82+
OUT: zsh: ffffffffffffffff
83+
OUT: dash: ffffffffffffffff
84+
OUT: bash: ffffffffffffffff
85+
OUT: ksh: ffffffffffffffff
86+
OUT: lksh: ffffffffffffffff
87+
OUT: ash: ffffffffffffffff
88+
```
89+
90+
There are anomalies in parsing large numbers:
91+
92+
```sh
93+
$ for sh in zsh dash bash ksh lksh "busybox ash"; do $sh -c 'printf "OUT: %4s: %x\n" "$0" $(( 0xffffffffffffffff ))'; done
94+
zsh:1: number truncated after 15 digits: ffffffffffffffff
95+
OUT: zsh: fffffffffffffff
96+
OUT: dash: 7fffffffffffffff
97+
OUT: bash: ffffffffffffffff
98+
OUT: ksh: ffffffffffffffff
99+
OUT: lksh: ffffffffffffffff
100+
OUT: ash: ffffffffffffffff
101+
102+
$ for sh in zsh dash bash ksh lksh "busybox ash"; do $sh -c 'printf "OUT: %4s: %s\n" "$0" $(( 0x8000000000000000 ))'; done
103+
zsh:1: number truncated after 15 digits: 8000000000000000
104+
OUT: zsh: 576460752303423488
105+
OUT: dash: 9223372036854775807
106+
OUT: bash: -9223372036854775808
107+
OUT: ksh: -9223372036854775808
108+
OUT: lksh: -9223372036854775808
109+
OUT: ash: -9223372036854775808
110+
111+
$ for sh in zsh dash bash ksh lksh "busybox ash"; do $sh -c 'printf "OUT: %4s: %d\n" "$0" $(( -9223372036854775808 ))'; done
112+
zsh:1: number truncated after 18 digits: 9223372036854775808
113+
OUT: zsh: -922337203685477580
114+
OUT: dash: -9223372036854775807
115+
OUT: bash: -9223372036854775808
116+
OUT: ksh: -9223372036854775808
117+
OUT: lksh: -9223372036854775808
118+
OUT: ash: -9223372036854775808
119+
```
120+
121+
## Variables
122+
123+
And one more thing. If you put some value in the variable, then in further
124+
calculations, parsing will happen again, which might have an extra effect.
125+
126+
```sh
127+
$ for sh in zsh dash bash ksh lksh "busybox ash"; do $sh -c 'v=$(( 1 << 62 )); printf "OUT: %4s: %x\n" $0 $(( $v ))'; done
128+
OUT: zsh: 4000000000000000
129+
OUT: dash: 4000000000000000
130+
OUT: bash: 4000000000000000
131+
OUT: ksh: 4000000000000000
132+
OUT: lksh: 4000000000000000
133+
OUT: ash: 4000000000000000
134+
135+
$ for sh in zsh dash bash ksh lksh "busybox ash"; do $sh -c 'v=0x7fffffffffffffff; printf "OUT: %4s: %x\n" $0 $(( $v ))'; done
136+
OUT: zsh: 7fffffffffffffff
137+
OUT: dash: 7fffffffffffffff
138+
OUT: bash: 7fffffffffffffff
139+
OUT: ksh: 7fffffffffffffff
140+
OUT: lksh: 7fffffffffffffff
141+
OUT: ash: 7fffffffffffffff
142+
143+
$ for sh in zsh dash bash ksh lksh "busybox ash"; do $sh -c 'v=$(( 1 << 63 )); printf "OUT: %4s: %x\n" $0 $(( $v ))'; done
144+
zsh:1: number truncated after 18 digits: 9223372036854775808
145+
OUT: zsh: f333333333333334
146+
OUT: dash: 8000000000000001
147+
OUT: bash: 8000000000000000
148+
OUT: ksh: 8000000000000000
149+
OUT: lksh: 8000000000000000
150+
OUT: ash: 8000000000000000
151+
152+
$ for sh in zsh dash bash ksh lksh "busybox ash"; do $sh -c 'v=0x8000000000000000; printf "OUT: %4s: %x\n" $0 $(( $v ))'; done
153+
zsh:1: number truncated after 15 digits: 8000000000000000
154+
OUT: zsh: 800000000000000
155+
OUT: dash: 7fffffffffffffff
156+
OUT: bash: 8000000000000000
157+
OUT: ksh: 8000000000000000
158+
OUT: lksh: 8000000000000000
159+
OUT: ash: 8000000000000000
160+
161+
$ for sh in zsh dash bash ksh lksh "busybox ash"; do $sh -c 'v=$(( 0x7fffffffffffffff + 1 )); printf "OUT: %4s: %x\n" $0 $(( $v ))'; done
162+
zsh:1: number truncated after 18 digits: 9223372036854775808
163+
OUT: zsh: f333333333333334
164+
OUT: dash: 8000000000000001
165+
OUT: bash: 8000000000000000
166+
OUT: ksh: 8000000000000000
167+
OUT: lksh: 8000000000000000
168+
OUT: ash: 8000000000000000
169+
170+
for sh in zsh dash bash ksh lksh "busybox ash"; do $sh -c 'v="(0x7fffffffffffffff + 1)"; printf "OUT: %4s: %x\n" $0 $(( $v ))'; done
171+
zsh:1: number truncated after 18 digits: 9223372036854775808
172+
OUT: zsh: f333333333333334
173+
OUT: dash: 8000000000000000
174+
OUT: bash: 8000000000000000
175+
OUT: ksh: 8000000000000000
176+
OUT: lksh: 8000000000000000
177+
OUT: ash: 8000000000000000
178+
```
179+
180+
It seems that if one wants to have the value `1 << 63` in a variable, it is more
181+
correct to keep it as "(0x7fffffffffffffff + 1)" string.
182+
183+
--
184+
Rgrds, legion

Makefile

Lines changed: 26 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,9 @@ capability_TARGETS = shell-regexp
2020
bin_TARGETS = $(filter-out shell-lib,$(wildcard shell-*))
2121
data_TARGETS = COPYING
2222

23-
mddocs_TARGETS = $(wildcard docs/shell-*.md)
24-
docs_TARGETS = docs/libshell.md $(mddocs_TARGETS)
25-
man_TARGETS = $(docs_TARGETS:.md=.3)
23+
mandocs_TARGETS = $(wildcard mans/shell-*.scd)
24+
docs_TARGETS = mans/libshell.scd $(mandocs_TARGETS)
25+
man_TARGETS = $(docs_TARGETS:.scd=.3)
2626

2727
.PHONY: $(SUBDIRS)
2828

@@ -40,7 +40,7 @@ shell-lib: ${bin_TARGETS}
4040
shell-regexp: shell-quote
4141
ln -s -- $^ $@
4242

43-
%.3: %.md
43+
%.3: %.scd
4444
@[ -z "$(SCDOC)" ] || $(SCDOC) < $< > $@
4545

4646
man: ${man_TARGETS}
@@ -81,20 +81,27 @@ $(PROJECT)-$(VERSION).tar.sign: $(PROJECT)-$(VERSION).tar.xz
8181
tar: $(PROJECT)-$(VERSION).tar.xz
8282
release: $(PROJECT)-$(VERSION).tar.sign
8383

84-
check:
85-
@cd tests; \
86-
for sh in $${CHECK_SHELL:-/bin/sh /bin/dash /bin/bash /bin/bash3 /bin/bash4 /bin/mksh /bin/yash /bin/pdksh}; do \
87-
[ -x "$$sh" ] || continue; \
88-
export TEST_SHELL="$$sh"; \
89-
echo "Running tests with $$sh"; \
90-
if ! "$$sh" -efu ./runtests; then \
91-
echo "Tests failed with $$sh"; \
84+
CHECK_SHELL =
85+
CHECK_SHELL += /bin/sh # POSIX Shell
86+
CHECK_SHELL += /bin/dash # Debian Almquist Shell (https://git.kernel.org/pub/scm/utils/dash/dash.git)
87+
CHECK_SHELL += /bin/bash /bin/bash3 /bin/bash4 # GNU Bourne-Again Shell (https://git.savannah.gnu.org/cgit/bash.git)
88+
CHECK_SHELL += /bin/mksh /bin/lksh # MirBSD Korn Shell (https://mbsd.evolvis.org/mksh.htm)
89+
90+
check-tests:
91+
@cd tests; rc=0; \
92+
for TEST_SHELL in $(wildcard $(CHECK_SHELL)); do export TEST_SHELL; \
93+
echo "Running tests with $$TEST_SHELL"; \
94+
if ! $$TEST_SHELL -efu ./runtests; then \
95+
echo >&2 "ERROR: tests failed."; \
9296
echo; \
93-
exit 1; \
97+
rc=1; \
9498
fi; \
95-
done
96-
@sed -n -e 's/^## \([^[:space:]]\+\)$$/\1/p' ${mddocs_TARGETS} |sort -uo "$(CURDIR)/.shell-funcs-documented"
97-
@sed -n -e 's/^\([A-Za-z][A-Za-z0-9_]\+\)().*/\1/p' ${bin_TARGETS} |sort -uo "$(CURDIR)/.shell-funcs"
99+
done; \
100+
exit $$rc;
101+
102+
check-documented:
103+
@sed -n -e 's/^## \([^[:space:]]\+\)$$/\1/p' ${mandocs_TARGETS} |sort -uo "$(CURDIR)/.shell-funcs-documented"
104+
@sed -n -e 's/^\([A-Za-z][A-Za-z0-9_]\+\)().*/\1/p' ${bin_TARGETS} |sort -uo "$(CURDIR)/.shell-funcs"
98105
@comm -13 \
99106
"$(CURDIR)/.shell-funcs-documented" \
100107
"$(CURDIR)/.shell-funcs" \
@@ -103,18 +110,19 @@ check:
103110
if [ "$$(wc -l < "$(CURDIR)/.shell-funcs-not-documented")" != "0" ]; then \
104111
echo >&2 "ERROR: some functions are not documented:"; \
105112
cat "$(CURDIR)/.shell-funcs-not-documented"; \
106-
echo; \
107113
rc=1; \
108114
else \
109115
echo "All functions are documented."; \
110-
echo; \
111116
fi; \
117+
echo; \
112118
rm -f -- \
113119
"$(CURDIR)/.shell-funcs-documented" \
114120
"$(CURDIR)/.shell-funcs-not-documented" \
115121
"$(CURDIR)/.shell-funcs"; \
116122
exit $$rc;
117123

124+
check: check-tests check-documented
125+
118126
NULL =
119127
SPACE = $(NULL) $(NULL)
120128
COMMA = ,

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ Install dependencies:
1414

1515
## Documentation
1616

17-
See [docs](docs/libshell.md)
17+
See [docs](mans/libshell.scd)
1818

1919
## LICENSE
2020

File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.

0 commit comments

Comments
 (0)