Reset exit status on assignment.

* gash/eval.scm (eval-word): Add 'on-command-substitution' keyword.
(eval-sh): On '<sh-set!>' reset the exit status unless a command
substitution has occurred.
* tests/assignments.org: Add tests.
This commit is contained in:
Timothy Sample 2019-10-12 09:34:32 -04:00
parent 9d98405821
commit 7fee72f5c7
2 changed files with 61 additions and 6 deletions

View File

@ -33,8 +33,10 @@
;;;
;;; Code:
(define* (eval-word word #:key (output 'fields) (rhs-tildes? #f))
(define* (eval-word word #:key (output 'fields) (rhs-tildes? #f)
(on-command-substitution noop))
(parameterize ((eval-cmd-sub (lambda (exps)
(on-command-substitution)
(sh:substitute-command
(lambda ()
(for-each eval-sh exps))))))
@ -124,11 +126,15 @@
(('<sh-pipeline> cmd*s ..1)
(apply sh:pipeline (map exp->thunk cmd*s)))
(('<sh-set!> (names words) ..1)
(for-each (lambda (name word)
(setvar! name (eval-word word
#:output 'string
#:rhs-tildes? #t)))
names words))
(let* ((command-substitution? #f)
(thunk (lambda () (set! command-substitution? #t))))
(for-each (lambda (name word)
(setvar! name (eval-word word
#:output 'string
#:rhs-tildes? #t
#:on-command-substitution thunk)))
names words)
(unless command-substitution? (set-status! 0))))
(('<sh-subshell> . sub-exps)
(sh:subshell (exps->thunk sub-exps)))
(('<sh-while> test-exp sub-exps ..1)

View File

@ -106,3 +106,52 @@
#+begin_example
bin:gash
#+end_example
* Assignments reset exit status
:script:
#+begin_src sh
set +e
false
x=foobar
#+end_src
* Assigning exit status works
:script:
#+begin_src sh
set +e
false
x=$?
echo $x
#+end_src
:stdout:
#+begin_example
1
#+end_example
* Assignments use command substitutions for exit status
:script:
#+begin_src sh
set +e
x=$(false)
echo $?
x=$(true)
echo $?
#+end_src
:stdout:
#+begin_example
1
0
#+end_example
* Assignments update exit status on the fly
:script:
#+begin_src sh
set +e
false
x=$? y=$(true) z=$?
echo $x $z
#+end_src
:stdout:
#+begin_example
1 0
#+end_example