scsh-users
[Top] [All Lists]

command line interface

To: scsh@martigny.ai.mit.edu
Subject: command line interface
From: spot@goober.graphics.cs.cmu.edu (Scott Draves)
Date: 27 Jun 1996 22:55:23 GMT
Organization: Carnegie-Mellon University, School of Computer Science
a while ago people where talking about implementing a better
interactive command line to scsh.  below is a very simple start at
one.  the way it handles both single and multiple line inputs is kind
of interesting.

#!
   cli - command line interface for scsh
   Copyright (C) 1995  Scott Draves <spot@cs.cmu.edu>

   This program 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 2 of the License, or
   (at your option) any later version.

   This program 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 this program; if not, write to the Free Software
   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
!#

#!

todo:

better syntax for globbing, tilde

job control (& adds pid to list)

access to module system

interrupts

handle multiple return values

!#
#!
> ,config ,load cli.scm
cli.scm .
> ,open cli
Load structure cli (y/n)? y
> (cli)
cli> (+ 1 2)
3
cli> date
Wed Jun 26 02:13:43 EDT 1996
cli> (define file "/afs/cs/user/spot/.twmrc")
cli> wc ,file
       225       591      5220 /afs/cs/user/spot/.twmrc
cli> grep color ,file
exit code 256
cli> sort /etc/protocols | tail -5 > /tmp/foo
cli> rm /tmp/foo
cli> cat /tmp/foo
UX:cat: ERROR: Cannot open /tmp/foo: No such file or directory
exit code 512
cli> ls -ld ,@(glob "p*")
drwxr-xr-x    6 spot     sys         2048 Nov 14  1994 pgp
drwxr-xr-x    2 spot     sys         2048 Feb 28 13:04 pub
cli> cd pgp
cli> ls
2.6-doc            doc                pgp.hlp            readme.doc
config.txt         local-pubring.bak  pgp.pmax_mach      src
contrib            local-pubring.pgp  pgp.sun4_mach
cli> (define (fact x)
        (if (zero? x) 1 (* x (fact (- x 1)))))
cli> (fact 10)
3628800
cli> 
!#

(define-structure cli
  (export cli)
  (open util pp handle scsh scheme)
  (begin

    (define (read-cmd prefix)
      (let ((l (read-line)))
        (if (eof-object? l) l
            (let* ((l (string-append prefix l))
                   (p (make-string-input-port l)))
              (call-with-current-continuation
               (lambda (k)
                 (with-handler (lambda (c punt)
                                 (if (eq? 'read-error (car c))
                                     (k (read-cmd (string-append l "\n")))
                                     (punt)))
                               (lambda ()
                                 (port->sexp-list p)))))))))

    (define (expand cmd)
      (define (redirs cmd stack)
        (if (null? cmd)
            (list (reverse stack))
            (case (car cmd)
              ((< > >> <<) (cons (reverse stack)
                                 (let ((a (redirs (cdr cmd) '())))
                                   (cons (cons (car cmd) (car a))
                                         (cdr a)))))
              (else (redirs (cdr cmd) (cons (car cmd) stack))))))
      (define (next stack)
        (cons 'epf (redirs (reverse stack) '())))
      (define (pipes cmd stack)
        (cond ((null? cmd) (list (next stack)))
              ((eq? (car cmd) '|) (cons (next stack) (pipes (cdr cmd) '())))
              (else (pipes (cdr cmd) (cons (car cmd) stack)))))

      (let ((r (reverse cmd)))
        (if (eq? '& (car r))
            `(& (| . ,(pipes (reverse (cdr r)) '())))
            `(run (| . ,(pipes cmd '()))))))

    (define (safe-eval e)
      (call-with-current-continuation
       (lambda (k)
         (define (handle c punt)
           (format #t "~S: ~A~%" (car c) (cadr c))
           (p (cddr c))
           (k (unspecific)))
         (with-handler handle
                       (lambda ()
                         (eval e (interaction-environment)))))))

    (define (one-cmd)
      (format #t "cli> ")
      (let ((cmd (read-cmd "")))
        (cond ((eof-object? cmd) cmd)
              ((null? cmd) 'empty)
              ((and (null? (cdr cmd)) (pair? (car cmd)))
               (let ((r (safe-eval (car cmd))))
                 (if (not (eq? r (unspecific)))
                     (p r))))
              ((eq? 'cd (car cmd)) (chdir (symbol->string (cadr cmd))))
              (else (let ((status (eval (expand cmd)  
(interaction-environment))))
                      (if (and (number? status) (not (zero? status)))
                          (format #t "exit code ~S~%" status)))))))

    (define (cli)
      (define (loop)
        (if (not (eof-object? (one-cmd)))
            (loop)))
      (loop)
      (format #t "~%cli done~%")
      (unspecific))))

--
                                balance
                                equilibrium
                                death

http://www.cs.cmu.edu/~spot
spot@cs.cmu.edu

<Prev in Thread] Current Thread [Next in Thread>
  • command line interface, Scott Draves <=