home *** CD-ROM | disk | FTP | other *** search
- ;;; (C) Copyright 1984 by Gold Hill Computers
-
- ;;; This file contains functions that support online documentation
-
- ;; reads a floating point number from the stream
- (DEFUN READ-NUM (STREAM)
- (LET ((N (COERCE 0 'SHORT-FLOAT))) ; cons a number
- (MULTIPLE-VALUE-BIND (O S) (%POINTER N)
- (%CONTENTS-STORE S (+ 1 O) (READ-BYTE STREAM) NIL)
- (%CONTENTS-STORE S (+ 2 O) (READ-BYTE STREAM) NIL)
- (%CONTENTS-STORE S (+ 3 O) (READ-BYTE STREAM) NIL)
- (%CONTENTS-STORE S (+ 4 O) (READ-BYTE STREAM) NIL))
- N))
-
-
- ;; The Common Lisp documentation function
-
- (DEFUN DOCUMENTATION (SYM TYPE)
- (LET ((HASH-STREAM (WITH-DISKETTE *DOCUMENT-DISKETTE*
- #'HASH-TABLE-OPEN
- (MERGE-PATHNAMES *DOC-FILE-PATHNAME*
- *DOCUMENT-PATHNAME*))))
- (UNWIND-PROTECT
- (LET ((DOC (GETF (SEND HASH-STREAM :SEARCH SYM TYPE) :DOC)))
- (IF (NOT (LISTP DOC))
- DOC
- (IF (<= (LENGTH DOC) 60)
- (APPLY #'STRING-APPEND DOC)
- (LET ((LEN (DO ((I DOC (CDR I))
- (SZ 0 (+ SZ (LENGTH (CAR I)))))
- ((NULL I) SZ)))
- AR I)
- (SETQ AR (MAKE-ARRAY LEN :ELEMENT-TYPE 'STRING-CHAR
- :FILL-POINTER 0))
- (DOLIST (STRG DOC)
- (DOTIMES (I (LENGTH STRG))
- (VECTOR-PUSH (CHAR STRG I) AR)))
- AR))))
- (CLOSE HASH-STREAM))))
-
-
- ;; for retrieving a particular doc type
- ;; RETURN-LIST: (DOC FOUNDP)
- ;; If TYPE is *, the doc entry in returned, it is an alist
- ;; for the particular function. The key is the type of documentation
- ;; and the rest is a plist of options for that doc type:
- ;; ((<type1> . <doc-plist1>)
- ;; eg for CAR:
- ;; ((FUNCTION :ARGUMENTS (LIST) :VALUES (OBJECT) :ONLINE-DOC <string>))
- ;;
- (DEFUN DOC (X &OPTIONAL TYPE)
-
- ;; we open the hash table with the name on *DOC-FILE-PATHNAME*
-
- (LET ((HASH-STREAM (WITH-DISKETTE *DOCUMENT-DISKETTE*
- #'HASH-TABLE-OPEN
- (MERGE-PATHNAMES *DOC-FILE-PATHNAME*
- *DOCUMENT-PATHNAME*)))
- DOC FOUNDP ARGLIST RETURN-LIST)
-
- (UNWIND-PROTECT
- (PROGN
-
- ;; we retrieve the hash table entry with only one keyword x
-
- (MULTIPLE-VALUE-SETQ (DOC FOUNDP)
- (FUNCALL HASH-STREAM :SEARCH X))
-
- (IFN FOUNDP
- (FORMAT T "~%No documentation found for ~A~%" X)
- (IF (AND TYPE (ASSOC TYPE DOC))
- (DOC-PRINT X (ASSOC TYPE DOC))
- (DOLIST (I DOC) (DOC-PRINT X I)))
- ))
-
- (FUNCALL HASH-STREAM :CLOSE))))
-
-
-
- ;; This function examines the entry, extracts the information associated
- ;; with :arguments, :values and :doc of the entry.
-
- (DEFUN DOC-PRINT (SYM ENTRY)
- (LET ((TYPE (FIRST ENTRY))
- (TEMP)
- (*PRINT-LENGTH* NIL)
- (*PRINT-LEVEL* NIL)
- (DOC (REST ENTRY)))
- (FORMAT T "~&~%~S is a ~S." SYM TYPE)
-
- (WHEN (MEMBER TYPE '(SPECIAL-FORM FUNCTION MACRO))
- (IF (CONSP (SETQ TEMP (GETF DOC :ARGUMENTS)))
- (WHEN (EQ (CAR (GETF DOC :ARGUMENTS)) '@TOO-LONG)
- (POP TEMP))
- (WHEN TEMP (SETQ TEMP (NCONS TEMP))))
- (FORMAT T "~%~@[~A~]" (CONS SYM TEMP))
-
- (WHEN (SETQ TEMP (GETF DOC :VALUES))
- (FORMAT T " -> ")
- (IF (OR (ATOM TEMP) (= (LENGTH TEMP) 1))
- (FORMAT T "~S" (IF (ATOM TEMP) TEMP (FIRST TEMP)))
- (DOLIST (I TEMP) (FORMAT T "~S " I))))
- )
-
- (IF (LISTP (SETQ TEMP (GETF DOC :DOC)))
- (DOLIST (I TEMP) (FORMAT T "~A" I))
- (FORMAT T "~A" TEMP)))
- (TERPRI T))
-
- ;; given a symbol name, we check whether it is of the functional form.
- ;; If yes, we will search the doc-file and returns 2 values:
- ;; LAMBDA-LIST, NOT-FOUND-P
-
- (DEFUN LAMBDA-LIST (X &OPTIONAL DONT-SEARCH &AUX I)
- (COND ((NOT (FBOUNDP X)) (VALUES NIL :NOT-FOUND))
-
- ((LISTP (SETQ I (SYMBOL-FUNCTION X)))
- (VALUES (CASE (CAR I)
- (LAMBDA (CADR I))
- (MACRO (CADDR I)))
- NIL))
- (DONT-SEARCH
- (VALUES NIL :NOT-FOUND))
- (T
- (LET ((HASH-STREAM (WITH-DISKETTE *DOCUMENT-DISKETTE*
- #'HASH-TABLE-OPEN
- (MERGE-PATHNAMES *DOC-FILE-PATHNAME*
- *DOCUMENT-PATHNAME*)))
- ARGLIST FOUNDP)
-
- (SETF (VALUES ARGLIST FOUNDP)
- (FUNCALL HASH-STREAM :SEARCH X '(FUNCTION MACRO SPECIAL-FORM)))
- (FUNCALL HASH-STREAM :CLOSE)
- (IF (AND FOUNDP
- (NOT (EQ (SETQ ARGLIST (GETF ARGLIST :ARGUMENTS :NO-ARGS))
- :NO-ARGS)))
- (VALUES ARGLIST NIL)
- (VALUES NIL :NOT-FOUND))))))
-
-
- ;;***************************************************************************
- ;;
- ;; VERSION 1.0 09/11/84
- ;;
- ;; 1) HASH-TABLE-OPEN &option <file-name>
- ;;
- ;; this procedure will open a hash table and allow user to refer
- ;; the hash table as a stream.
- ;;
- ;; Example: (let ((hash-stream (HASH-TABLE-OPEN "personal"))
- ;;
- ;; 2) Funcall <stream-name> :SEARCH <keyword 1> &optional <keyword 2>
- ;;
- ;; this procedure retrieves an entry in the hash table with
- ;; <keyword 1> as its key. The returned result will have
- ;; the key deleted. For more explanation see the following
- ;; two cases.
- ;;
- ;; <keyword 2> is optional. If supplied, it is used slightly
- ;; differntly in the following 2 different cases:
- ;;
- ;; case a)
- ;; if each entry is of the form:
- ;;
- ;; ( (<key1> <property 1> <value>...<property n> <value n>)
- ;; :
- ;; :
- ;; (<key m> <property 1> <value>...<property g> <value g>) )
- ;;
- ;; <keyword 1> will be used to assoc the right list
- ;; (<keyword i> <property 1> <value 1>...<prop d> <value d>)
- ;; from the hash tabke entry. <keyword 2> will be used as
- ;; the property keyword to obtain the appropiate value. The
- ;; value will be returned.
- ;;
- ;; case b) if each hash table entry is of the form:
- ;;
- ;; ((<key1> (<key11> a b c...) (<key12>...) ...)
- ;; (<key2> (<key21>...) (<key22>...) ...)
- ;; :
- ;; (<keym> (<keym1>...) (<keym2>...) ...) )
- ;;
- ;; and suppose <keyword 1> = <key1> and <keyword2> = <key2>
- ;; the function call will return (a b c ...).
- ;;
- ;;
- ;; 3) FUNCALL <stream-name> :close
- ;;
- ;; this command will close the file associated with the hash table
- ;; stream.
- ;;
- ;;*****************************************************************************
- ;;
- ;;
- ;; HASH-TABLE-OPEN is used to open a hash table. The pathname the user
- ;; supplies will be merged with the value of *DOCUMENT-PATHNAME*.
- ;; The file stream will be used as part of the returned closure that
- ;; will process subsequent commands to the hash table (e.g. :SEARCH,
- ;; :CLOSE).
-
-
-
- (defun HASH-TABLE-OPEN (file-name)
- (let (final-pathname table-size)
-
- ;; we first compute the name of the hash table
-
- (setf final-pathname (pathname file-name))
-
- ;; we return the hash-stream handler with the hash-table enclosed
-
- (let* ((hash-stream (open final-pathname
- :element-type 'unsigned-byte
- :direction :input))
- (table-size (logior (read-byte hash-stream)
- (lsh (read-byte hash-stream) 8))))
-
- (closure '(hash-stream table-size) 'hash-stream-handler))))
-
-
- ;; the hash-stream-handler is called by user in the form indicated in the
- ;; documentation at the beginning of the file
-
-
- (defun HASH-STREAM-HANDLER (command &optional key-1 keyword-2)
- (let (idx entry keyword-1)
- (cond ((equal command :close) (close hash-stream))
- ((equal command :search)
-
- ;; we are getting ready to read the pointer from hash table
- (let (temp)
- ;; due to the way BUILD-DEFINITIONS handles string key
- (setf keyword-1 (if (stringp key-1) (intern key-1)
- key-1))
- (setf temp (+ 2 (* 4 (\\ (sxhash keyword-1) table-size))))
- (funcall hash-stream :set-pointer temp)
- (setf idx (read-num hash-stream))
-
- ;; set the stream pointer to the real entry
- (when (not (zerop idx)) (funcall hash-stream
- :set-pointer idx))
- (if (zerop idx)
- (values nil nil)
- (progn
- (setf entry (assoc keyword-1 (read hash-stream)))
- (if keyword-2
- (dble-srch (rest entry) keyword-2)
- (values (rest entry) (if entry t nil)))
- )))))))
-
-
- ;; dble assume that an entry has been retrieved with the encoded key deleted.
- ;; the routine will use the next keyword to locate the proper property or the
- ;; sublist mdepending on the form of the entry is of the form:
- ;; (property1 value1 property2 value2 ... ) or
- ;; ((key1 ...) (key2 ...) ...)
- ;; In the second case, the second input can be either an atom or a list
-
- (defun dble-srch (trunc-entry keyword &aux result)
- (if (null trunc-entry)
- (values nil nil)
- (if (atom (first trunc-entry))
-
- ;; in the case where the form is of the form of a property list
- ;; we check whether the keyword parameter is of the form of a list
-
- (if (atom keyword)
-
- (values (setf result (getf trunc-entry keyword))
- (if result t nil))
-
- (dolist (each-key keyword (values nil nil))
- (if (setf result (getf trunc-entry each-key))
- (return (values result t)))))
-
- ;; in this case,the truncated form is of the form of an a-list
-
- (if (atom keyword)
-
- (values (rest (setf result (assoc keyword trunc-entry)))
- (if result t nil))
-
- (dolist (each-key keyword (values nil nil))
- (if (setf result (assoc each-key trunc-entry))
- (return (values (rest result) t)))))
-
- )))