1;; Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd. 2;; All rights reserved. 3;; 4;; Redistribution and use in source and binary forms, with or without 5;; modification, are permitted provided that the following conditions are 6;; met: 7;; 8;; - Redistributions of source code must retain the above copyright 9;; notice, this list of conditions and the following disclaimer. 10;; 11;; - Redistributions in binary form must reproduce the above copyright 12;; notice, this list of conditions and the following disclaimer in 13;; the documentation and/or other materials provided with the 14;; distribution. 15;; 16;; - Neither the name of The Numerical ALgorithms Group Ltd. nor the 17;; names of its contributors may be used to endorse or promote products 18;; derived from this software without specific prior written permission. 19;; 20;; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 21;; IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 22;; TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 23;; PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 24;; OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 25;; EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 26;; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 27;; PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 28;; LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 29;; NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 30;; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 32#| 33This file is a collection of utility functions that are useful 34for system level work. {\bf build-interpsys} interfaces to the 35src/interp/Makefile. 36 37A fifth group of related functions are some translated boot 38functions we need to define here so they work and are available 39at load time. 40|# 41(in-package "BOOT") 42(export '($spadroot $directory-list reroot 43 make-absolute-filename |$defaultMsgDatabaseName|)) 44 45;;; Various lisps use different ``extensions'' on the filename to indicate 46;;; that a file has been compiled. We set this variable correctly depending 47;;; on the system we are using. 48(defvar |$lisp_bin_filetype| 49 #+:GCL "o" 50 #+lucid "bbin" 51 #+symbolics "bin" 52 #+:cmu (c:backend-fasl-file-type c:*target-backend*) 53 #+:sbcl "fasl" 54 #+:clisp "fas" 55 #+:openmcl (subseq (namestring CCL:*.FASL-PATHNAME*) 1) 56 #+:ecl "fas" 57 #+:lispworks (pathname-type (compile-file-pathname "foo.lisp")) 58 #+:poplog "lsp" 59 ) 60 61;;; The relative directory list specifies a search path for files 62;;; for the current directory structure. 63(defvar $relative-directory-list 64 '("/share/msgs/" 65 "/share/spadhelp/" )) 66 67;;; The relative directory list specifies how to find the algebra 68;;; directory from the current {\bf FRICAS} shell variable. 69(defvar $relative-library-directory-list '("/algebra/")) 70 71;;; This is the system-wide list of directories to search. 72;;; It is set up in the {\bf reroot} function. 73(defvar $directory-list ()) 74 75;;; This is the system-wide search path for library files. 76;;; It is set up in the {\bf reroot} function. 77(defvar $library-directory-list ()) 78 79;;; Prefix a filename with the {\bf FRICAS} shell variable. 80(defun make-absolute-filename (name) 81 (concatenate 'string $spadroot name)) 82 83#| 84The reroot function is used to reset the important variables used by 85the system. In particular, these variables are sensitive to the 86{\bf FRICAS} shell variable. That variable is renamed internally to 87be {\bf \$spadroot}. The {\bf reroot} function will change the 88system to use a new root directory and will have the same effect 89as changing the {\bf FRICAS} shell variable and rerunning the system 90from scratch. A correct call looks like: 91\begin{verbatim} 92(in-package "BOOT") 93(reroot "${FRICAS}") 94\end{verbatim} 95where the [[${FRICAS}]] variable points to installed tree. 96|# 97(defun reroot (dir) 98 (setq $spadroot dir) 99 (setq $directory-list 100 (mapcar #'make-absolute-filename $relative-directory-list)) 101 (setq $library-directory-list 102 (mapcar #'make-absolute-filename $relative-library-directory-list)) 103 (setq |$defaultMsgDatabaseName| 104 (pathname (make-absolute-filename "/share/msgs/s2-us.msgs"))) 105 ) 106 107;;; Sets up the system to use the {\bf FRICAS} shell variable if we can 108;;; and default to the {\bf \$spadroot} variable (which was the value 109;;; of the {\bf FRICAS} shell variable at build time) if we can't. 110;;; Use the parent directory of FRICASsys binary as fallback. 111(defun initroot (&optional (newroot nil)) 112 (reroot (or (|getEnv| "FRICAS") newroot 113 (if (|fricas_probe_file| $spadroot) $spadroot) 114 (let ((bin-parent-dir 115 (concatenate 'string 116 (directory-namestring (car (|getCLArgs|))) 117 "/../"))) 118 (if (|fricas_probe_file| (concatenate 'string bin-parent-dir 119 "algebra/interp.daase")) 120 bin-parent-dir)) 121 (error "setenv FRICAS or (setq $spadroot)")))) 122 123;;; Gnu Common Lisp (GCL) (at least 2.6.[78]) requires some changes 124;;; to the default memory setup to run FriCAS efficiently. 125;;; This function performs those setup commands. 126(defun init-memory-config (&key 127 (cons 500) 128 (fixnum 200) 129 (symbol 500) 130 (package 8) 131 (array 400) 132 (string 500) 133 (cfun 100) 134 (cpages 3000) 135 (rpages 1000) 136 (hole 2000) ) 137 ;; initialize GCL memory allocation parameters 138 #+:GCL 139 (progn 140 (system:allocate 'cons cons) 141 (system:allocate 'fixnum fixnum) 142 (system:allocate 'symbol symbol) 143 (system:allocate 'package package) 144 (system:allocate 'array array) 145 (system:allocate 'string string) 146 (system:allocate 'cfun cfun) 147 (system:allocate-contiguous-pages cpages) 148 (system:allocate-relocatable-pages rpages) 149 (system:set-hole-size hole)) 150 #-:GCL 151 nil) 152 153#| 154;############################################################################ 155;# autoload dependencies 156;# 157;# if you are adding a file which is to be autoloaded the following step 158;# information is useful: 159;# there are 2 cases: 160;# 1) adding files to currently autoloaded parts 161;# (as of 2/92: browser old parser and old compiler) 162;# 2) adding new files 163;# case 1: 164;# a) you have to add the file to the list of files currently there 165;# (e.g. see BROBJS above) 166;# b) add an autolaod rule 167;# (e.g. ${AUTO}/parsing.${O}: ${OUT}/parsing.${O}) 168;# c) edit util.lisp to add the 'external' function (those that 169;# should trigger the autoload 170;# case 2: 171;# build-interpsys (in util.lisp) needs an extra argument for the 172;# new autoload things and several functions in util.lisp need hacking. 173;############################################################################ 174 175The {\bf build-interpsys} function takes a list of files to load 176into the image ({\bf load-files}). It also takes several lists of files, 177one for each subsystem which will be autoloaded. Autoloading is explained 178below. Next it takes a set of shell variables, the most important of 179which is the {\bf spad} variable. This is normally set to be the same 180as the final build location. This function is called in the 181src/interp/Makefile. 182 183This function calls {\bf initroot} to set up pathnames we need. Next 184it sets up the lisp system memory (at present only for GCL). Next 185it loads all of the named files, resets a few global state variables, 186loads the databases, sets up autoload triggers and clears out hash tables. 187After this function is called the image is clean and can be saved. 188|# 189(defun build-interpsys (load-files spad) 190 #-:ecl 191 (progn 192 (mapcar #'load load-files) 193 (interpsys-image-init spad)) 194 (if (and (boundp 'FRICAS-LISP::*building-fricassys*) 195 FRICAS-LISP::*building-fricassys*) 196 (progn 197 #+:GCL(setf compiler::*default-system-p* nil) 198 #+:GCL(compiler::emit-fn nil) 199 (setq *load-verbose* nil) 200 #+:clisp(setf custom:*suppress-check-redefinition* t) 201 ) 202 ) 203 #+:ecl 204 (progn 205 (setf FRICAS-LISP::*fricas-initial-lisp-objects* 206 (append FRICAS-LISP::*fricas-initial-lisp-objects* 207 '("util.o") 208 load-files)) 209 (let ((initforms nil)) 210 (dolist (el '(|$build_date| |$build_version| |$createLocalLibDb|)) 211 (if (boundp el) 212 (push (list 'defparameter el (symbol-value el)) 213 initforms))) 214 (push `(interpsys-ecl-image-init ,spad) initforms) 215 (push `(fricas-restart) initforms) 216 (setf initforms (reverse initforms)) 217 (push `progn initforms) 218 (setf FRICAS-LISP::*fricas-initial-lisp-forms* initforms) 219 ) 220 ) 221) 222 223(defun interpsys-ecl-image-init (spad) 224 (format *standard-output* "Starting interpsys~%") 225 #+:ecl (let ((sym (or (find-symbol "TRAP-FPE" "EXT") 226 (find-symbol "TRAP-FPE" "SI")))) 227 (if (and sym (fboundp sym)) 228 (funcall sym T T))) 229 #+:ecl (let ((sym (find-symbol "*BREAK-ENABLE*" "SI"))) 230 (if (and sym (boundp sym)) 231 (setf (symbol-value sym) t))) 232 (initroot spad) 233 (setf spad $spadroot) 234 (format *standard-output* "spad = ~s~%" spad) 235 (force-output *standard-output*) 236 (interpsys-image-init spad) 237 (format *standard-output* "before fricas-restart~%") 238 (force-output *standard-output*) 239) 240 241(defun interpsys-image-init (spad) 242 (setf *package* (find-package "BOOT")) 243 (initroot spad) 244 #+:GCL 245 (init-memory-config :cons 500 :fixnum 200 :symbol 500 :package 8 246 :array 400 :string 500 :cfun 100 :cpages 1000 247 :rpages 1000 :hole 2000) 248 #+:GCL 249 (setq compiler::*suppress-compiler-notes* t) 250 (|interpsysInitialization|) 251 (setq *load-verbose* nil) 252 (resethashtables) ; the databases into core, then close the streams 253 ) 254 255;; the following are for conditional reading 256(setq |$opSysName| '"shell") 257 258;;; moved from bookvol5 259 260(defvar |$HiFiAccess| t "t means turn on history mechanism") 261 262(defvar |$reportUndo| nil "t means we report the steps undo takes") 263(defvar $openServerIfTrue t "t means try starting an open server") 264(defparameter $SpadServerName "/tmp/.d" "the name of the spad server socket") 265(defvar |$SpadServer| nil "t means Scratchpad acts as a remote server") 266 267 268(defun |loadExposureGroupData| () 269 (cond 270 ((load "./exposed" :verbose nil :if-does-not-exist nil) 271 '|done|) 272 ((load (concat (|getEnv| "FRICAS") "/algebra/exposed") 273 :verbose nil :if-does-not-exist nil) 274 '|done|) 275 (t '|failed|) )) 276 277(defvar *fricas-load-libspad* t) 278 279(defun fricas-init () 280#+:GCL 281 (init-memory-config :cons 500 :fixnum 200 :symbol 500 :package 8 282 :array 400 :string 500 :cfun 100 :cpages 3000 :rpages 1000 :hole 2000) 283#+:GCL (setq compiler::*compile-verbose* nil) 284#+:GCL (setq compiler::*suppress-compiler-warnings* t) 285#+:GCL (setq compiler::*suppress-compiler-notes* t) 286 (in-package "BOOT") 287 (initroot) 288#+:poplog (setf POPLOG:*READ-PROMPT* "") ;; Turn off Poplog read prompts 289#+:GCL (system:gbc-time 0) 290 #+(or :sbcl :clisp :openmcl :lispworks) 291 (if *fricas-load-libspad* 292 (let* ((ax-dir (|getEnv| "FRICAS")) 293 (spad-lib (concatenate 'string ax-dir "/lib/libspad.so"))) 294 (format t "Checking for foreign routines~%") 295 (format t "FRICAS=~S~%" ax-dir) 296 (format t "spad-lib=~S~%" spad-lib) 297 (if (|fricas_probe_file| spad-lib) 298 (progn 299 (setf *fricas-load-libspad* nil) 300 (format t "foreign routines found~%") 301 #+(or :sbcl :openmcl :lispworks) 302 (|quiet_load_alien| spad-lib) 303 #+(or :sbcl :openmcl) 304 (fricas-lisp::init-gmp 305 (concatenate 'string ax-dir "/lib/gmp_wrap.so")) 306 #+(and :clisp :ffi) 307 (progn 308 (eval `(FFI:DEFAULT-FOREIGN-LIBRARY ,spad-lib)) 309 (FRICAS-LISP::clisp-init-foreign-calls)) 310 ) 311 (setf $openServerIfTrue nil)))) 312 #+(or :GCL (and :clisp :ffi) :sbcl :cmu :openmcl :ecl :lispworks) 313 (if $openServerIfTrue 314 (let ((os (|openServer| $SpadServerName))) 315 (format t "openServer result ~S~%" os) 316 (if (zerop os) 317 (progn 318 (setf $openServerIfTrue nil) 319 #+:GCL 320 (if (fboundp 'si::readline-off) 321 (si::readline-off)) 322 (setq |$SpadServer| t))))) 323 (|interpsys_restart|) 324) 325 326(DEFVAR |$trace_stream| *standard-output*) 327(DEFVAR CUROUTSTREAM *standard-output*) 328 329(defun fricas-restart () 330 ;;; Need to reinitialize CUROUTSTREAM and |$trace_stream| because 331 ;;; clisp closes it when dumping executable 332 (setf CUROUTSTREAM *standard-output*) 333 (setf |$trace_stream| *standard-output*) 334 (fricas-init) 335 #+(or :GCL :poplog) 336 (|spad|) 337 #-(or :GCL :poplog) 338 (let ((*debugger-hook* 339 (lambda (condition previous-handler) 340 (spad-system-error-handler condition)) 341 )) 342 (handler-bind ((error #'spad-system-error-handler)) 343 (|spad|))) 344) 345 346 347(defun spad-save (save-file do-restart) 348 (setq |$SpadServer| nil) 349 (setq $openServerIfTrue t) 350 (FRICAS-LISP::save-core-restart save-file 351 (if do-restart #'boot::fricas-restart nil)) 352) 353 354(defun |statisticsInitialization| () 355 "initialize the garbage collection timer" 356 #+:GCL (system:gbc-time 0) 357 nil) 358 359(defun |mkAutoLoad| (fn cname) 360 (function (lambda (&rest args) 361 #+:sbcl 362 (handler-bind ((style-warning #'muffle-warning)) 363 (|autoLoad| fn cname)) 364 #-:sbcl 365 (|autoLoad| fn cname) 366 (apply cname args)))) 367 368(defun |eval|(x) 369 #-:GCL 370 (handler-bind ((warning #'muffle-warning) 371 #+:sbcl (sb-ext::compiler-note #'muffle-warning)) 372 (eval x)) 373 #+:GCL 374 (eval x) 375) 376 377;;; For evaluating categories we need to bind $. 378(defun |c_eval|(u) (let (($ '$)) (declare (special $)) (|eval| u))) 379 380;;; Accesed from HyperDoc 381(defun |setViewportProcess| () 382 (setq |$ViewportProcessToWatch| 383 (stringimage (CDR 384 (|processInteractive| '(|key| (|%%| -2)) NIL) )))) 385 386;;; Accesed from HyperDoc 387(defun |waitForViewport| () 388 (progn 389 (do () 390 ((not (zerop (obey 391 (concat 392 "ps " 393 |$ViewportProcessToWatch| 394 " > /dev/null"))))) 395 ()) 396 (|sockSendInt| |$MenuServer| 1) 397 (|setIOindex| (- |$IOindex| 3)) 398 ) 399) 400