Code execution in .sbclrc

Discussion of Common Lisp
Post Reply
neuwirthe
Posts: 1
Joined: Sat Mar 24, 2012 2:45 pm

Code execution in .sbclrc

Post by neuwirthe » Sat Mar 24, 2012 3:22 pm

I need help.
I need to evaluate expressions in .sbclrc conditionally on the version on the sbcl interpreter.
Reason: I work on a Mac, I have the latest sbcl, and I also have Maxima which brings its own sblc
which is an older version.
There seem to be problems when the Maxima sbcl runs $HOME/.sbclrc.
So I would like to inhibit evaluation of .sbclrc when the older version of sbcl is started by Maxima.

Kompottkin
Posts: 94
Joined: Mon Jul 21, 2008 7:26 am
Location: München, Germany
Contact:

Re: Code execution in .sbclrc

Post by Kompottkin » Sun Mar 25, 2012 3:28 am

For an ad-hoc, SBCL-specific hack like that, you can parse the return value of the lisp-implementation-version function.

Code: Select all

(defun parsed-lisp-implementation-version ()
  (loop for ver = (lisp-implementation-version)
            then (subseq ver (1+ pos))
        for pos = (position #\. ver)
        collect (parse-integer (if pos (subseq ver 0 pos) ver))
        while pos))

Code: Select all

(defun version<= (version1 version2)
  (loop for x = version1 then (cdr x)
        for y = version2 then (cdr y)
        while (or x y)
        when (null x)
          do (return t)
        when (null y)
          do (return nil)
        when (< (car x) (car y))
          do (return t)
        when (> (car x) (car y))
          do (return nil)
        finally (return t)))

edgar-rft
Posts: 226
Joined: Fri Aug 06, 2010 6:34 am
Location: Germany

Re: Code execution in .sbclrc

Post by edgar-rft » Sun Mar 25, 2012 5:24 am

I have exactly the same problem if I use Maxima and "plain vanilla" SBCL both with the same SBCL version. I have a rather huge bloat of SBCL specific files I read at SBCL startup from .sbclrc, but I do not want all this stuff to be read when I'm starting Maxima.

IMO Maxima should read its own user configuration file[s] and ignore the .sbclrc file by default. The bad thing is that the Maxima command line options to not give the possibility to skip reading the .sbclrc file. Here is my solution with no need to write a conditionalized .sbclrc file.

At the end of the maxima startup script (the file that is executed if you type "maxima" at the shell prompt), there are the following lines:

Code: Select all

elif [ "$MAXIMA_LISP" = "sbcl" ]; then
    exec "sbcl" --core "$maxima_image_base.core" \
    --noinform $MAXIMA_LISP_OPTIONS \
    --end-runtime-options --eval '(cl-user::run) ...
[Note to the forum admin: The \[code\] formatter is configured wrong. It breaks long code lines at an arbitrary point instead of adding a horizontal scrollbar. I had to add backslash escapes, destroying the original context.]

Note to the forum readers: the lines 2 to 5 "exec..." until "--eval '(cl-user::run) ..." is one single line, where the dots at the end of the fifth line indicate that the original line is even much longer.

The particular problem with the Maxima startup script is that the $MAXIMA_LISP_OPTIONS (the Maxima command line options) are inserted before the SBCL "--end-runtime-options", while the reading of the .sbclrc file can only by stopped by the SBCL "--no-userinit" option, which is a top-level option and must appear after "--end-runtime-options" and before "--end-toplevel-options".

Between "--end-runtime-options" and "--eval", I add "--no-userinit", so the lines read:

Code: Select all

elif [ "$MAXIMA_LISP" = "sbcl" ]; then
    exec "sbcl" --core "$maxima_image_base.core" \
    --noinform $MAXIMA_LISP_OPTIONS \
    --end-runtime-options --no-userinit --eval '(cl-user::run) ...
Now Maxima will ignore the .sbclrc file by default."Plain vanilla" SBCL can be configured via .sbclrc and Maxima via its own configuration file[s]. In case of doubt the Maxima files can still read .sbclrc, but now at any time *you* want and not when Maxima forces you to want.

Here is a shell code snippet that does this automatically while I'm building Maxima:

Code: Select all

if [ "x" = "x$(grep -- "--end-runtime-options --eval" src/maxima)" ]
then
  echo 'error: "--end-runtime-options --eval" not found in src/maxima'
else
  sed "s/--end-runtime-options --eval/--end-runtime-options --no-userinit --eval/" src/maxima > src/maxima.tmp
  if [ "x" = "x$(grep -- "--end-runtime-options --no-userinit --eval" src/maxima.tmp)" ]
  then
    echo 'error: "--end-runtime-options --no-userinit --eval" not found in src/maxima.tmp'
  else
    mv src/maxima src/maxima.bak
    mv src/maxima.tmp src/maxima
    echo "Ok."
  fi
fi
The shell code must be run from the root directory of the Maxima source tree. In case of doubt copy the shell code into a text editor if the \[code\] formatter has scrambled the line breaks.

Post Reply