From 150c6eac53761748ae42a58e3767811de9b360d1 Mon Sep 17 00:00:00 2001 From: Timothy Sample Date: Fri, 14 Jun 2019 20:58:23 -0400 Subject: [PATCH] Handle 'return' errors. * gash/built-ins/utils.scm (string->exit-status): New procedure. * gash/built-ins/return.scm (main): Use it to simplify argument checking; check for too many arguments; and print messages on errors. * tests/functions.org (Too many arguments to return): New test. --- gash/built-ins/return.scm | 28 ++++++++++++++-------------- gash/built-ins/utils.scm | 11 ++++++++++- tests/functions.org | 11 +++++++++++ 3 files changed, 35 insertions(+), 15 deletions(-) diff --git a/gash/built-ins/return.scm b/gash/built-ins/return.scm index e463ac4..87b55b6 100644 --- a/gash/built-ins/return.scm +++ b/gash/built-ins/return.scm @@ -17,8 +17,10 @@ ;;; along with Gash. If not, see . (define-module (gash built-ins return) + #:use-module (gash built-ins utils) #:use-module (gash compat) - #:use-module (gash environment)) + #:use-module (gash environment) + #:use-module (ice-9 match)) ;;; Commentary: ;;; @@ -27,16 +29,14 @@ ;;; Code: (define (main . args) - (let* ((arg (or (and (pair? args) - (car (last-pair args))) - (number->string (get-status)) - "0")) - (number (string->number arg)) - (status (or (and (exact-integer? number) - (>= number 0) - (<= number 256) - number) - ;; If the above is not true, the exit status is - ;; undefined. - EXIT_FAILURE))) - (sh:return status))) + (match args + (() (main (number->string (get-status)))) + ((arg) + (match (string->exit-status arg) + (#f (format (current-error-port) + "gash: return: argument must be a number from 0 to 255~%") + EXIT_FAILURE) + (n (sh:return n)))) + (_ (format (current-error-port) + "gash: return: too many arguments~%") + EXIT_FAILURE))) diff --git a/gash/built-ins/utils.scm b/gash/built-ins/utils.scm index 67dc466..cf6dfc0 100644 --- a/gash/built-ins/utils.scm +++ b/gash/built-ins/utils.scm @@ -21,7 +21,8 @@ #:export (get-evaluator built-in? split-assignment - string->positive-integer)) + string->positive-integer + string->exit-status)) ;;; Commentary: ;;; @@ -65,3 +66,11 @@ (and=> (and (string-every char-set:ascii-digit s) (string->number s)) (lambda (n) (and (exact-integer? n) (> n 0) n)))) + +(define (string->exit-status s) + "Return the exit status represented by the string @var{s}. If +@var{s} does not represent an exit status (a decimal integer from 0 to +255) return @code{#f}." + (and=> (and (string-every char-set:ascii-digit s) (string->number s)) + (lambda (n) + (and (exact-integer? n) (>= n 0) (<= n 255) n)))) diff --git a/tests/functions.org b/tests/functions.org index 4f0b0d1..af9ef71 100644 --- a/tests/functions.org +++ b/tests/functions.org @@ -72,3 +72,14 @@ cat $TEST_TMP/foo.tmp rm $TEST_TMP/foo.tmp #+end_src + +* Too many arguments to return +:script: +#+begin_src sh + foo () { + return 1 2 3 + } + + foo +#+end_src +:status: 1