Add -e, -x options. Use -x for running tests.

This commit is contained in:
Jan Nieuwenhuizen 2018-07-04 06:58:01 +02:00
parent 503be95f97
commit 795b059373
6 changed files with 24 additions and 13 deletions

View File

@ -54,11 +54,13 @@
(display "\ (display "\
gash [options] gash [options]
-c, --command=STRING Evaluate STRING and exit -c, --command=STRING Evaluate STRING and exit
-e, --errexit Exit upon error
-d, --debug Enable PEG tracing -d, --debug Enable PEG tracing
-h, --help Display this help -h, --help Display this help
-p, --parse Parse the shell script and print the parse tree -p, --parse Parse the shell script and print the parse tree
--prefer-builtins Use builtins, even if command is available in PATH --prefer-builtins Use builtins, even if command is available in PATH
-v, --version Display the version -v, --version Display the version
-x, --xtrace Print simple command trace
")) "))
(define (display-version) (define (display-version)
@ -72,7 +74,7 @@ the GNU Public License, see COPYING for the copyleft.
")) "))
(define global-variables (list '("SHELLOPTS" . ""))) (define global-variables (list (cons "SHELLOPTS" "")))
(define (main args) (define (main args)
(map (lambda (key-value) (map (lambda (key-value)
@ -85,11 +87,13 @@ the GNU Public License, see COPYING for the copyleft.
(lambda () (lambda ()
(job-control-init) (job-control-init)
(let* ((option-spec '((command (single-char #\c) (value #t)) (let* ((option-spec '((command (single-char #\c) (value #t))
(debug (single-char #\d) (value #f)) (debug (single-char #\d))
(help (single-char #\h) (value #f)) (errexit (single-char #\e))
(parse (single-char #\p) (value #f)) (help (single-char #\h))
(parse (single-char #\p))
(prefer-builtins) (prefer-builtins)
(version (single-char #\v) (value #f)))) (version (single-char #\v))
(xtrace (single-char #\x))))
(options (getopt-long args option-spec #:stop-at-first-non-option #t )) (options (getopt-long args option-spec #:stop-at-first-non-option #t ))
(command? (option-ref options 'command #f)) (command? (option-ref options 'command #f))
(opt? (lambda (name) (lambda (o) (and (eq? (car o) name) (cdr o))))) (opt? (lambda (name) (lambda (o) (and (eq? (car o) name) (cdr o)))))
@ -108,6 +112,8 @@ the GNU Public License, see COPYING for the copyleft.
(#t (#t
(sh-exec ast)))))) (sh-exec ast))))))
(set! %prefer-builtins? (option-ref options 'prefer-builtins #f)) (set! %prefer-builtins? (option-ref options 'prefer-builtins #f))
(set-shell-opt! "errexit" (option-ref options 'errexit #f))
(set-shell-opt! "xtrace" (option-ref options 'xtrace #f))
(if (option-ref options 'debug #f) (if (option-ref options 'debug #f)
(set! %debug-level debug)) (set! %debug-level debug))
(cond (cond
@ -225,10 +231,10 @@ the GNU Public License, see COPYING for the copyleft.
(format #t "~a=~a\n" (car o) (cdr o))) (format #t "~a=~a\n" (car o) (cdr o)))
(match args (match args
(() (for-each display-var global-variables)) (() (for-each display-var global-variables))
(("-e") (set-shell-opt "errexit" #t)) (("-e") (set-shell-opt! "errexit" #t))
(("+e") (set-shell-opt "errexit" #f)) (("+e") (set-shell-opt! "errexit" #f))
(("-x") (set-shell-opt "xtrace" #t)) (("-x") (set-shell-opt! "xtrace" #t))
(("+x") (set-shell-opt "xtrace" #f)))) (("+x") (set-shell-opt! "xtrace" #f))))
(define (exit-command . args) (define (exit-command . args)
(match args (match args
@ -238,7 +244,7 @@ the GNU Public License, see COPYING for the copyleft.
((args ...) ((args ...)
(format (current-error-port) "exit: too many arguments: ~a\n" (string-join args))))) (format (current-error-port) "exit: too many arguments: ~a\n" (string-join args)))))
(define (set-shell-opt name set?) (define (set-shell-opt! name set?)
(let* ((shell-opts (assoc-ref global-variables "SHELLOPTS")) (let* ((shell-opts (assoc-ref global-variables "SHELLOPTS"))
(options (if (string-null? shell-opts) '() (options (if (string-null? shell-opts) '()
(string-split shell-opts #\:))) (string-split shell-opts #\:)))
@ -364,8 +370,8 @@ the GNU Public License, see COPYING for the copyleft.
(else (list 0)))) ; some commands return a string? (else (list 0)))) ; some commands return a string?
job)) job))
(stati (map status:exit-val stati)) (stati (map status:exit-val stati))
(status (or (find (negate zero?) stati) 0)) (status (if (shell-opt? "pipefail") (or (find (negate zero?) (reverse stati)) 0)
;; mimick BASH for now (last stati)))
(pipestatus (string-append (pipestatus (string-append
"(" "("
(string-join (string-join

View File

@ -5,7 +5,7 @@ SHELL=${SHELL-bin/gash}
for f in test/*.sh; do for f in test/*.sh; do
echo -n "$f: " echo -n "$f: "
b=test/$(basename $f .sh) b=test/$(basename $f .sh)
$SHELL $f $SHELL -e $f
r=$? r=$?
if [ -f $b.exit ]; then if [ -f $b.exit ]; then
e=$(cat $b.exit) e=$(cat $b.exit)

1
test/20-pipe-exit-0.sh Normal file
View File

@ -0,0 +1 @@
false | true

1
test/21-pipe-exit-1.exit Normal file
View File

@ -0,0 +1 @@
1

1
test/21-pipe-exit-1.sh Normal file
View File

@ -0,0 +1 @@
true | false

View File

@ -0,0 +1,2 @@
# gash makes this into a pipeline, then uses `true''s exit status
false ; true