Mercurial > core / lisp/lib/cli/shell.lisp
changeset 698: |
96958d3eb5b0 |
parent: |
5540a3e32ba1
|
author: |
Richard Westhaver <ellis@rwest.io> |
date: |
Fri, 04 Oct 2024 22:04:59 -0400 |
permissions: |
-rw-r--r-- |
description: |
fixes |
1 ;;; lib/cli/shell.lisp --- shell utils 3 ;; utils for working with shells in different environments 9 ;; A read macro is accessible in the named readtable :SHELL. It has 10 ;; three modes of operation: read, compile, and eval. In read mode, 11 ;; input is parsed and embedded lisp forms are expanded. The string is 12 ;; returned as is. In eval mode, embedded lisp forms are expanded and 13 ;; the resulting string is wrapped in a call to 14 ;; SB-EXT:RUN-PROGRAM. Finally, in eval mode the compiled function is 15 ;; called with default arguments and the result of that call is 19 (in-package :cli/shell) 22 (defparameter *shell* "/bin/bash") 23 (defparameter *shell-directory* nil) 24 (defparameter *shell-input* nil) 26 (deftype %shell-state () '(member :sh :dolla :pound)) 28 (defun plain-shell-reader (stream) 29 (let (out (state :sh)) 30 (declare (type %shell-state state)) 31 (loop for c = (read-char stream) 35 (#\$ (setq state :dolla)) 36 (#\# (setq state :pound)) 41 (push (coerce (format nil "~A" (eval (read stream nil nil))) 'list) out) 54 (flatten (nreverse out))))) 56 (defmacro define-process-output-handler (type &body body) 57 "Define a new function which handles the result of a SB-EXT:PROCESS in 58 the context of the $#-reader macro." 59 (declare (ignore type body))) 61 (defun |#$-reader| (stream sub-char numarg) 62 "Switch on the shell reader, parsing STREAM and returning a 63 shell program or executing it. In other words, this is an 64 implementation of the lazy version of SHCL's #$-reader. 66 Similar to shcl, we add some reader extensions to enable embedding 67 lisp forms and other goodies. 73 (declare (ignore sub-char) ((or (integer 0 9) null) numarg)) 74 (let ((str (plain-shell-reader stream))) 79 (string-right-trim '(#\Newline) 80 (with-output-to-string (s) 81 (sb-ext:run-program *shell* 82 (list "-c" (format nil "~a" str)) 83 :directory (or *shell-directory* *default-pathname-defaults*) 85 :input *shell-input*)))) 87 (let ((args (list "-c" (format nil "~a" str))) 88 (directory (or *shell-directory* *default-pathname-defaults*))) 89 (lambda (&key (output *standard-output*) (wait t)) 91 (:string (string-right-trim 93 (with-output-to-string (s) 94 (sb-ext:run-program *shell* args 99 (:integer (parse-integer 102 (with-output-to-string (s) 103 (sb-ext:run-program *shell* args 108 (t (sb-ext:run-program *shell* 116 "The shell readtable" 118 (:dispatch-macro-char #\# #\$ #'|#$-reader|))