1 ;;; -*- Mode: Lisp; Package: Maxima; Syntax: Common-Lisp; Base: 10 -*- ;;;;
2 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
3 ;;; The data in this file contains enhancments. ;;;;;
5 ;;; Copyright (c) 1984,1987 by William Schelter,University of Texas ;;;;;
6 ;;; All rights reserved ;;;;;
7 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
11 (defconstant *doc-start
* (code-char 31))
13 (defun $example
(item &optional
(file
14 (merge-pathnames "manual.demo"
15 $describe_documentation
))
17 (and (symbolp file
) (setq file
(stripdollar file
)))
19 (return-from $example
"Please supply a file name as the second arg"))
20 (and (symbolp item
) (setq item
(symbol-name item
))
21 (setq item
(subseq item
1))
25 while
(setq tem
(read-char st nil
))
27 (cond ((and (eql tem
#\
&)
28 (eql (setq tem
(read-char st nil
)) #\
&))
30 ((and (symbolp (setq tem
(read st nil
)))
31 (string-search item
(symbol-name tem
)))
32 (format t
"~%Examples for ~a :~%" tem
)
33 ;; This code fulls maxima into thinking that it just
34 ;; started, by resetting the values of the special
35 ;; variables $labels and $linenum to their initial
36 ;; values. They will be reset just after $example
37 ;; is done. The d-labels will also not be disturbed
38 ;; by calling example.
40 ;; Protect the user labels and variables
41 ;; from being voerwritten by creating a new
54 (or (null (setq tem
(peek-char nil st nil
)))
56 for expr
= (mread st nil
)
58 (let ($display2d
) (displa (third expr
)))
59 ;; Make the c-label and d-label.
60 (let ((c-label (makelabel $inchar
))
61 (d-label (makelabel $outchar
)))
62 ;; Set the c-label to the input
64 (set c-label
(third expr
))
65 (format t
"<~d>==>" $linenum
)
66 (displa (setq $%
(meval* (third expr
))))
70 ;; Clean-up form, which will be
71 ;; evaluated even if an error occurs,
72 ;; because of unwind-protect. Kill
73 ;; all labels and values used the
74 ;; example. This is harmless, because
75 ;; the local binding established with
76 ;; progv is in effect.
84 (eval-when (compile eval load
)
86 (defvar *pdp-describe
* t
"The file positioning is not so good for
87 pdp type servers, because of character translation so we index more carefully.
88 This should be ok for any file system")
90 ;;this should really be in "macsyma-source:macsyma;macsym.doc" but I don't
91 ;;want to copy it for here
94 (defmvar $describe_documentation
#+lispm
95 "maxima-documentation:maxima;macsym.doc"
96 #-lispm
"/usr/public/maxima/doc/macsym.doc"
97 "This is the name of the main macsyma documentation file")
101 ;;keep documentation on logical host maxima-documentation
102 (defmvar $all_macsyma_documentation
104 $describe_documentation
108 ;(defstruct (describe-index :named (:conc-name index-))
113 (defstruct (describe-index (:type list
) :named
(:conc-name index-
))
117 (defun make-entry (&key string file-pointer
)
118 (cons string file-pointer
))
120 (defmacro key-string
(x) `(car ,x
))
122 (defmacro key-file-pointer
(x) `(cdr , x
))
124 ;;The following assumes that :set-pointer will do something reasonable as
125 ;;it does currently under chaos. When and if we switch to tcp that will create
126 ;;problems. The reasonable strategy is then to switch to a line number
127 ;;index and use a number of smaller files. It took 37 seconds to read
128 ;;once through the documentation file using tcp on the r20.
130 (defmacro read-1-char
(st)
131 `(let ((tem (read-byte ,st nil nil
)))
132 (if tem
(code-char tem
))))
136 (defun file-position (a &optional b
)
137 (if b
(send a
:set-pointer b
) (send a
:read-pointer
)))
139 (defun file-options (pathname) pathname
142 (case (send (send pathname
:host
) :system-type
)
143 (:lispm
(list nil
8))
144 (:tops-20
(error " can't use any more")(list nil
7))
145 (t (format t
"~%Assuming byte-size 8 for making index") (list nil
8) )))
147 (defun index-file ( file
&aux
148 word
(ch 0) cha fil options ind
)
149 (setq fil
(probe-file file
))
150 (setq options
(file-options fil
))
152 (st file
:element-type
#+symbolics
'(unsigned-byte 8)
153 #-symbolics
'(mod 256))
155 when
(eql (setq ch
(read-1-char st
)) *doc-start
* )
157 ;;the first character after *doc-start* is used to say what
158 ;;kind of documentation this is. This is compatible with
159 ;;the gnu doc string files.
161 (setq ind
(file-position st
))
162 (setq word
(with-output-to-string
164 (sloop until
(zl-MEMBER
166 (setq cha
(read-1-char st
))
168 '(#\space
#\return
#\newline nil
)
172 finally
(if cha
(unread-char cha st
))
175 collecting
(make-entry :string
177 (array-has-fill-pointer-p word
)
179 (length (the string word
))))
181 :file-pointer ind
) into llist
183 (print (length llist
))
184 (return (make-describe-index
189 (defun font-number (ch)
190 (cond ((char> ch
#\
*) (f- (char-code ch
)#.
(char-code #\
0)))
193 (defun line-in (stream buffer end-char
)
194 (let ((tem (or buffer
195 (make-array 70 :fill-pointer
0 :element-type
' #.
(array-element-type "abc")
199 (eql (setq ch
(read-1-char stream
)) end-char
)
200 do
(if (null ch
) (loop-finish))
201 (vector-push-extend ch tem
))
206 (defun read-item (stream file-pos
&key
(up-to *doc-start
*) item
(out-stream *standard-output
*) &aux
(prev-ch) (ch 0) lin
)
207 ;;have to set pointer to 0 for non lispm server.
208 (cond ( *pdp-describe
* (file-position stream
0)))
209 (file-position stream file-pos
)
210 (setq lin
(line-in stream nil
#\newline
))
211 (cond ((and item
(null (string-search item lin
))
212 (y-or-n-p "~%Bad index file. Try making a new one?"))
213 (set-up-index (pathname stream
) :make-new-one t
)
214 (error "now start over"))
215 (t (format out-stream
"~%~A~%" lin
)))
216 (sloop until
(and (eql (setq ch
(read-1-char stream
)) ;(send stream :tyi))
217 up-to
) (eql prev-ch
#\newline
))
221 (cond ((char= ch
#\
\x06)
222 (send stream
:set-current-font
(setq prev-ch
(tyi stream
)))))
223 (tyo ch out-stream
) ; (send out-stream :tyo ch)
226 (defvar *describe-indices
* nil
)
227 ;;convention:use the same name for the documentation file as the index-name
228 (defun add-to-describe-indices (index-name describe-index
&aux tem
)
229 (declare (special *index-path
*))
230 (setq index-name
(string-downcase index-name
))
231 (and (boundp '*index-path
*)
232 (setf (index-documentation-file describe-index
)
233 (alter-pathname *index-path
* :name index-name
:type
"doc")))
234 (cond ((setq tem
(zl-MEMBER index-name
*describe-indices
*))
235 (setf (second tem
) describe-index
))
236 (t (push describe-index
*describe-indices
*)
237 (push index-name
*describe-indices
*))))
239 (defun set-up-index (file &key write-file-name make-new-one
240 &aux index-name index tem
)
241 (setq file
(pathname file
))
243 (or (probe-file file
)
244 (and (setq tem
(alter-pathname file
:directory
247 (pathname si
::*system-directory
*))
248 (pathname-directory "../doc/"))))
253 ; (setq index-name (string-upcase (pathname-name file)))
254 (cond ((null write-file-name
)
255 (setq write-file-name
256 (format nil
"~a~a-index.~a"
257 *describe-index-directory
*
258 (pathname-name file
) *index-file-type
*)))
259 (t (setq write-file-name
(alter-pathname write-file-name
:type
*index-file-type
*))))
260 (cond ((or make-new-one
(null (probe-file write-file-name
)))
261 (format t
"~%Having to make a new index...")
262 (setq index
(index-file file
))
263 (add-to-describe-indices index-name index
)
264 (write-forms-to-file write-file-name
265 (lisp:LIST
(lisp:LIST
'add-to-describe-indices
269 :in-package
"MAXIMA" :type
*index-file-type
*))
271 (let ((*index-path
* write-file-name
))
272 (declare (special *index-path
*))
273 (load write-file-name
)))))
278 (defun write-forms-to-file
279 (file-name forms
&key
280 ( in-package
*package
*) (type :lisp
) &aux
#+lispm tem
)
283 (with-open-file (st (alter-pathname file-name
:type
"LISP") :direction
:output
)
284 (format st
";;; - * - Mode:Lisp; Package:~A;Syntax:common-lisp - * -~%" in-package
)
285 (format st
"~%(in-package \"~a\")~%" in-package
)
286 (prin1 (cons 'progn forms
) st
) (pathname st
)))
288 ((member type
'(:bin
:xfasl
))
289 (si::dump-forms-to-file
(setq tem
(alter-pathname file-name
:type type
))
290 forms
(list :package in-package
)) tem
)))
293 (defmvar *index-file-type
* :lisp
)
295 (defvar *describe-index-directory
* #-lispm
"/usr/public/maxima/doc/"
296 #+lispm
"cl-maxima-object:maxima;")
299 (defun cl-string (zl-string &aux
(leng (length zl-string
)) answ
)
300 (cond ((and (> leng
0)
301 (not (integerp(aref zl-string
0)))) zl-string
)
302 (t (setq answ
(make-array leng
:element-type
' #.
(array-element-type "abc")))
303 (sloop for i below leng
304 do
(setf (aref answ i
) (code-char (aref zl-string i
))))
307 (defun add-main-macsyma-documentation ( &aux file-name
)
308 (sloop for v in
(cdr $all_macsyma_documentation
)
310 (setq file-name
(pathname v
) )
311 (cond ((not (MEMBER (pathname-name file-name
)
312 *describe-indices
* :test
'equalp
))
313 (set-up-index file-name
)))))
315 (defun maxima-union (&rest lists
&aux test
)
316 (setq test
(or (second (memq :test lists
)) #'eq
))
317 (sloop for v in lists until
(eql v
:test
)
319 do
(sloop for vv in v do
(pushnew vv answ
:test test
))
322 (defun $describe
( items-to-describe
&key editor
323 (index-names 'use-all
)
324 &aux items done zl-SOME all-files
)
325 (cond ((not (consp items-to-describe
))
326 (setq items-to-describe
(list items-to-describe
))))
327 (setq items-to-describe
(sloop for v in items-to-describe
328 collecting
(string-trim "&$" v
)))
329 (add-main-macsyma-documentation)
330 (setq items
(sloop for
(name this-ind
) on
*describe-indices
* by
'cddr
331 when
(or (eq index-names
'use-all
)
332 (zl-MEMBER name index-names
))
334 (sloop for u in
(index-entries this-ind
)
335 when
(sloop for v in items-to-describe
336 when
(string-search v
(car u
))
339 (cons (index-documentation-file this-ind
) u
))))
341 (sloop for v in items
343 do
(format *terminal-io
* "~%~3D: ~A" i
(key-string (cdr v
))))
347 (let ((*standard-input
* *query-io
*))
348 #+lispm
(send *query-io
* :send-if-handles
:fresh-line
)
350 (format *query-io
* "Enter a number, or a Maxima list of numbers, all or none:")
351 ; (setq zl-SOME (mread-noprompt ))
352 (setq zl-SOME
(let ((*mread-prompt
* ""))
353 (dbm-read *standard-input
* nil nil
)))
354 (print (list 'zl-some zl-some
))
356 (cond ((atom zl-SOME
)
357 (cond ((numberp zl-SOME
) (setq zl-SOME
(list zl-SOME
)))
359 (setq zl-SOME
(sloop for i below
362 ((eq '$none zl-some
) (setq zl-SOME nil
))))
363 (($listp zl-SOME
)(setq zl-SOME
(cdr zl-SOME
))))
364 (cond ((null zl-SOME
) (setq done t
))
365 ((numberp (car zl-SOME
))
366 (setq items
(sloop for i in zl-SOME
367 collecting
(nth i items
)))
368 (setq all-files
(maxima-union (mapcar 'car items
) :test
'equalp
))
369 (sloop for fil in all-files
370 do
(read-documentation
371 (sloop for it in items
372 when
(equal (car it
) fil
)
376 (t (format t
"~%No keys contain the strings ~A" items-to-describe
)))
379 (setf (symbol-function '$apropos
) #'$describe
)
380 (defun read-documentation (items file
&key editor
) editor
384 (with-open-file (stream file
:element-type
#+symbolics
'(unsigned-byte 8) #-symbolics
'(mod 256)
387 (let ((output (cond #+lispm
389 (zwei::REST-OF-INTERVAL-STREAM
(zwei::POINT
)))
390 (t *standard-output
*))))
391 (sloop for v in items
392 do
(read-item stream
(cdr v
)
393 :out-stream output
:item
(car v
))))))))
396 (defun search-file ( expr
&optional
(file $describe_documentation
) &aux
(ch 0) cha leng
)
397 (with-open-file (st file
)
398 (setq leng
(send st
:length
))
400 when
(eql (setq ch
(send st
:tyi
)) *doc-start
*)
401 do
(setf (fill-pointer *word
* )0)
402 (with-output-to-string
404 (sloop until
(zl-MEMBER (setq cha
(send st
:tyi
))
405 '(#\space
#\return
#\newline nil
))
407 (send strin
:tyo cha
)))
409 when
(string-search expr
*word
*)
411 (sloop while cha until
(eql (setq cha
(send st
:tyi
)) *doc-start
*)
413 (send *standard-output
* :tyo cha
)))))
416 (defun get-next-keyword (stream &aux cha
(ch 0))
417 (setf (fill-pointer *word
*) 0)
419 (eql (setq ch
(tyi stream
)) *doc-start
*)
421 (with-output-to-string
423 (sloop until
(zl-MEMBER (setq cha
(tyi stream
))
424 '(#\space
#\return
#\newline
))
428 (return (values *word
*))))
430 (defun get-next-keyword (stream &aux cha
(ch 0))
431 (setf (fill-pointer *word
*) 0)
433 (eql (setq ch
(send stream
:tyi
)) *doc-start
* )
435 (with-output-to-string
437 (sloop until
(zl-MEMBER (setq cha
(send st
:tyi
))
438 '(#\space
#\return
#\newline
))
440 (send strin
:tyo cha
)))
441 (return (values *word
*))))
447 (defun mread-noprompt (&rest read-args
)
448 (let ((*mread-prompt
* ""))
449 (declare (special *mread-prompt
*))
450 (or read-args
(setq read-args
(list *query-io
*)))
451 (caddr (apply #'mread read-args
))))
454 ;;;some functions for converting from the DOE style documentation file
455 ;;;to the type we use. DO-IT is the function that does it.
456 ;;in our documentation files the key always follows a a \n *doc-start*
459 ;(defun my-alphabetp (ch)
460 ; (or (maxima:alphabetp ch)
463 ;(defun read-from-stream-for-fix (stream to-string prev-name left-over &aux (from-file t) in-white info (spaces 0) tem eof ch)
464 ; (setf (fill-pointer to-string) 0)
466 ; (with-output-to-string (str to-string)
467 ; (cond ((and left-over (> (length (the string left-over)) 0)
468 ; (eql (aref left-over 0) #/())
469 ; (format str "~%~%&~s" prev-name))
470 ; (t (format str "~%~%&~s " prev-name))))))
472 ; (with-output-to-string (str to-string)
473 ; (format str "~A" left-over))))
474 ;; (cond ((setq tem (string-search " " to-string))
476 ;; (setq spaces 20)(setq from-file nil)(setf (fill-pointer to-string) tem)))
479 ; do (setq in-white (fill-pointer to-string))
481 ; (sloop with past-space
482 ; while (setq ch (send stream :tyi))
483 ; do (vector-push-extend ch to-string)
484 ; until (memq ch '(#\linefeed #\newline))
485 ; when (not (eql ch #\space))
486 ; do(setq past-space t)
487 ; until (and past-space (eql ch #\space))))
488 ; (t (setq from-file t)))
489 ; (multiple-value-bind (answ left-over end) (check-for-end to-string in-white)
490 ; (cond (answ (setf (fill-pointer to-string) end)
491 ; (return-from sue (values answ left-over)))))
492 ; while (setq ch (send stream :tyi))
493 ; do (vector-push-extend ch to-string)
494 ; when (eql ch #\space)
497 ; else do (setq spaces 0)))
499 ;;;for copying documentation file
501 ;(defun do-it (strin in-file out-file &aux next-name left-over )
504 ;; (st "isaac:>wfs>doc.tem")
505 ; (with-open-file (st1 out-file '(:out))
506 ; (sloop ;for i below n
508 ; (multiple-value-setq (next-name left-over)
509 ; (read-from-stream-for-fix st strin next-name left-over ))
511 ;; (format t "~%~S" next-name)
512 ; (format st1 "~A" strin)
515 ;(defvar *strin* (make-array 100 :type 'art-string :fill-pointer 0))
517 ;(defun not-white-space-p (n) (cond ((not (memq n '(#\space #\newline ))) n)))
518 ;(defun advance-over-white-space (string start &optional reversep &aux ch )
519 ; (cond (reversep (sloop for i downfrom start to 0
520 ; until (setq ch (not-white-space-p (aref string i)))
521 ; finally (return (and ch (add1 i)))))
522 ; (t (sloop for i from start below (length (the string string))
523 ; until (setq ch (not-white-space-p (aref string i)))
524 ; finally (return (and ch i))))))
525 ;(defun read-atom-from-string (string start)
526 ; (declare (values contents end-char-position))
527 ; (condition-case (condit)
528 ; (progn (read-from-string string nil start))
529 ; (sys:read-package-not-found nil)))
533 ;; Some list creation utilities.
536 (defmacro $create_list
(form &rest l
)
537 `(create-list2 ',form
',l
))
539 (defun create-list2 (form l
)
540 (cons '(mlist) (apply 'create-list1 form l
)))
542 (defun create-list1(form &rest l
&aux lis var1 top
)
543 (cond ((null l
)(list (meval* form
)))
548 (or (symbolp var1
) (merror "~a not a symbol" var1
))
549 (setq lis
(meval* lis
))
552 (cond ((and (numberp lis
)
554 (setq top
(car l
) l
(cdr l
))
555 (setq top
(meval* top
))
557 (sloop for i from lis to top
564 (sloop for v in
(cdr lis
)
570 (T (merror "BAD ARG")))))))