...
 
Commits (7)
  • janneke's avatar
    Respect '--parse' flag for files and non-TTY inputs. · 23a237b2
    janneke authored
    * gash/gash.scm (main): Include 'parse?' in all calls to 'run-repl'.
    23a237b2
  • janneke's avatar
    Support redirects with empty commands. · 17aa4267
    janneke authored
    Co-authored-by: Timothy Sample <samplet@ngyro.com>.
    
    * gash/eval.scm (exp->thunk): Return 'noop' if 'exp' is '#f'.
    * tests/50-redirect-clobber.sh: New file.
    * tests/50-redirect-clobber.stdout: New file.
    * Makefile.am (FULL_TESTS): Add tests/50-redirect-clobber.sh.
    17aa4267
  • janneke's avatar
    Delete merge leftover. · 81ceb3ae
    janneke authored
    * check.sh: Delete file.
    81ceb3ae
  • janneke's avatar
    tests: Add 43-trap-subshell.sh. · d272d74e
    janneke authored
    * tests/43-trap-subshell.sh: New file.
    * tests/43-trap-subshell.stdout: New file.
    * Makefile.am (FULL_TESTS): Add tests/43-trap-subshell.sh.
    d272d74e
  • janneke's avatar
    tests: Add 100-test-false.sh. · a7e130f6
    janneke authored
    * tests/100-test-false.sh: New file.
    * Makefile.am (FULL_TESTS): Add it.
    a7e130f6
  • janneke's avatar
    Allow setting the status with a Boolean. · a6eee399
    janneke authored
    * gash/environment.scm (set-status!): Allow numerical or boolean input.
    a6eee399
  • janneke's avatar
    echo: Implement escapes. · 1a05e21d
    janneke authored
    Co-authored-by: Timothy Sample <samplet@ngyro.com>.
    
    * gash/built-ins/echo.scm (escape->control): New function.
    (echo): Support '-e' and '-E' options even when clumped.
    * Makefile.am (XFAIL_TESTS): Remove tests/20-pipe-sed.sh.
    1a05e21d
......@@ -205,6 +205,7 @@ FULL_TESTS = \
tests/42-sh-export.sh \
tests/42-export-new.sh \
tests/42-sh-export-new.sh \
tests/43-trap-subshell.sh \
tests/50-iohere.sh \
tests/50-iohere-builtin.sh \
tests/50-redirect.sh \
......@@ -214,6 +215,7 @@ FULL_TESTS = \
tests/50-redirect-sed.sh \
tests/50-redirect-space.sh \
tests/50-redirect-in-out.sh \
tests/50-redirect-clobber.sh \
tests/60-function.sh \
tests/60-function-at.sh \
tests/60-subst.sh \
......@@ -228,13 +230,13 @@ FULL_TESTS = \
tests/100-cd.sh \
tests/100-cd-foo.sh \
tests/100-test.sh \
tests/100-test-false.sh \
tests/100-test-file.sh \
tests/100-bracket-file.sh
TESTS = $(UNIT_TESTS) $(FULL_TESTS)
XFAIL_TESTS = \
tests/20-pipe-sed.sh \
tests/70-hash.sh \
tests/70-hash-hash.sh \
tests/70-percent.sh \
......
if [ -n "$V" ]; then
set -x
fi
DIFF=diff
SHELL=${SHELL-scripts/gash}
tests='
00-exit
00-exit-0
00-exit-1
00-exit-2
00-exit-error
00-exit-var
01-script-newline
01-script-semi
01-script-backslash
01-script-backslash-space
01-script-backslash-twice
01-script-arg-0
01-script-arg-length
01-script-arg-list
01-script-shift
03-echo
03-echo-doublequotes
03-echo-nesting
03-echo-escaped-doublequotes
03-echo-quoted-doublequotes
03-echo-brace
04-echo-var
04-echo-equal
04-echo-word-at
04-echo-word-at-word
05-assignment
05-assignment-echo
05-assignment-empty
05-assignment-singlequote
05-assignment-double-quote
05-assignment-variable-word
05-assignment-word-variable
05-assignment-doublequoted-doublequotes
06-compound-word
06-command-compound-word
07-variable-or
07-variable-not-or
07-variable-or-slash
07-variable-or-variable
07-variable-or-doublequote
07-variable-or-empty
08-variable-and
08-variable-not-and
10-if
10-if-false
10-if-word-variable
10-if-multiple
10-if-else
10-else-multiple
10-if-elif
10-if-test
10-if-test-false
10-if-bracket
10-if-bracket-false
10-if-redirect
11-for
11-for-split-sequence
11-for-done-subshell
20-semi
20-or
20-and
20-pipe-exit-0
20-pipe-exit-1
20-pipe-sed
20-exec
30-substitution
30-substitution-word
30-substitution-backtick
30-substitution-assignment
30-for-substitution
30-substitution-assignment
30-substitution-assignment-at
30-substitution-redirect
40-eval
40-eval-echo-variable
40-assignment-eval-echo
41-dot
42-sh
42-sh-export
50-iohere
50-iohere-builtin
50-redirect
50-redirect-space
50-redirect-in
50-redirect-append
50-redirect-pipe
50-redirect-merge
50-redirect-sed
50-redirect-in-out
60-function
60-function-at
60-subst
70-hash
70-hash-hash
70-percent
70-percent-percent
70-percent-space
70-slash
70-slash-string
70-slash-string-slash
100-cd
100-cd-foo
100-test
100-test-file
100-bracket-file
100-basename-root
100-dirname-root
100-basename-autoconf
100-dirname-autoconf
100-sed
100-sed-once
100-sed-global
100-sed-case
100-sed-group
100-sed-group-extended
100-sed-twice
100-sed-undo
100-sed-file
100-sed-fooRbar
100-sed-pattern-address
100-sed-quit
100-sed-autoconf-basename
100-tar
100-tar-Z
100-tar-Z-old
100-tar-Z-pipe
100-tar-ro
100-tr
'
broken="
"
if [ "$(basename $SHELL)" = bash ]; then
broken="
00-sed
"
fi
expect=$(echo $broken | wc -w)
pass=0
fail=0
total=0
for t in $tests; do
if [ "$PARSE" ]; then
scripts/gash -p "tests/$t.sh"
else
sh test.sh "tests/$t" &> tests/"$t".log
fi
r=$?
total=$((total+1))
if [ $r = 0 ]; then
echo $t: [OK]
pass=$((pass+1))
else
echo $t: [FAIL]
fail=$((fail+1))
fi
done
[ $expect != 0 ] && echo "expect: $expect"
[ $fail != 0 ] && echo "failed: $fail"
[ $fail -lt $expect ] && echo "solved: $(($expect - $fail))"
echo "passed: $pass"
echo "total: $total"
if [ $fail != 0 -a $fail -gt $expect ]; then
echo FAILED: $fail/$total
exit 1
elif [ $fail != 0 ]; then
echo PASS: $pass/$total
else
echo PASS: $total
fi
;;; Gash -- Guile As SHell
;;; Copyright © 2018 Timothy Sample <samplet@ngyro.com>
;;; Copyright © 2018, 2019 Timothy Sample <samplet@ngyro.com>
;;; Copyright © 2019 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
;;;
;;; This file is part of Gash.
;;;
......@@ -17,6 +18,9 @@
;;; along with Gash. If not, see <http://www.gnu.org/licenses/>.
(define-module (gash built-ins echo)
#:use-module (ice-9 match)
#:use-module (srfi srfi-1)
#:use-module (srfi srfi-26)
#:export (echo))
;;; Commentary:
......@@ -25,10 +29,50 @@
;;;
;;; Code:
(define (escape->control string)
(list->string
(let loop ((lst (string->list string)))
(if (null? lst) '()
(let ((char (car lst)))
(if (or (not (eq? char #\\))
(null? (cdr lst))) (cons char (loop (cdr lst)))
(let* ((lst (cdr lst))
(char (car lst)))
(case char
((#\\) (cons #\\ (loop (cdr lst))))
((#\a) (cons #\alarm (loop (cdr lst))))
((#\b) (cons #\backspace (loop (cdr lst))))
((#\c) '())
((#\e) (cons #\escape (loop (cdr lst))))
((#\f) (cons #\page (loop (cdr lst))))
((#\n) (cons #\newline (loop (cdr lst))))
((#\r) (cons #\return (loop (cdr lst))))
((#\t) (cons #\tab (loop (cdr lst))))
((#\v) (cons #\vtab (loop (cdr lst))))
((#\0) (error "echo: TODO: \\0NNN"))
((#\x) (error "echo: TODO: \\xNNN"))))))))))
(define (option? str)
(and (> (string-length str) 1)
(char=? (string-ref str 0) #\-)
(string-every (cut member <> '(#\E #\e #\n)) (substring str 1))))
(define (echo . args)
(let* ((n? (and (pair? args) (string=? (car args) "-n")))
(args (if n? (cdr args) args)))
(display (string-join args " "))
(unless n?
(let* ((options (append-map (compose cdr string->list)
(take-while option? args)))
(args (drop-while option? args))
(newline? (not (member #\n options)))
(escapes? (fold (lambda (x acc)
(match x
(#\e #t)
(#\E #f)
(_ acc)))
#f
options))
(string (string-join args)))
(display (if escapes?
(escape->control string)
string))
(when newline?
(newline))
0))
;;; Gash -- Guile As SHell
;;; Copyright © 2018, 2019 Timothy Sample <samplet@ngyro.com>
;;; Copyright © 2019 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
;;;
;;; This file is part of Gash.
;;;
......@@ -71,7 +72,12 @@
(define (set-status! n)
"Set the current status."
(set! *status* n))
(match n
((? number?)
(set! *status* n))
(#t (set-status! 0))
(#f (set-status! 1))
(_ (throw 'invalid-status n))))
(define *root-pid* (getpid))
......
;;; Gash -- Guile As SHell
;;; Copyright © 2018 Timothy Sample <samplet@ngyro.com>
;;; Copyright © 2018, 2019 Timothy Sample <samplet@ngyro.com>
;;; Copyright © 2018, 2019 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
;;;
;;; This file is part of Gash.
;;;
......@@ -52,7 +53,10 @@
(_ `(,op ,fd ,field)))))
(define (exp->thunk exp)
(lambda () (eval-sh exp)))
;; XXX: See comment in `exps->thunk'.
(if exp
(lambda () (eval-sh exp))
noop))
(define (exps->thunk exps)
;; XXX: It probably makes more sense to exclude '#f' expressions at
......
......@@ -144,7 +144,7 @@ copyleft.
(set-program-arguments files)
(call-with-input-file script
(lambda (port)
(exit (run-repl port))))))
(exit (run-repl port parse?))))))
((isatty? (current-input-port))
(let* ((HOME (string-append (getenv "HOME") "/.gash_history"))
(thunk (lambda ()
......@@ -166,7 +166,7 @@ copyleft.
(with-readline-completion-function completion thunk)
(write-history HOME)
(newline)))
(else (exit (run-repl))))))))
(else (exit (run-repl (current-input-port) parse?))))))))
(thunk)))
(define prompt
......
set +e
false
if test $? -ne 0; then
exit 0;
fi
exit 1
trap "rm /tmp/bar$$" 0
echo foo > /tmp/bar$$
cat /tmp/bar$$
(exit 0)
cat /tmp/bar$$
echo foo > /tmp/bar$$
cat /tmp/bar$$
> /tmp/bar$$
cat /tmp/bar$$