Fix bug #3996: parse_string fails to parse string which contains semicolon
[maxima.git] / archive / src / macdes-prev.lisp
blobd5752ea8856acbc68095a68d7058b8eefe621324
1 ;;; -*- Mode: Lisp; Package: Maxima; Syntax: Common-Lisp; Base: 10 -*- ;;;;
2 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
3 ;;; The data in this file contains enhancments. ;;;;;
4 ;;; ;;;;;
5 ;;; Copyright (c) 1984,1987 by William Schelter,University of Texas ;;;;;
6 ;;; All rights reserved ;;;;;
7 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
9 (in-package "MAXIMA")
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)))
18 (or (probe-file 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))
22 (with-open-file
23 (st file)
24 (sloop with tem
25 while (setq tem (read-char st nil))
27 (cond ((and (eql tem #\&)
28 (eql (setq tem (read-char st nil)) #\&))
29 (cond
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.
39 (progv
40 ;; Protect the user labels and variables
41 ;; from being voerwritten by creating a new
42 ;; binding.
43 (append '($linenum
44 $labels
45 $values)
46 (cdr $labels)
47 (cdr $values))
48 (list 1
49 '((mlist simp))
50 '((mlist simp)))
51 ;; Run the example.
52 (unwind-protect
53 (sloop until
54 (or (null (setq tem (peek-char nil st nil)))
55 (eql tem #\&))
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
63 ;; expression.
64 (set c-label (third expr))
65 (format t "<~d>==>" $linenum)
66 (displa (setq $% (meval* (third expr))))
67 (set d-label $%)
68 (incf $linenum)
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.
77 (mapc #'makunbound
78 (append
79 (cdr $labels)
80 (cdr $values))
81 )))))))))))
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
103 (list'(mlist)
104 $describe_documentation
108 ;(defstruct (describe-index :named (:conc-name index-))
109 ; documentation-file
110 ; entries)
113 (defstruct (describe-index (:type list) :named (:conc-name index-))
114 documentation-file
115 entries)
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))))
135 #+ti
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
140 #-lispm (list nil 8)
141 #+lispm
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))
151 (with-open-file
152 (st file :element-type #+symbolics '(unsigned-byte 8)
153 #-symbolics '(mod 256))
154 (sloop while ch
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.
160 (read-1-char st)
161 (setq ind (file-position st))
162 (setq word (with-output-to-string
163 (strin )
164 (sloop until (zl-MEMBER
165 (progn
166 (setq cha (read-1-char st))
168 '(#\space #\return #\newline nil)
171 (tyo cha strin)
172 finally (if cha (unread-char cha st))
175 collecting (make-entry :string
176 (cond (
177 (array-has-fill-pointer-p word)
178 (subseq word 0
179 (length (the string word))))
180 (t word))
181 :file-pointer ind) into llist
182 finally
183 (print (length llist))
184 (return (make-describe-index
185 :documentation-file
186 (namestring file)
187 :entries llist)))))
189 (defun font-number (ch)
190 (cond ((char> ch #\*) (f- (char-code ch)#. (char-code #\0)))
191 (t 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")
196 :adjustable t
197 ))))
198 (sloop with ch until
199 (eql (setq ch (read-1-char stream)) end-char)
200 do (if (null ch) (loop-finish))
201 (vector-push-extend ch tem))
202 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))
218 while ch
219 do (setq prev-ch ch)
220 #-symbolics
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))
242 #+kcl
243 (or (probe-file file)
244 (and (setq tem (alter-pathname file :directory
245 (append
246 (pathname-directory
247 (pathname si::*system-directory*))
248 (pathname-directory "../doc/"))))
249 (probe-file tem)
250 (setq file tem)
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
266 index-name
267 (lisp:LIST
268 'QUOTE index)))
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)
281 (cond
282 ((eq type :lisp)
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)))
287 #+lispm
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))))
305 answ)))
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)
318 with answ = nil
319 do (sloop for vv in v do (pushnew vv answ :test test))
320 (return answ)))
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))
333 appending
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))
337 do (loop-return t))
338 collecting
339 (cons (index-documentation-file this-ind) u))))
341 (sloop for v in items
342 for i from 0
343 do (format *terminal-io* "~%~3D: ~A" i (key-string (cdr v))))
344 (cond (items
345 (sloop until done
347 (let ((*standard-input* *query-io*))
348 #+lispm(send *query-io* :send-if-handles :fresh-line)
349 #-lispm (terpri)
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)))
358 ((eq zl-some '$all)
359 (setq zl-SOME (sloop for i below
360 (length items)
361 collecting i)))
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)
373 collecting (cdr it))
374 fil :editor editor))
375 (setq done t)))))
376 (t (format t "~%No keys contain the strings ~A" items-to-describe)))
377 '$done)
379 (setf (symbol-function '$apropos) #'$describe)
380 (defun read-documentation (items file &key editor) editor
381 (cond
382 ((null items) nil)
384 (with-open-file (stream file :element-type #+symbolics '(unsigned-byte 8) #-symbolics '(mod 256)
385 ;:byte-size 8.
387 (let ((output (cond #+lispm
388 (editor
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))
399 (sloop while ch
400 when (eql (setq ch(send st :tyi)) *doc-start*)
401 do (setf (fill-pointer *word* )0)
402 (with-output-to-string
403 (strin *word* )
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)))))
415 #+cl
416 (defun get-next-keyword (stream &aux cha (ch 0))
417 (setf (fill-pointer *word*) 0)
418 (sloop while ch when
419 (eql (setq ch (tyi stream )) *doc-start*)
421 (with-output-to-string
422 (strin *word* )
423 (sloop until (zl-MEMBER (setq cha (tyi stream))
424 '(#\space #\return #\newline))
426 (tyo cha strin)
428 (return (values *word*))))
429 #-cl
430 (defun get-next-keyword (stream &aux cha (ch 0))
431 (setf (fill-pointer *word*) 0)
432 (sloop while ch when
433 (eql (setq ch (send stream :tyi)) *doc-start* )
435 (with-output-to-string
436 (strin *word* )
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)
461 ; (memq ch '(#/")
462 ; )))
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)
465 ; (cond (prev-name
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))))))
471 ; (cond (left-over
472 ; (with-output-to-string (str to-string)
473 ; (format str "~A" left-over))))
474 ;; (cond ((setq tem (string-search " " to-string))
475 ;; (show to-string)
476 ;; (setq spaces 20)(setq from-file nil)(setf (fill-pointer to-string) tem)))
477 ; (sloop named sue
478 ; when (> spaces 40)
479 ; do (setq in-white (fill-pointer to-string))
480 ; (cond (from-file
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)
495 ; do
496 ; (incf spaces)
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 )
502 ; (with-open-file
503 ; (st in-file
504 ;; (st "isaac:>wfs>doc.tem")
505 ; (with-open-file (st1 out-file '(:out))
506 ; (sloop ;for i below n
507 ; do
508 ; (multiple-value-setq (next-name left-over)
509 ; (read-from-stream-for-fix st strin next-name left-over ))
510 ; while next-name do
511 ;; (format t "~%~S" next-name)
512 ; (format st1 "~A" strin)
513 ; ))))
514 ;;(do-it *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)))
545 (setq var1 (car l)
546 lis (second l)
547 l (cddr l))
548 (or (symbolp var1) (merror "~a not a symbol" var1))
549 (setq lis (meval* lis))
550 (progv (list var1)
551 (list nil)
552 (cond ((and (numberp lis)
553 (progn
554 (setq top (car l) l (cdr l))
555 (setq top (meval* top))
556 (numberp top)))
557 (sloop for i from lis to top
558 nodeclare t
559 do (set var1 i)
560 append
561 (apply 'create-list1
562 form l)))
563 (($listp lis)
564 (sloop for v in (cdr lis)
565 do (set var1 v)
566 append
567 (apply 'create-list1
568 form l)
570 (T (merror "BAD ARG")))))))