;;; -*- mode:lisp;package:user;base:10.;fonts:(cptfontb) -*- ;;; ;;;$Header: /ct/ctlisp/ctio.l,v 1.20 84/09/05 10:45:57 alex Exp $ ;;; ;;;$Log: /ct/ctlisp/ctio.l,v $ ;;;Revision 1.20 84/09/05 10:45:57 alex ;;;fix the ct_readline2 in rel 5. ;;; ;;;Revision 1.19 84/06/26 17:13:21 alex ;;;handle the return immediately in ct_readline2, don't ;;;ignore them. ;;; ;;;Revision 1.18 84/06/26 01:01:20 alex ;;;append the #\return ad the end of the string returned by ct_readline2.This is important because the finite state machine use it to stop reading more num. ;;; ;;;Revision 1.17 84/06/25 14:08:36 alex ;;;add the ct_readline2 function. ;;; ;;;Revision 1.16 84/01/06 13:10:25 penny ;;;removed the localf declare for test-stream alex uses it ;;; ;;;Revision 1.15 83/12/09 14:01:17 john ;;;Added localf declarations ;;; ;;;Revision 1.14 83/10/18 12:06:10 john ;;;added ct_readline function. ;;; ;;;Revision 1.13 83/10/05 10:52:39 susan ;;;Added ct_tyipeeks that know about db%windows and extesting_streams ;;; ;;;Revision 1.12 83/09/24 23:22:06 mark ;;; Fixed underscore bug from VMS filename conversion and cleaned ;;; up commentary. Also tested each function a little. NB: these ;;; functions currently return different values on franz vs. zeta! ;;; ;;;Revision 1.11 83/09/20 22:56:11 penny ;;; Convert to new filename convention ;;; ;;;Revision 1.10 83/09/08 15:29:53 john ;;; Added freshline, skipline, and moved some of mark's ;;; private functions here to use ct_io. ;;; ;;;Revision 1.9 83/09/01 10:50:16 john ;;; Added ':' to 'ct_format ;;; ;;;Revision 1.8 83/09/01 10:43:32 john ;;; 2nd try to fix ct_format ;;; ;;;Revision 1.7 83/09/01 10:34:44 john ;;; Repaired ct_format to use "<-" with franz and "send" with lispm ;;; ;;;Revision 1.6 83/08/31 08:50:09 john ;;; Checked out for compilation only. ;;; ;;;Revision 1.5 83/08/31 08:47:10 john ;;; Improved ct_format to not double-evaluate some of its args. ;;; ;;;Revision 1.4 83/08/30 17:04:46 john ;;; Fix ct_tyi to allow eof option in Franz. ;;; ;;;Revision 1.3 83/08/30 15:38:55 john ;;; Allow use of EOF option for ct_tyi and ct_read. ;;; ;;;Revision 1.2 83/08/30 14:15:21 penny ;;; Fixed ct_format to not evaluate the stream ;;; ;;;Revision 1.1 83/08/30 00:44:36 penny ;;; Initial revision ;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; CTIO ;;; ;;; John Shelton August 1983 ;;; ;;; ;;; ;;; Computer Thought Improved IO Package ;;; ;;; ;;; ;;; This file includes most of the standard io functions (tyi, ;;; ;;; princ, etc.) in ct format. If the object that is supplied for a ;;; ;;; stream is one of some selected flavors, it will be sent a ;;; ;;; message corresponding to the function name. ;;; ;;; ;;; ;;; These functions are defined as (quasi-) exprs (not macros) to ;;; ;;; allow for easy recompilation of everything else. ;;; ;;; ;;; ;;; So far, have done: ;;; ;;; ;;; ;;; princ print prin1 tyo format terpri read tyi freshline skipline. ;;; ;;; ;;; ;;; This file is part of a proprietary software project. Source ;;; ;;; code and documentation describing implementation details are ;;; ;;; available on a confidential, non-disclosure basis only. These ;;; ;;; materials, including this file in particular, are trade secrets ;;; ;;; of Computer * Thought Corporation. ;;; ;;; ;;; ;;; (c) Copyright 1982 and 1983, Computer * Thought Corporation. ;;; ;;; All Rights Reserved. ;;; ;;; ;;; ;;; Reference materials: ;;; ;;; Foderaro and Sklower, The FRANZ LISP Manual, September 1981. ;;; ;;; Weinreb and Moon, LISP MACHINE MANUAL, Symbolics, July 1981. ;;; ;;; Charniak et al., 1980. Artificial Intelligence Programming. ;;; ;;; Miller, 1982. The C*T Ada Tutor: Guide to the Implementation. ;;; ;;; AJPO, Feb 1983. ANSI/MIL-STD-1815A Ada Reference Manual. ;;; ;;; The following code assumes familiarity with these materials. ;;; ;;; ;;; ;;; ASSUMES CT_LOAD AND SUITABLE FILEMAP ;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; **************************************************************** ;;; Ensure presence of needed files. ;;; **************************************************************** (eval-when (compile load eval) (ct_load 'ctstrl)) #+franz (eval-when (compile load eval) (ct_load 'format)) #+franz(eval-when (compile load eval) (ct_load 'readline)) ;;; **************************************************************** ;;; Compiler Declarations and Global Variables -- ;;; **************************************************************** #+franz (declare (macros t)) ;;; Constant definitions, etc. ;;; The list of possible flavors for the stream argument that should ;;; be handled separately. (defconst *ct-redefined-io-function-flavors* '(db%debug_window extesting_stream)) ;;; **************************************************************** ;;; Functions, etc. ;;; **************************************************************** ;;; Tests to see if the "stream" argument should be sent a message ;;; or not. (defun test-stream (stream) (and stream #+lispm (memq (typep stream) *ct-redefined-io-function-flavors*) #+franz (and (instancep stream) (memq (flavor stream) *ct-redefined-io-function-flavors*)))) (defun ct_princ (thing &optional (stream ':not-supplied)) (cond ((test-stream stream) (ct_send stream ':ct_princ thing)) ((eq stream ':not-supplied) (princ thing)) (t (princ thing stream)))) (defun ct_print (thing &optional (stream ':not-supplied)) (cond ((test-stream stream) (ct_send stream ':ct_print thing)) ((eq stream ':not-supplied) (print thing)) (t (print thing stream)))) (defun ct_prin1 (thing &optional (stream ':not-supplied)) (cond ((test-stream stream) (ct_send stream ':ct_prin1 thing)) ((eq stream ':not-supplied) (prin1 thing)) (t (prin1 thing stream)))) (defun ct_tyo (thing &optional (stream ':not-supplied)) (cond ((test-stream stream) (ct_send stream ':ct_tyo thing)) ((eq stream ':not-supplied) (tyo thing)) (t (tyo thing stream)))) (defun ct_terpri (&optional (stream ':not-supplied)) (cond ((test-stream stream) (ct_send stream ':ct_terpri)) ((eq stream ':not-supplied) (terpri)) (t (terpri stream)))) (defun freshline (&optional (stream ':not-supplied)) (cond ((test-stream stream) (ct_send stream ':ct_terpri)) ((eq stream ':not-supplied) (terpri)) (t (terpri stream)))) (defun skipline (&optional (stream ':not-supplied)) (cond ((test-stream stream) (ct_send stream ':ct_terpri) (ct_send stream ':ct_terpri)) ((eq stream ':not-supplied) (terpri) (terpri)) (t (terpri stream) (terpri stream)))) (defun ct_format (stream ctl-string &rest args) (cond ((test-stream stream) #+franz (apply #'<- (cons stream (cons ':ct_format (cons ctl-string args)))) #+lispm (lexpr-send stream :ct_format ctl-string args)) (t (apply #'format (cons stream (cons ctl-string args)))))) (defun ct_read (&optional (stream ':not-supplied) (eof-option ':not-supplied)) (cond ((test-stream stream) (ct_send stream ':ct_read)) ((eq stream ':not-supplied) (read)) ((eq eof-option ':not-supplied) (read stream)) (t (read stream eof-option)))) (defun ct_tyi (&optional (stream ':not-supplied) (eof-option ':not-supplied)) (cond ((test-stream stream) (ct_send stream ':ct_tyi)) ((eq stream ':not-supplied) (tyi)) ((eq eof-option ':not-supplied) (tyi stream)) (t (tyi stream eof-option)))) ;;; A basic incompatibility between LM and Franz peeking #+franz (defun ct_tyipeek (&optional (stream ':not-supplied)) (cond ((test-stream stream) (ct_send stream ':ct_tyipeek)) ((eq stream ':not-supplied) (tyipeek)) (t (tyipeek stream)))) ;;; Force the lispm version to return -1 at end of file. Franz does ;;; this automagically. #+lispm (defun ct_tyipeek (&optional (stream ':not-supplied)) (cond ((test-stream stream) (ct_send stream ':ct_tyipeek)) ((eq stream ':not-supplied) (tyipeek nil nil -1)) (t (tyipeek nil stream -1 )))) ;;; Allows reading up to next line separator in file. #+lispm (defun ct_readline3 (stream) (let (firstch) (setq firstch (ct_send stream 'any-tyi)) (cond ((listp firstch) (ct_readline3 stream)) ;;ignore the mouse click (t (ct_tyo firstch stream) (ct_string_append (implode (cons firstch (read_rest stream))))) ) )) #| ;;; the following code is for rel 4.5 only #+lispm (defun ct_readline2 (stream) (cond ((and (not rubout-handler) (memq ':rubout-handler (funcall stream ':which-operations))) (funcall stream ':rubout-handler '((:pass-through m-l-1) (:do-not-echo #\end)) #'ct_readline2 stream)) (t (do ((ch nil) (quit nil) (len 80) (string (make-array 80 ':type 'art-string)) (idx 0) (first_return t) (end_key nil)) (quit (adjust-array-size string idx) (ct_string_append string #\return)) (setq ch (errset (send stream ':tyi) nil)) (cond ((null ch)) (t (setq ch (car ch)) (ct_if (eq ch #\end) (setq end_key t)) (cond ((or (= ch #\return) (listp ch))) (t (ct_if (= idx len) (adjust-array-size string (setq len (+ len 40)))) (setq first_return nil) (aset ch string idx) (setq idx (1+ idx))) ) (ct_if (or (null ch) end_key (= ch #\cr)) (setq quit t)) )) )))) |# ;;; rel 5 version (defun ct_readline2 (&optional (stream standard-input)) (with-input-editing (stream '((:pass-through m-l-1) (:do-not-echo #\end))) (do ((ch nil) (quit nil) (len 80) (string (make-array 80 ':type 'art-string)) (idx 0) (first_return t) (end_key nil)) (quit (adjust-array-size string idx) (ct_string_append string #\return)) (setq ch (errset (send stream ':tyi) nil)) (cond ((null ch)) (t (setq ch (car ch)) (ct_if (eq ch #\end) (setq end_key t)) (cond ((or (= ch #\return) (listp ch))) (t (ct_if (= idx len) (adjust-array-size string (setq len (+ len 40)))) (setq first_return nil) (aset ch string idx) (setq idx (1+ idx))) ) (ct_if (or (null ch) end_key (= ch #\cr)) (setq quit t)) )) ) )) #+lispm (defun read_rest (stream) (do ((ans nil) (fini nil) (ch nil)) (fini (nreverse ans)) (setq ch (ct_send stream 'any-tyi)) (cond ((listp ch)) ;; ignore the mouse click ((eq ch #\return) (setq fini t)) (t (setq ans (cons ch ans)) (ct_tyo ch stream)) ) )) #+lispm (deff ct_readline 'readline) #+franz (defun ct_readline (&optional (stream ':not-supplied) (eof -1)) (cond ((test-stream stream) (ct_send stream ':ct_readline)) ((memq stream '(:not-supplied t nil)) (int_ct_readline)) (t (readline stream eof)))) ;;; Reads a line from the terminal. #+franz (defun int_ct_readline () (loop with string = "" for char = (tyi) until (memq char '(#\linefeed #\return)) do (cond ((memq char '(#\rubout #\backspace)) (cond ((not (equal string "")) (setq string (ct_substring string 0 (- (string-length string) 2)))))) ((and (< 31. char) (< char 127.)) (setq string (ct_string_append string char))) (t (beep))) finally (return string))) ;;; **************************************************************** ;;; Other functions, etc. ;;; **************************************************************** ;;; Identical to LM version called prin1-then-space. (defun prin1_sp macro (form) ;(thing stream) (selfinsertmacro form `(progn (ct_prin1 ,@(cdr form)) (ct_princ " " ,@(cddr form))))) (defun sp_princ macro (form) (selfinsertmacro form `(progn (ct_princ " " ,@(cddr form)) (ct_princ ,@(cdr form))))) (defun princ_sp macro (form) (selfinsertmacro form `(progn (ct_princ ,@(cdr form)) (ct_princ " " ,@(cddr form))))) (defun nl_indent macro (form) (selfinsertmacro form `(let ((x ,(cadr form))) (declare (fixnum x)) (ct_terpri) (do ((i 1 (1+ i))) ((= i x)) (ct_princ " ")))))