2018-07-12 02:51:54 +01:00
|
|
|
|
;;; The Geesh Shell Interpreter
|
|
|
|
|
;;; Copyright 2018 Timothy Sample <samplet@ngyro.com>
|
|
|
|
|
;;;
|
|
|
|
|
;;; This file is part of Geesh.
|
|
|
|
|
;;;
|
|
|
|
|
;;; Geesh is free software: you can redistribute it and/or modify
|
|
|
|
|
;;; it under the terms of the GNU General Public License as published by
|
|
|
|
|
;;; the Free Software Foundation, either version 3 of the License, or
|
|
|
|
|
;;; (at your option) any later version.
|
|
|
|
|
;;;
|
|
|
|
|
;;; Geesh is distributed in the hope that it will be useful,
|
|
|
|
|
;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
|
;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
|
;;; GNU General Public License for more details.
|
|
|
|
|
;;;
|
|
|
|
|
;;; You should have received a copy of the GNU General Public License
|
|
|
|
|
;;; along with Geesh. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
|
|
|
|
|
|
(define-module (geesh environment)
|
Globalize the environment module
Instead of passing around references to the environment, just treat it
as a global. The old way was just the remains of an idea to make the
environment immutable and keep the interpreter from manipulating any
global state. By making everything global and mutable, we will have
less impedance mismatch with POSIX going forward.
The following changelog is only a sketch, since nearly every function
has changed.
* geesh/environment.scm: Replace this module with one that treats the
environment as a global resource.
* tests/environment.scm: Delete file.
* Makefile.am: Remove it from the list of tests.
* geesh/shell.scm, geesh/eval.scm, geesh/repl.scm, geesh/word.scm,
geesh/built-ins/break.scm, geesh/built-ins/continue.scm,
geesh/built-ins/echo.scm, geesh/built-ins/export.scm,
geesh/built-ins/false.scm, geesh/built-ins/read.scm,
geesh/built-ins/readonly.scm, geesh/built-ins/set.scm,
geesh/built-ins/true.scm, geesh/built-ins/unset.scm: Remove 'env'
parameters and use the new environment module.
* .dir-locals.el: Update indentation of functions that no longer take
an 'env' parameter and add with-arguments, with-environ, and
with-variables from the new environment module.
* tests/shell.scm, tests/word.scm: Update environment creation and
manipulation in tests.
2018-11-25 05:47:09 +00:00
|
|
|
|
#:use-module (ice-9 hash-table)
|
2018-07-12 02:51:54 +01:00
|
|
|
|
#:use-module (ice-9 match)
|
2018-07-18 04:29:37 +01:00
|
|
|
|
#:use-module (srfi srfi-1)
|
|
|
|
|
#:use-module (srfi srfi-26)
|
Globalize the environment module
Instead of passing around references to the environment, just treat it
as a global. The old way was just the remains of an idea to make the
environment immutable and keep the interpreter from manipulating any
global state. By making everything global and mutable, we will have
less impedance mismatch with POSIX going forward.
The following changelog is only a sketch, since nearly every function
has changed.
* geesh/environment.scm: Replace this module with one that treats the
environment as a global resource.
* tests/environment.scm: Delete file.
* Makefile.am: Remove it from the list of tests.
* geesh/shell.scm, geesh/eval.scm, geesh/repl.scm, geesh/word.scm,
geesh/built-ins/break.scm, geesh/built-ins/continue.scm,
geesh/built-ins/echo.scm, geesh/built-ins/export.scm,
geesh/built-ins/false.scm, geesh/built-ins/read.scm,
geesh/built-ins/readonly.scm, geesh/built-ins/set.scm,
geesh/built-ins/true.scm, geesh/built-ins/unset.scm: Remove 'env'
parameters and use the new environment module.
* .dir-locals.el: Update indentation of functions that no longer take
an 'env' parameter and add with-arguments, with-environ, and
with-variables from the new environment module.
* tests/shell.scm, tests/word.scm: Update environment creation and
manipulation in tests.
2018-11-25 05:47:09 +00:00
|
|
|
|
#:export (get-status
|
|
|
|
|
set-status!
|
2018-12-05 18:58:34 +00:00
|
|
|
|
get-root-pid
|
Globalize the environment module
Instead of passing around references to the environment, just treat it
as a global. The old way was just the remains of an idea to make the
environment immutable and keep the interpreter from manipulating any
global state. By making everything global and mutable, we will have
less impedance mismatch with POSIX going forward.
The following changelog is only a sketch, since nearly every function
has changed.
* geesh/environment.scm: Replace this module with one that treats the
environment as a global resource.
* tests/environment.scm: Delete file.
* Makefile.am: Remove it from the list of tests.
* geesh/shell.scm, geesh/eval.scm, geesh/repl.scm, geesh/word.scm,
geesh/built-ins/break.scm, geesh/built-ins/continue.scm,
geesh/built-ins/echo.scm, geesh/built-ins/export.scm,
geesh/built-ins/false.scm, geesh/built-ins/read.scm,
geesh/built-ins/readonly.scm, geesh/built-ins/set.scm,
geesh/built-ins/true.scm, geesh/built-ins/unset.scm: Remove 'env'
parameters and use the new environment module.
* .dir-locals.el: Update indentation of functions that no longer take
an 'env' parameter and add with-arguments, with-environ, and
with-variables from the new environment module.
* tests/shell.scm, tests/word.scm: Update environment creation and
manipulation in tests.
2018-11-25 05:47:09 +00:00
|
|
|
|
getvar
|
|
|
|
|
setvar!
|
|
|
|
|
unsetvar!
|
|
|
|
|
exported?
|
|
|
|
|
set-exported!
|
|
|
|
|
read-only?
|
|
|
|
|
set-read-only!
|
|
|
|
|
with-variables
|
|
|
|
|
get-environ
|
|
|
|
|
with-environ
|
|
|
|
|
getfun
|
|
|
|
|
defun!
|
|
|
|
|
unsetfun!
|
|
|
|
|
with-arguments
|
2018-11-26 01:57:08 +00:00
|
|
|
|
getopt
|
|
|
|
|
setopt!
|
|
|
|
|
*option-names*
|
|
|
|
|
*option-letters*
|
Globalize the environment module
Instead of passing around references to the environment, just treat it
as a global. The old way was just the remains of an idea to make the
environment immutable and keep the interpreter from manipulating any
global state. By making everything global and mutable, we will have
less impedance mismatch with POSIX going forward.
The following changelog is only a sketch, since nearly every function
has changed.
* geesh/environment.scm: Replace this module with one that treats the
environment as a global resource.
* tests/environment.scm: Delete file.
* Makefile.am: Remove it from the list of tests.
* geesh/shell.scm, geesh/eval.scm, geesh/repl.scm, geesh/word.scm,
geesh/built-ins/break.scm, geesh/built-ins/continue.scm,
geesh/built-ins/echo.scm, geesh/built-ins/export.scm,
geesh/built-ins/false.scm, geesh/built-ins/read.scm,
geesh/built-ins/readonly.scm, geesh/built-ins/set.scm,
geesh/built-ins/true.scm, geesh/built-ins/unset.scm: Remove 'env'
parameters and use the new environment module.
* .dir-locals.el: Update indentation of functions that no longer take
an 'env' parameter and add with-arguments, with-environ, and
with-variables from the new environment module.
* tests/shell.scm, tests/word.scm: Update environment creation and
manipulation in tests.
2018-11-25 05:47:09 +00:00
|
|
|
|
call-with-continue
|
2018-12-04 20:24:30 +00:00
|
|
|
|
sh:continue
|
Globalize the environment module
Instead of passing around references to the environment, just treat it
as a global. The old way was just the remains of an idea to make the
environment immutable and keep the interpreter from manipulating any
global state. By making everything global and mutable, we will have
less impedance mismatch with POSIX going forward.
The following changelog is only a sketch, since nearly every function
has changed.
* geesh/environment.scm: Replace this module with one that treats the
environment as a global resource.
* tests/environment.scm: Delete file.
* Makefile.am: Remove it from the list of tests.
* geesh/shell.scm, geesh/eval.scm, geesh/repl.scm, geesh/word.scm,
geesh/built-ins/break.scm, geesh/built-ins/continue.scm,
geesh/built-ins/echo.scm, geesh/built-ins/export.scm,
geesh/built-ins/false.scm, geesh/built-ins/read.scm,
geesh/built-ins/readonly.scm, geesh/built-ins/set.scm,
geesh/built-ins/true.scm, geesh/built-ins/unset.scm: Remove 'env'
parameters and use the new environment module.
* .dir-locals.el: Update indentation of functions that no longer take
an 'env' parameter and add with-arguments, with-environ, and
with-variables from the new environment module.
* tests/shell.scm, tests/word.scm: Update environment creation and
manipulation in tests.
2018-11-25 05:47:09 +00:00
|
|
|
|
call-with-break
|
2018-12-04 20:24:30 +00:00
|
|
|
|
sh:break
|
2018-12-04 20:59:21 +00:00
|
|
|
|
call-with-return
|
|
|
|
|
sh:return
|
|
|
|
|
set-atexit!
|
|
|
|
|
sh:exit
|
Globalize the environment module
Instead of passing around references to the environment, just treat it
as a global. The old way was just the remains of an idea to make the
environment immutable and keep the interpreter from manipulating any
global state. By making everything global and mutable, we will have
less impedance mismatch with POSIX going forward.
The following changelog is only a sketch, since nearly every function
has changed.
* geesh/environment.scm: Replace this module with one that treats the
environment as a global resource.
* tests/environment.scm: Delete file.
* Makefile.am: Remove it from the list of tests.
* geesh/shell.scm, geesh/eval.scm, geesh/repl.scm, geesh/word.scm,
geesh/built-ins/break.scm, geesh/built-ins/continue.scm,
geesh/built-ins/echo.scm, geesh/built-ins/export.scm,
geesh/built-ins/false.scm, geesh/built-ins/read.scm,
geesh/built-ins/readonly.scm, geesh/built-ins/set.scm,
geesh/built-ins/true.scm, geesh/built-ins/unset.scm: Remove 'env'
parameters and use the new environment module.
* .dir-locals.el: Update indentation of functions that no longer take
an 'env' parameter and add with-arguments, with-environ, and
with-variables from the new environment module.
* tests/shell.scm, tests/word.scm: Update environment creation and
manipulation in tests.
2018-11-25 05:47:09 +00:00
|
|
|
|
*fd-count*
|
|
|
|
|
fd->current-port))
|
2018-07-12 02:51:54 +01:00
|
|
|
|
|
|
|
|
|
;;; Commentary:
|
|
|
|
|
;;;
|
Globalize the environment module
Instead of passing around references to the environment, just treat it
as a global. The old way was just the remains of an idea to make the
environment immutable and keep the interpreter from manipulating any
global state. By making everything global and mutable, we will have
less impedance mismatch with POSIX going forward.
The following changelog is only a sketch, since nearly every function
has changed.
* geesh/environment.scm: Replace this module with one that treats the
environment as a global resource.
* tests/environment.scm: Delete file.
* Makefile.am: Remove it from the list of tests.
* geesh/shell.scm, geesh/eval.scm, geesh/repl.scm, geesh/word.scm,
geesh/built-ins/break.scm, geesh/built-ins/continue.scm,
geesh/built-ins/echo.scm, geesh/built-ins/export.scm,
geesh/built-ins/false.scm, geesh/built-ins/read.scm,
geesh/built-ins/readonly.scm, geesh/built-ins/set.scm,
geesh/built-ins/true.scm, geesh/built-ins/unset.scm: Remove 'env'
parameters and use the new environment module.
* .dir-locals.el: Update indentation of functions that no longer take
an 'env' parameter and add with-arguments, with-environ, and
with-variables from the new environment module.
* tests/shell.scm, tests/word.scm: Update environment creation and
manipulation in tests.
2018-11-25 05:47:09 +00:00
|
|
|
|
;;; This module contains functions to inspect and manipulate the
|
2018-07-12 02:51:54 +01:00
|
|
|
|
;;; environment of the Shell language.
|
|
|
|
|
;;;
|
|
|
|
|
;;; Code:
|
|
|
|
|
|
Globalize the environment module
Instead of passing around references to the environment, just treat it
as a global. The old way was just the remains of an idea to make the
environment immutable and keep the interpreter from manipulating any
global state. By making everything global and mutable, we will have
less impedance mismatch with POSIX going forward.
The following changelog is only a sketch, since nearly every function
has changed.
* geesh/environment.scm: Replace this module with one that treats the
environment as a global resource.
* tests/environment.scm: Delete file.
* Makefile.am: Remove it from the list of tests.
* geesh/shell.scm, geesh/eval.scm, geesh/repl.scm, geesh/word.scm,
geesh/built-ins/break.scm, geesh/built-ins/continue.scm,
geesh/built-ins/echo.scm, geesh/built-ins/export.scm,
geesh/built-ins/false.scm, geesh/built-ins/read.scm,
geesh/built-ins/readonly.scm, geesh/built-ins/set.scm,
geesh/built-ins/true.scm, geesh/built-ins/unset.scm: Remove 'env'
parameters and use the new environment module.
* .dir-locals.el: Update indentation of functions that no longer take
an 'env' parameter and add with-arguments, with-environ, and
with-variables from the new environment module.
* tests/shell.scm, tests/word.scm: Update environment creation and
manipulation in tests.
2018-11-25 05:47:09 +00:00
|
|
|
|
|
2018-12-05 18:58:34 +00:00
|
|
|
|
;;; Status and PID.
|
Globalize the environment module
Instead of passing around references to the environment, just treat it
as a global. The old way was just the remains of an idea to make the
environment immutable and keep the interpreter from manipulating any
global state. By making everything global and mutable, we will have
less impedance mismatch with POSIX going forward.
The following changelog is only a sketch, since nearly every function
has changed.
* geesh/environment.scm: Replace this module with one that treats the
environment as a global resource.
* tests/environment.scm: Delete file.
* Makefile.am: Remove it from the list of tests.
* geesh/shell.scm, geesh/eval.scm, geesh/repl.scm, geesh/word.scm,
geesh/built-ins/break.scm, geesh/built-ins/continue.scm,
geesh/built-ins/echo.scm, geesh/built-ins/export.scm,
geesh/built-ins/false.scm, geesh/built-ins/read.scm,
geesh/built-ins/readonly.scm, geesh/built-ins/set.scm,
geesh/built-ins/true.scm, geesh/built-ins/unset.scm: Remove 'env'
parameters and use the new environment module.
* .dir-locals.el: Update indentation of functions that no longer take
an 'env' parameter and add with-arguments, with-environ, and
with-variables from the new environment module.
* tests/shell.scm, tests/word.scm: Update environment creation and
manipulation in tests.
2018-11-25 05:47:09 +00:00
|
|
|
|
|
|
|
|
|
(define *status* 0)
|
|
|
|
|
|
|
|
|
|
(define (get-status)
|
|
|
|
|
"Return the current status."
|
|
|
|
|
*status*)
|
|
|
|
|
|
|
|
|
|
(define (set-status! n)
|
|
|
|
|
"Set the current status."
|
|
|
|
|
(set! *status* n))
|
|
|
|
|
|
2018-12-05 18:58:34 +00:00
|
|
|
|
(define *root-pid* (getpid))
|
|
|
|
|
|
|
|
|
|
(define (get-root-pid)
|
|
|
|
|
*root-pid*)
|
|
|
|
|
|
Globalize the environment module
Instead of passing around references to the environment, just treat it
as a global. The old way was just the remains of an idea to make the
environment immutable and keep the interpreter from manipulating any
global state. By making everything global and mutable, we will have
less impedance mismatch with POSIX going forward.
The following changelog is only a sketch, since nearly every function
has changed.
* geesh/environment.scm: Replace this module with one that treats the
environment as a global resource.
* tests/environment.scm: Delete file.
* Makefile.am: Remove it from the list of tests.
* geesh/shell.scm, geesh/eval.scm, geesh/repl.scm, geesh/word.scm,
geesh/built-ins/break.scm, geesh/built-ins/continue.scm,
geesh/built-ins/echo.scm, geesh/built-ins/export.scm,
geesh/built-ins/false.scm, geesh/built-ins/read.scm,
geesh/built-ins/readonly.scm, geesh/built-ins/set.scm,
geesh/built-ins/true.scm, geesh/built-ins/unset.scm: Remove 'env'
parameters and use the new environment module.
* .dir-locals.el: Update indentation of functions that no longer take
an 'env' parameter and add with-arguments, with-environ, and
with-variables from the new environment module.
* tests/shell.scm, tests/word.scm: Update environment creation and
manipulation in tests.
2018-11-25 05:47:09 +00:00
|
|
|
|
|
|
|
|
|
;;; Variables.
|
|
|
|
|
|
|
|
|
|
(define (environ->alist env)
|
|
|
|
|
"Convert @var{environ} (a value of the type returned by
|
|
|
|
|
@code{environ}) to an alist."
|
2018-07-18 04:29:37 +01:00
|
|
|
|
(define (string-split-1 str char_pred)
|
|
|
|
|
(and=> (string-index str char_pred)
|
|
|
|
|
(lambda (index)
|
|
|
|
|
`(,(substring str 0 index) . ,(substring str (1+ index))))))
|
Globalize the environment module
Instead of passing around references to the environment, just treat it
as a global. The old way was just the remains of an idea to make the
environment immutable and keep the interpreter from manipulating any
global state. By making everything global and mutable, we will have
less impedance mismatch with POSIX going forward.
The following changelog is only a sketch, since nearly every function
has changed.
* geesh/environment.scm: Replace this module with one that treats the
environment as a global resource.
* tests/environment.scm: Delete file.
* Makefile.am: Remove it from the list of tests.
* geesh/shell.scm, geesh/eval.scm, geesh/repl.scm, geesh/word.scm,
geesh/built-ins/break.scm, geesh/built-ins/continue.scm,
geesh/built-ins/echo.scm, geesh/built-ins/export.scm,
geesh/built-ins/false.scm, geesh/built-ins/read.scm,
geesh/built-ins/readonly.scm, geesh/built-ins/set.scm,
geesh/built-ins/true.scm, geesh/built-ins/unset.scm: Remove 'env'
parameters and use the new environment module.
* .dir-locals.el: Update indentation of functions that no longer take
an 'env' parameter and add with-arguments, with-environ, and
with-variables from the new environment module.
* tests/shell.scm, tests/word.scm: Update environment creation and
manipulation in tests.
2018-11-25 05:47:09 +00:00
|
|
|
|
(filter-map (cut string-split-1 <> #\=) env))
|
|
|
|
|
|
2018-12-05 16:06:25 +00:00
|
|
|
|
(define (initial-pwd env)
|
|
|
|
|
(let* ((pwd (assoc-ref env "PWD"))
|
|
|
|
|
(pwd-p (false-if-exception (canonicalize-path pwd))))
|
|
|
|
|
(if (and pwd
|
|
|
|
|
(string-prefix? "/" pwd)
|
|
|
|
|
pwd-p
|
|
|
|
|
(string=? pwd-p (getcwd))
|
|
|
|
|
(not (any (lambda (component)
|
|
|
|
|
(member component '("." "..")))
|
|
|
|
|
(string-split pwd #\/))))
|
|
|
|
|
pwd
|
|
|
|
|
(getcwd))))
|
|
|
|
|
|
|
|
|
|
(define (initial-variables)
|
|
|
|
|
(let ((env (environ->alist (environ))))
|
|
|
|
|
(alist->hash-table
|
|
|
|
|
(map (match-lambda
|
|
|
|
|
((name . value) `(,name . ,(vector value #t #f))))
|
|
|
|
|
(append `(("PWD" . ,(initial-pwd env)))
|
|
|
|
|
env)))))
|
|
|
|
|
|
|
|
|
|
(define *variables* (initial-variables))
|
Globalize the environment module
Instead of passing around references to the environment, just treat it
as a global. The old way was just the remains of an idea to make the
environment immutable and keep the interpreter from manipulating any
global state. By making everything global and mutable, we will have
less impedance mismatch with POSIX going forward.
The following changelog is only a sketch, since nearly every function
has changed.
* geesh/environment.scm: Replace this module with one that treats the
environment as a global resource.
* tests/environment.scm: Delete file.
* Makefile.am: Remove it from the list of tests.
* geesh/shell.scm, geesh/eval.scm, geesh/repl.scm, geesh/word.scm,
geesh/built-ins/break.scm, geesh/built-ins/continue.scm,
geesh/built-ins/echo.scm, geesh/built-ins/export.scm,
geesh/built-ins/false.scm, geesh/built-ins/read.scm,
geesh/built-ins/readonly.scm, geesh/built-ins/set.scm,
geesh/built-ins/true.scm, geesh/built-ins/unset.scm: Remove 'env'
parameters and use the new environment module.
* .dir-locals.el: Update indentation of functions that no longer take
an 'env' parameter and add with-arguments, with-environ, and
with-variables from the new environment module.
* tests/shell.scm, tests/word.scm: Update environment creation and
manipulation in tests.
2018-11-25 05:47:09 +00:00
|
|
|
|
|
|
|
|
|
(define (exported? name)
|
|
|
|
|
"Check if the variable @var{name} has been exported."
|
|
|
|
|
(match (hash-ref *variables* name)
|
|
|
|
|
(#(_ exported? _) exported?)
|
|
|
|
|
(_ #f)))
|
|
|
|
|
|
|
|
|
|
(define* (set-exported! name #:optional value)
|
|
|
|
|
"Export the variable @var{name}. If the optional parameter
|
|
|
|
|
@var{value} is provided, update the variable's value as well."
|
|
|
|
|
(match (hash-ref *variables* name)
|
|
|
|
|
((? vector? vec)
|
|
|
|
|
(vector-set! vec 1 #t)
|
|
|
|
|
(when value
|
|
|
|
|
(vector-set! vec 0 value)))
|
|
|
|
|
(v (hash-set! *variables* name (vector (or value v) #t #f)))))
|
|
|
|
|
|
|
|
|
|
(define (read-only? name)
|
|
|
|
|
"Check if the variable @var{name} has been marked read-only."
|
|
|
|
|
(match (hash-ref *variables* name)
|
|
|
|
|
(#(_ _ read-only?) read-only?)
|
|
|
|
|
(_ #f)))
|
|
|
|
|
|
|
|
|
|
(define* (set-read-only! name #:optional value)
|
|
|
|
|
"Mark the variable @var{name} as read-only. If the optional
|
|
|
|
|
parameter @var{value} is provided, update the variable's value as
|
|
|
|
|
well."
|
|
|
|
|
(match (hash-ref *variables* name)
|
|
|
|
|
((? vector? vec)
|
|
|
|
|
(vector-set! vec 2 #t)
|
|
|
|
|
(when value
|
|
|
|
|
(vector-set! vec 0 value)))
|
|
|
|
|
(v (hash-set! *variables* name (vector (or value v) #f #t)))))
|
|
|
|
|
|
|
|
|
|
(define* (getvar name #:optional dflt)
|
|
|
|
|
"Return the value of the variable @var{name}. If it does not exist
|
|
|
|
|
and @var{dflt} is provided, return @var{dflt}. Otherwise, return
|
|
|
|
|
@code{#f}."
|
|
|
|
|
(match (hash-ref *variables* name dflt)
|
2018-12-31 16:03:30 +00:00
|
|
|
|
(#(value _ _) (or value dflt))
|
Globalize the environment module
Instead of passing around references to the environment, just treat it
as a global. The old way was just the remains of an idea to make the
environment immutable and keep the interpreter from manipulating any
global state. By making everything global and mutable, we will have
less impedance mismatch with POSIX going forward.
The following changelog is only a sketch, since nearly every function
has changed.
* geesh/environment.scm: Replace this module with one that treats the
environment as a global resource.
* tests/environment.scm: Delete file.
* Makefile.am: Remove it from the list of tests.
* geesh/shell.scm, geesh/eval.scm, geesh/repl.scm, geesh/word.scm,
geesh/built-ins/break.scm, geesh/built-ins/continue.scm,
geesh/built-ins/echo.scm, geesh/built-ins/export.scm,
geesh/built-ins/false.scm, geesh/built-ins/read.scm,
geesh/built-ins/readonly.scm, geesh/built-ins/set.scm,
geesh/built-ins/true.scm, geesh/built-ins/unset.scm: Remove 'env'
parameters and use the new environment module.
* .dir-locals.el: Update indentation of functions that no longer take
an 'env' parameter and add with-arguments, with-environ, and
with-variables from the new environment module.
* tests/shell.scm, tests/word.scm: Update environment creation and
manipulation in tests.
2018-11-25 05:47:09 +00:00
|
|
|
|
(value value)))
|
|
|
|
|
|
|
|
|
|
(define (setvar! name value)
|
|
|
|
|
"Set the variable @var{name} to @var{value}. If @var{value} is
|
|
|
|
|
@code{#f}, the variable will be removed from the set of current
|
|
|
|
|
variables. If @var{name} has been marked read-only, an exception will
|
|
|
|
|
be thrown."
|
|
|
|
|
(match (hash-ref *variables* name)
|
|
|
|
|
((? vector? vec)
|
|
|
|
|
(when (vector-ref vec 2)
|
|
|
|
|
(scm-error
|
|
|
|
|
'shell-error "setvar!"
|
|
|
|
|
"Attempted to assign the read-only only variable \"~A\"."
|
|
|
|
|
`(,name)
|
|
|
|
|
'(variable-assignment-error)))
|
|
|
|
|
(if value
|
|
|
|
|
(vector-set! vec 0 value)
|
|
|
|
|
(hash-remove! *variables* name)))
|
|
|
|
|
(_ (if value
|
|
|
|
|
(hash-set! *variables* name value)
|
|
|
|
|
(hash-remove! *variables* name)))))
|
|
|
|
|
|
|
|
|
|
(define (unsetvar! name)
|
|
|
|
|
"Remove the variable @var{name} from the set of current variables."
|
|
|
|
|
(setvar! name #f))
|
|
|
|
|
|
|
|
|
|
(define (with-variables variables thunk)
|
|
|
|
|
"Call @var{thunk} in a dynamic extent in which the set of current
|
|
|
|
|
variables contains only @var{variables}. The previous set of current
|
|
|
|
|
variables is unaffected by any changes made from within the dynamic
|
|
|
|
|
extent of @var{thunk}."
|
|
|
|
|
(let ((outside-variables #f)
|
|
|
|
|
(inside-variables (alist->hash-table variables)))
|
|
|
|
|
(dynamic-wind
|
|
|
|
|
(lambda ()
|
|
|
|
|
(set! outside-variables *variables*)
|
|
|
|
|
(set! *variables* inside-variables))
|
|
|
|
|
thunk
|
|
|
|
|
(lambda ()
|
|
|
|
|
(set! inside-variables *variables*)
|
|
|
|
|
(set! outside-variables *variables*)))))
|
|
|
|
|
|
|
|
|
|
(define* (get-environ #:optional (bindings '()))
|
|
|
|
|
"Return a value that represents the set of current variables is
|
|
|
|
|
suitable for passing to @code{environ}. If @var{bindings} is set,
|
|
|
|
|
consider them as part of the set of current variables."
|
|
|
|
|
(let ((exported (hash-fold (lambda (name v acc)
|
|
|
|
|
(match v
|
|
|
|
|
(#(value #t _)
|
|
|
|
|
(cons `(,name . ,value) acc))
|
|
|
|
|
(_ acc)))
|
|
|
|
|
'()
|
|
|
|
|
*variables*)))
|
|
|
|
|
(map (match-lambda
|
|
|
|
|
((name . value) (string-append name "=" value)))
|
|
|
|
|
(delete-duplicates!
|
|
|
|
|
(append bindings exported)
|
|
|
|
|
(lambda (x y)
|
|
|
|
|
(string=? (car x) (car y)))))))
|
|
|
|
|
|
|
|
|
|
(define (with-environ env thunk)
|
|
|
|
|
"Call @var{thunk} in a dynamic extent in which the environment (the
|
|
|
|
|
regular @code{getenv}/@code{setenv} one -- not the Geesh one) has been
|
|
|
|
|
set to @var{env} (a value suitable for passing to @code{environ}."
|
|
|
|
|
(let ((outside-env #f)
|
|
|
|
|
(inside-env env))
|
|
|
|
|
(dynamic-wind
|
|
|
|
|
(lambda ()
|
|
|
|
|
(set! outside-env (environ))
|
|
|
|
|
(environ inside-env))
|
|
|
|
|
thunk
|
|
|
|
|
(lambda ()
|
|
|
|
|
(set! inside-env (environ))
|
|
|
|
|
(environ outside-env)))))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
;;; Functions.
|
|
|
|
|
|
|
|
|
|
(define *functions* (make-hash-table))
|
|
|
|
|
|
|
|
|
|
(define (getfun name)
|
|
|
|
|
"Return the function @var{name}. If it does not exist, return
|
|
|
|
|
@code{#f}."
|
|
|
|
|
(hash-ref *functions* name))
|
|
|
|
|
|
|
|
|
|
(define (defun! name proc)
|
|
|
|
|
"Define the function @var{name} to be @var{proc} (a procedure that
|
|
|
|
|
takes a variable number of arguments)."
|
|
|
|
|
(hash-set! *functions* name proc))
|
|
|
|
|
|
|
|
|
|
(define (unsetfun! name)
|
|
|
|
|
"Remove the function @var{name} from the set of current functions."
|
|
|
|
|
(hash-remove! *functions* name))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
;;; Arguments.
|
|
|
|
|
|
|
|
|
|
(define (with-arguments args thunk)
|
|
|
|
|
"Call @var{thunk} in a dynamic extent in which the current arguments
|
|
|
|
|
list (as obtained by calling @code{program-arguments}) is set to
|
|
|
|
|
@var{args}. The previous arguments list is unaffected by any changes
|
|
|
|
|
made from within the dynamic extent of @var{thunk}."
|
|
|
|
|
(let ((outside-args #f)
|
|
|
|
|
(inside-args args))
|
2018-11-09 03:11:34 +00:00
|
|
|
|
(dynamic-wind
|
|
|
|
|
(lambda ()
|
Globalize the environment module
Instead of passing around references to the environment, just treat it
as a global. The old way was just the remains of an idea to make the
environment immutable and keep the interpreter from manipulating any
global state. By making everything global and mutable, we will have
less impedance mismatch with POSIX going forward.
The following changelog is only a sketch, since nearly every function
has changed.
* geesh/environment.scm: Replace this module with one that treats the
environment as a global resource.
* tests/environment.scm: Delete file.
* Makefile.am: Remove it from the list of tests.
* geesh/shell.scm, geesh/eval.scm, geesh/repl.scm, geesh/word.scm,
geesh/built-ins/break.scm, geesh/built-ins/continue.scm,
geesh/built-ins/echo.scm, geesh/built-ins/export.scm,
geesh/built-ins/false.scm, geesh/built-ins/read.scm,
geesh/built-ins/readonly.scm, geesh/built-ins/set.scm,
geesh/built-ins/true.scm, geesh/built-ins/unset.scm: Remove 'env'
parameters and use the new environment module.
* .dir-locals.el: Update indentation of functions that no longer take
an 'env' parameter and add with-arguments, with-environ, and
with-variables from the new environment module.
* tests/shell.scm, tests/word.scm: Update environment creation and
manipulation in tests.
2018-11-25 05:47:09 +00:00
|
|
|
|
(set! outside-args (program-arguments))
|
|
|
|
|
(set-program-arguments inside-args))
|
2018-11-09 03:11:34 +00:00
|
|
|
|
thunk
|
|
|
|
|
(lambda ()
|
Globalize the environment module
Instead of passing around references to the environment, just treat it
as a global. The old way was just the remains of an idea to make the
environment immutable and keep the interpreter from manipulating any
global state. By making everything global and mutable, we will have
less impedance mismatch with POSIX going forward.
The following changelog is only a sketch, since nearly every function
has changed.
* geesh/environment.scm: Replace this module with one that treats the
environment as a global resource.
* tests/environment.scm: Delete file.
* Makefile.am: Remove it from the list of tests.
* geesh/shell.scm, geesh/eval.scm, geesh/repl.scm, geesh/word.scm,
geesh/built-ins/break.scm, geesh/built-ins/continue.scm,
geesh/built-ins/echo.scm, geesh/built-ins/export.scm,
geesh/built-ins/false.scm, geesh/built-ins/read.scm,
geesh/built-ins/readonly.scm, geesh/built-ins/set.scm,
geesh/built-ins/true.scm, geesh/built-ins/unset.scm: Remove 'env'
parameters and use the new environment module.
* .dir-locals.el: Update indentation of functions that no longer take
an 'env' parameter and add with-arguments, with-environ, and
with-variables from the new environment module.
* tests/shell.scm, tests/word.scm: Update environment creation and
manipulation in tests.
2018-11-25 05:47:09 +00:00
|
|
|
|
(set! inside-args (program-arguments))
|
|
|
|
|
(set-program-arguments outside-args)))))
|
|
|
|
|
|
2018-11-26 01:57:08 +00:00
|
|
|
|
|
|
|
|
|
;;; Options.
|
|
|
|
|
|
|
|
|
|
(define *options*
|
|
|
|
|
(map (cut cons <> #f)
|
|
|
|
|
'(allexport
|
|
|
|
|
errexit
|
|
|
|
|
ignoreeof
|
|
|
|
|
monitor
|
|
|
|
|
noclobber
|
|
|
|
|
noglob
|
|
|
|
|
noexec
|
|
|
|
|
nolog
|
|
|
|
|
notify
|
|
|
|
|
nounset
|
|
|
|
|
verbose
|
|
|
|
|
vi
|
|
|
|
|
xtrace)))
|
|
|
|
|
|
|
|
|
|
(define (getopt name)
|
|
|
|
|
"Get the value of the option named @var{name}."
|
|
|
|
|
(match (assq name *options*)
|
|
|
|
|
((_ . value) value)))
|
|
|
|
|
|
|
|
|
|
(define (setopt! name value)
|
|
|
|
|
"Set the value of the option named @var{name} to @var{value}."
|
|
|
|
|
(match (assq name *options*)
|
|
|
|
|
((? pair? p) (set-cdr! p value))))
|
|
|
|
|
|
|
|
|
|
(define *option-names*
|
|
|
|
|
(map car *options*))
|
|
|
|
|
|
|
|
|
|
(define *option-letters*
|
|
|
|
|
'((#\a . allexport)
|
|
|
|
|
(#\e . errexit)
|
|
|
|
|
(#\m . monitor)
|
|
|
|
|
(#\C . noclobber)
|
|
|
|
|
(#\f . noglob)
|
|
|
|
|
(#\n . noexec)
|
|
|
|
|
(#\b . notify)
|
|
|
|
|
(#\u . nounset)
|
|
|
|
|
(#\v . verbose)
|
|
|
|
|
(#\x . xtrace)))
|
|
|
|
|
|
Globalize the environment module
Instead of passing around references to the environment, just treat it
as a global. The old way was just the remains of an idea to make the
environment immutable and keep the interpreter from manipulating any
global state. By making everything global and mutable, we will have
less impedance mismatch with POSIX going forward.
The following changelog is only a sketch, since nearly every function
has changed.
* geesh/environment.scm: Replace this module with one that treats the
environment as a global resource.
* tests/environment.scm: Delete file.
* Makefile.am: Remove it from the list of tests.
* geesh/shell.scm, geesh/eval.scm, geesh/repl.scm, geesh/word.scm,
geesh/built-ins/break.scm, geesh/built-ins/continue.scm,
geesh/built-ins/echo.scm, geesh/built-ins/export.scm,
geesh/built-ins/false.scm, geesh/built-ins/read.scm,
geesh/built-ins/readonly.scm, geesh/built-ins/set.scm,
geesh/built-ins/true.scm, geesh/built-ins/unset.scm: Remove 'env'
parameters and use the new environment module.
* .dir-locals.el: Update indentation of functions that no longer take
an 'env' parameter and add with-arguments, with-environ, and
with-variables from the new environment module.
* tests/shell.scm, tests/word.scm: Update environment creation and
manipulation in tests.
2018-11-25 05:47:09 +00:00
|
|
|
|
|
|
|
|
|
;;; Prompts
|
|
|
|
|
|
|
|
|
|
(define *continue-tag* (make-prompt-tag))
|
|
|
|
|
|
|
|
|
|
(define (call-with-continue thunk)
|
|
|
|
|
"Call @var{thunk} in such a way that a call to @code{continue} will
|
|
|
|
|
exit the dynamic extent of @var{thunk}."
|
|
|
|
|
(call-with-prompt *continue-tag*
|
|
|
|
|
thunk
|
|
|
|
|
(lambda (cont n)
|
|
|
|
|
(when (> n 0)
|
|
|
|
|
(false-if-exception
|
|
|
|
|
(abort-to-prompt *continue-tag* (1- n)))))))
|
|
|
|
|
|
2018-12-04 20:24:30 +00:00
|
|
|
|
(define* (sh:continue #:optional (n 0))
|
Globalize the environment module
Instead of passing around references to the environment, just treat it
as a global. The old way was just the remains of an idea to make the
environment immutable and keep the interpreter from manipulating any
global state. By making everything global and mutable, we will have
less impedance mismatch with POSIX going forward.
The following changelog is only a sketch, since nearly every function
has changed.
* geesh/environment.scm: Replace this module with one that treats the
environment as a global resource.
* tests/environment.scm: Delete file.
* Makefile.am: Remove it from the list of tests.
* geesh/shell.scm, geesh/eval.scm, geesh/repl.scm, geesh/word.scm,
geesh/built-ins/break.scm, geesh/built-ins/continue.scm,
geesh/built-ins/echo.scm, geesh/built-ins/export.scm,
geesh/built-ins/false.scm, geesh/built-ins/read.scm,
geesh/built-ins/readonly.scm, geesh/built-ins/set.scm,
geesh/built-ins/true.scm, geesh/built-ins/unset.scm: Remove 'env'
parameters and use the new environment module.
* .dir-locals.el: Update indentation of functions that no longer take
an 'env' parameter and add with-arguments, with-environ, and
with-variables from the new environment module.
* tests/shell.scm, tests/word.scm: Update environment creation and
manipulation in tests.
2018-11-25 05:47:09 +00:00
|
|
|
|
"Exit to the closest invocation of @code{call-with-continue}. If
|
|
|
|
|
@var{n} is set, exit to the @math{n + 1}th closest invocation."
|
|
|
|
|
(abort-to-prompt *continue-tag* n))
|
|
|
|
|
|
|
|
|
|
(define *break-tag* (make-prompt-tag))
|
|
|
|
|
|
|
|
|
|
(define (call-with-break thunk)
|
|
|
|
|
"Call @var{thunk} in such a way that a call to @code{break} will
|
|
|
|
|
exit the dynamic extent of @var{thunk}."
|
|
|
|
|
(call-with-prompt *break-tag*
|
|
|
|
|
thunk
|
|
|
|
|
(lambda (cont n)
|
|
|
|
|
(when (> n 0)
|
|
|
|
|
(false-if-exception
|
|
|
|
|
(abort-to-prompt *break-tag* (1- n)))))))
|
|
|
|
|
|
2018-12-04 20:24:30 +00:00
|
|
|
|
(define* (sh:break #:optional (n 0))
|
Globalize the environment module
Instead of passing around references to the environment, just treat it
as a global. The old way was just the remains of an idea to make the
environment immutable and keep the interpreter from manipulating any
global state. By making everything global and mutable, we will have
less impedance mismatch with POSIX going forward.
The following changelog is only a sketch, since nearly every function
has changed.
* geesh/environment.scm: Replace this module with one that treats the
environment as a global resource.
* tests/environment.scm: Delete file.
* Makefile.am: Remove it from the list of tests.
* geesh/shell.scm, geesh/eval.scm, geesh/repl.scm, geesh/word.scm,
geesh/built-ins/break.scm, geesh/built-ins/continue.scm,
geesh/built-ins/echo.scm, geesh/built-ins/export.scm,
geesh/built-ins/false.scm, geesh/built-ins/read.scm,
geesh/built-ins/readonly.scm, geesh/built-ins/set.scm,
geesh/built-ins/true.scm, geesh/built-ins/unset.scm: Remove 'env'
parameters and use the new environment module.
* .dir-locals.el: Update indentation of functions that no longer take
an 'env' parameter and add with-arguments, with-environ, and
with-variables from the new environment module.
* tests/shell.scm, tests/word.scm: Update environment creation and
manipulation in tests.
2018-11-25 05:47:09 +00:00
|
|
|
|
"Exit to the closest invocation of @code{call-with-break}. If
|
|
|
|
|
@var{n} is set, exit to the @math{n + 1}th closest invocation."
|
|
|
|
|
(abort-to-prompt *break-tag* n))
|
|
|
|
|
|
2018-12-04 20:59:21 +00:00
|
|
|
|
(define *return-tag* (make-prompt-tag))
|
|
|
|
|
|
|
|
|
|
(define (call-with-return thunk)
|
|
|
|
|
"Call @var{thunk} in such a way that a call to @code{return} will
|
|
|
|
|
exit the dynamic extent of @var{thunk}."
|
|
|
|
|
(call-with-prompt *return-tag*
|
|
|
|
|
thunk
|
|
|
|
|
(lambda (cont status)
|
|
|
|
|
(set-status! status))))
|
|
|
|
|
|
|
|
|
|
(define* (sh:return #:optional (status (get-status)))
|
|
|
|
|
"Exit to the closest invocation of @code{call-with-return} setting
|
|
|
|
|
status to @var{status}. If @var{status} is not set, keep the current
|
|
|
|
|
status."
|
|
|
|
|
(abort-to-prompt *return-tag* status))
|
|
|
|
|
|
|
|
|
|
(define *atexit* #f)
|
|
|
|
|
(define *exiting?* #f)
|
|
|
|
|
|
|
|
|
|
(define (set-atexit! handler)
|
|
|
|
|
(set! *atexit* handler))
|
|
|
|
|
|
|
|
|
|
(define* (sh:exit #:optional status)
|
|
|
|
|
(if (and (not *exiting?*) (thunk? *atexit*))
|
|
|
|
|
(begin
|
|
|
|
|
(set! *exiting?* #t)
|
|
|
|
|
(*atexit*)
|
|
|
|
|
(exit (or status (get-status))))
|
|
|
|
|
(exit (or status (get-status)))))
|
|
|
|
|
|
Globalize the environment module
Instead of passing around references to the environment, just treat it
as a global. The old way was just the remains of an idea to make the
environment immutable and keep the interpreter from manipulating any
global state. By making everything global and mutable, we will have
less impedance mismatch with POSIX going forward.
The following changelog is only a sketch, since nearly every function
has changed.
* geesh/environment.scm: Replace this module with one that treats the
environment as a global resource.
* tests/environment.scm: Delete file.
* Makefile.am: Remove it from the list of tests.
* geesh/shell.scm, geesh/eval.scm, geesh/repl.scm, geesh/word.scm,
geesh/built-ins/break.scm, geesh/built-ins/continue.scm,
geesh/built-ins/echo.scm, geesh/built-ins/export.scm,
geesh/built-ins/false.scm, geesh/built-ins/read.scm,
geesh/built-ins/readonly.scm, geesh/built-ins/set.scm,
geesh/built-ins/true.scm, geesh/built-ins/unset.scm: Remove 'env'
parameters and use the new environment module.
* .dir-locals.el: Update indentation of functions that no longer take
an 'env' parameter and add with-arguments, with-environ, and
with-variables from the new environment module.
* tests/shell.scm, tests/word.scm: Update environment creation and
manipulation in tests.
2018-11-25 05:47:09 +00:00
|
|
|
|
|
|
|
|
|
;;; Files.
|
|
|
|
|
|
|
|
|
|
(define *fd-count* 10)
|
|
|
|
|
|
|
|
|
|
(define current-3-port (make-parameter #f))
|
|
|
|
|
(define current-4-port (make-parameter #f))
|
|
|
|
|
(define current-5-port (make-parameter #f))
|
|
|
|
|
(define current-6-port (make-parameter #f))
|
|
|
|
|
(define current-7-port (make-parameter #f))
|
|
|
|
|
(define current-8-port (make-parameter #f))
|
|
|
|
|
(define current-9-port (make-parameter #f))
|
|
|
|
|
|
|
|
|
|
(define fd->current-port
|
|
|
|
|
(let ((cps (vector current-input-port
|
|
|
|
|
current-output-port
|
|
|
|
|
current-error-port
|
|
|
|
|
current-3-port
|
|
|
|
|
current-4-port
|
|
|
|
|
current-5-port
|
|
|
|
|
current-6-port
|
|
|
|
|
current-7-port
|
|
|
|
|
current-8-port
|
|
|
|
|
current-9-port)))
|
|
|
|
|
(lambda (fd)
|
|
|
|
|
"Return the current port (e.g. @code{current-input-port})
|
|
|
|
|
corresponding to the the Shell file descriptor @var{fd}. The value of
|
|
|
|
|
@var{fd} must be a nonnegative integer less than @code{*fd-count*}."
|
|
|
|
|
(vector-ref cps fd))))
|