From 9c100b6ab0287f9adff31bc0320578b07bbed3d6 Mon Sep 17 00:00:00 2001 From: Peter Seibel Date: Tue, 6 Mar 2007 23:26:53 +0000 Subject: [PATCH] Sources from my private svn repo, revision 552. --- COPYING | 43 ++ ChangeLog | 5 + GNUmakefile | 286 ++++++++++ GNUmakefile.allegro | 8 + GNUmakefile.base | 9 + GNUmakefile.clisp | 34 ++ GNUmakefile.distros | 17 + GNUmakefile.emacs | 65 +++ GNUmakefile.openmcl | 9 + GNUmakefile.portableaserve | 6 + GNUmakefile.practicals | 6 + GNUmakefile.sbcl | 15 + GNUmakefile.sbcl.ORIG | 27 + GNUmakefile.slime | 15 + GNUmakefile.sourcedistro | 18 + GNUmakefile.vars | 35 ++ Info.plist | 39 ++ OSXpackage.mk | 90 +++ README | 76 +++ README.source | 64 +++ allegro-license-linux | 57 ++ allegro-license-osx | 57 ++ allegro-url.txt | 2 + asdf-extensions.lisp | 262 +++++++++ asdf.lisp | 1102 ++++++++++++++++++++++++++++++++++++ bc-lispbox.bat | 17 + download.html | 88 +++ emacs-env-vars.txt | 28 + install.html | 64 +++ just-lisp-snippet.html | 40 ++ lispbox-register-el.test | 2 + lispbox.html | 197 +++++++ make-distro-from-cvs.sh | 27 + new-lispbox-register.el | 8 + new-lispbox.bat | 31 + no-windows.html | 60 ++ notes.txt | 116 ++++ osx-build-flag.txt | 179 ++++++ publish-html.sh | 3 + relocatable-emacs.sh | 34 ++ site-init.lisp | 54 ++ style.css | 51 ++ write-lispbox-el.sh | 56 ++ write-lispbox.sh | 57 ++ write-site-init-lisp.sh | 66 +++ 45 files changed, 3525 insertions(+) create mode 100644 COPYING create mode 100644 ChangeLog create mode 100644 GNUmakefile create mode 100644 GNUmakefile.allegro create mode 100644 GNUmakefile.base create mode 100644 GNUmakefile.clisp create mode 100644 GNUmakefile.distros create mode 100644 GNUmakefile.emacs create mode 100644 GNUmakefile.openmcl create mode 100644 GNUmakefile.portableaserve create mode 100644 GNUmakefile.practicals create mode 100644 GNUmakefile.sbcl create mode 100644 GNUmakefile.sbcl.ORIG create mode 100644 GNUmakefile.slime create mode 100644 GNUmakefile.sourcedistro create mode 100644 GNUmakefile.vars create mode 100644 Info.plist create mode 100644 OSXpackage.mk create mode 100644 README create mode 100644 README.source create mode 100644 allegro-license-linux create mode 100644 allegro-license-osx create mode 100644 allegro-url.txt create mode 100644 asdf-extensions.lisp create mode 100644 asdf.lisp create mode 100644 bc-lispbox.bat create mode 100644 download.html create mode 100644 emacs-env-vars.txt create mode 100644 install.html create mode 100644 just-lisp-snippet.html create mode 100644 lispbox-register-el.test create mode 100644 lispbox.html create mode 100755 make-distro-from-cvs.sh create mode 100644 new-lispbox-register.el create mode 100644 new-lispbox.bat create mode 100644 no-windows.html create mode 100644 notes.txt create mode 100644 osx-build-flag.txt create mode 100755 publish-html.sh create mode 100644 relocatable-emacs.sh create mode 100644 site-init.lisp create mode 100644 style.css create mode 100644 write-lispbox-el.sh create mode 100755 write-lispbox.sh create mode 100644 write-site-init-lisp.sh diff --git a/COPYING b/COPYING new file mode 100644 index 0000000..0fbbd6c --- /dev/null +++ b/COPYING @@ -0,0 +1,43 @@ +The components that make up the bulk of Lispbox (Emacs, +SLIME, and the various Common Lisp implementions) are +each distributed according to their own license. The +Lispbox code itself may be redistributed according to +the following, BSD-sans-advertising-clause, license: + +Copyright (c) 2005, Peter Seibel All rights reserved. + +Redistribution and use in source and binary forms, with +or without modification, are permitted provided that +the following conditions are met: + + * Redistributions of source code must retain the + above copyright notice, this list of conditions + and the following disclaimer. + + * Redistributions in binary form must reproduce the + above copyright notice, this list of conditions + and the following disclaimer in the documentation + and/or other materials provided with the + distribution. + + * Neither the name of Peter Seibel nor the names of + its contributors may be used to endorse or + promote products derived from this software + without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND +CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED +WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL +THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF +USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER +IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE +USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + diff --git a/ChangeLog b/ChangeLog new file mode 100644 index 0000000..369618d --- /dev/null +++ b/ChangeLog @@ -0,0 +1,5 @@ +2005-04-06 Peter Seibel + + * write-lispbox.sh: Changed way we compute LISPBOX_HOME in order + to work when script run as ./lispbox.sh + diff --git a/GNUmakefile b/GNUmakefile new file mode 100644 index 0000000..37b9ca6 --- /dev/null +++ b/GNUmakefile @@ -0,0 +1,286 @@ +# +# GNUmakefile to build Practical Common Lisp Lispbox distro. +# Copyright 2005 Peter Seibel. +# + +# N.B. I know about the z flag to tar. However, on OS X gzip complains +# about trailing garbage if not passed the -q flag. And tar doesn't +# seem to pay attention to the GZIP environment variable. + +include GNUmakefile.vars + +LISPBOX_LISP := sbcl +GNU_LINUX_EMACS_VERSION := 21.4 +WINDOWS_EMACS_VERSION := 21.3 +CLISP_VERSION := 2.41 +ALLEGRO_VERSION := 70_trial +SBCL_VERSION := 1.0.3 +OPENMCL_VERSION := 1.0 +SLIME_VERSION := 20070306.205402 +PRACTICALS_VERSION := 1.0.3 +PORTABLEASERVE_VERSION := 1.2.35 + +ifeq ($(os),Linux) +emacs := emacs-$(GNU_LINUX_EMACS_VERSION) +endif +ifeq ($(os),Darwin) +emacs := Emacs.app +endif +ifeq ($(os),Windows) +emacs := emacs-$(WINDOWS_EMACS_VERSION) +endif + +clisp := clisp-$(CLISP_VERSION) +allegro := acl$(ALLEGRO_VERSION) +sbcl := sbcl-$(SBCL_VERSION) +openmcl := openmcl-$(OPENMCL_VERSION) + +lisp := $($(LISPBOX_LISP)) +slime := slime-$(SLIME_VERSION) +practicals := practicals-$(PRACTICALS_VERSION) + +ifeq ($(os),Darwin) +lispbox_script_dir := $(prefix)/Emacs.app/Contents/MacOS +emacs_site_lisp := $(prefix)/Emacs.app/Contents/Resources/site-lisp +export LISPBOX_HOME_RELATIVE := /../../.. +export EMACS_EXE := Emacs.app/Contents/MacOS/Emacs +endif +ifeq ($(os),Linux) +lispbox_script_dir := $(prefix) +emacs_site_lisp := $(prefix)/$(emacs)/share/emacs/site-lisp +export LISPBOX_HOME_RELATIVE := +export EMACS_EXE := $(emacs)/bin/emacs +export LINUX=yes +endif +ifeq ($(os),Windows) +lispbox_script_dir := $(prefix) +emacs_site_lisp := $(prefix)/$(emacs)/site-lisp +export LISPBOX_HOME_RELATIVE := +export EMACS_EXE := $(emacs)/bin/runemacs.exe +endif + +export EMACS := $(emacs) + +lispbox_elisp_dir := $(if $(NO_EMACS),$(prefix),$(emacs_site_lisp)) + +all: distro + +distros: + $(MAKE) -f GNUmakefile.distros + +clean: + rm -rf staging + rm -rf $(prefix) + +source-dist: $(LISPBOX_HOME)-source.tar.gz + +$(LISPBOX_HOME)-source.tar.gz: + mkdir $(prefix) + mkdir -p $(prefix)/binary-archives + cp binary-archives/$(practicals).tar.gz $(prefix)/binary-archives/ + mkdir -p $(prefix)/source-archives + mkdir -p $(prefix)/staging-archives + cp asdf-extensions.lisp $(prefix) + cp asdf.lisp $(prefix) + cp COPYING $(prefix) + cp ChangeLog $(prefix) + cp GNUmakefile $(prefix) + cp GNUmakefile.allegro $(prefix) + cp GNUmakefile.base $(prefix) + cp GNUmakefile.clisp $(prefix) + cp GNUmakefile.emacs $(prefix) + cp GNUmakefile.portableaserve $(prefix) + cp GNUmakefile.practicals $(prefix) + cp GNUmakefile.sbcl $(prefix) + cp GNUmakefile.slime $(prefix) + cp GNUmakefile.vars $(prefix) + cp Info.plist $(prefix) + cp OSXpackage.mk $(prefix) + cp README $(prefix) + cp README.source $(prefix) + cp write-lispbox-el.sh $(prefix) + cp write-lispbox.sh $(prefix) + cp lispbox.bat $(prefix) + cp write-site-init-lisp.sh $(prefix) + (cd $(TOP); tar czf - $(LISPBOX_HOME)) > $@ + +$(prefix) staging: + mkdir -p $@ + +staging/%: source-archives/%.tar.gz staging + cat $< | (cd staging; gzip -cdq | tar xf -) + find $@ -exec touch {} \; + +staging/%: source-archives/%.tar.bz2 staging + cat $< | (cd staging; tar xjf -) + find $@ -exec touch {} \; + +###################################################################### +# Installer + +ifeq ($(os),Linux) +distro_no_emacs := lispbox-$(LISPBOX_VERSION)-no-emacs-with-$(lisp).tar.gz +distro_with_emacs := lispbox-$(LISPBOX_VERSION)-$(lisp).tar.gz +distro_just_lisp := lispbox-$(LISPBOX_VERSION)-just-lisp-$(lisp).tar.gz + +distro := $(if $(JUST_LISP),$(distro_just_lisp),$(if $(NO_EMACS),$(distro_no_emacs),$(distro_with_emacs))) + +distro: $(distro) + +$(distro): lispbox + (cd $(TOP); tar czf - $(LISPBOX_HOME)) > $@ +endif + +ifeq ($(os),Darwin) +distro_with_emacs := LispboxInstaller-$(LISPBOX_VERSION)-with-$(lisp).dmg +distro_no_emacs := LispboxInstallerNoEmacs-$(LISPBOX_VERSION)-with-$(lisp).dmg +distro_just_lisp := LispboxInstallerJustLisp-$(LISPBOX_VERSION)-$(lisp).dmg + +distro := $(if $(JUST_LISP),$(distro_just_lisp),$(if $(NO_EMACS),$(distro_no_emacs),$(distro_with_emacs))) + +distro: $(distro) + +$(distro): lispbox + $(MAKE) -f OSXpackage.mk clean all NAME=$(distro) LISPBOX_VERSION=$(LISPBOX_VERSION) LISPBOX_LISP=$(lisp) + +endif + +ifeq ($(os),Windows) +distro_no_emacs := lispbox-$(LISPBOX_VERSION)-no-emacs-with-$(lisp).zip +distro_with_emacs := lispbox-$(LISPBOX_VERSION)-$(lisp).zip +distro_just_lisp := lispbox-$(LISPBOX_VERSION)-just-lisp-$(lisp).zip + +distro := $(if $(JUST_LISP),$(distro_just_lisp),$(if $(NO_EMACS),$(distro_no_emacs),$(distro_with_emacs))) + +distro: $(distro) + +$(distro): lispbox + (cd $(TOP); tar czf - $(LISPBOX_HOME)) > $@ +endif + + +###################################################################### +# Lispbox + +lispbox: staging + +ifndef JUST_LISP +ifndef NO_EMACS +lispbox: $(emacs) +ifeq ($(os),Windows) +lispbox: $(lispbox_script_dir)/lispbox.bat +endif +ifneq ($(os),Windows) +lispbox: $(lispbox_script_dir)/lispbox.sh +endif +ifeq ($(os),Darwin) +lispbox: $(prefix)/Emacs.app/Contents/Info.plist +endif # Darwin +endif # not NO_EMACS + +lispbox: $(slime) +lispbox: $(practicals) +lispbox: $(prefix)/$(slime)/site-init.lisp +lispbox: $(lispbox_elisp_dir)/lispbox.el +lispbox: $(prefix)/asdf.lisp +lispbox: $(prefix)/asdf-extensions.lisp +ifneq ($(LISPBOX_LISP),allegro) +portableaserve := portableaserve-$(PORTABLEASERVE_VERSION) +lispbox: $(portableaserve) +endif # not allegro +endif # not JUST_LISP + +lispbox: $(lisp) +lispbox: $(prefix)/$(lisp)/lispbox-register.el + +$(lispbox_script_dir)/lispbox.bat: lispbox.bat + cp $< $@ + +$(lispbox_script_dir)/lispbox.sh: write-lispbox.sh $(prefix) + SBCL_DIR=$(sbcl) OPENMCL_DIR=$(openmcl) $(SH) $< > $@ + chmod +x $@ + +foo: $(lispbox_elisp_dir)/lispbox.el + +$(lispbox_elisp_dir)/lispbox.el: write-lispbox-el.sh $(if $(NO_EMACS),$(prefix),$(emacs)) + SLIME_DIR=$(slime) SBCL_DIR=$(sbcl) OPENMCL_DIR=$(openmcl) $(SH) $< > $@ + +$(prefix)/$(slime)/site-init.lisp: write-site-init-lisp.sh $(prefix)/$(slime) + PRACTICALS=$(practicals) PORTABLEASERVE=$(portableaserve) $(SH) $< > $@ + chmod 0644 $@ + +$(prefix)/asdf.lisp: asdf.lisp + cp $< $@ + chmod 0644 $@ + +$(prefix)/asdf-extensions.lisp: asdf-extensions.lisp + cp $< $@ + chmod 0644 $@ + +$(prefix)/$(allegro)/lispbox-register.el: lisppath := (lispbox-list-to-filename (list (file-name-directory load-file-name) \"alisp\")) +$(prefix)/$(allegro)/lispbox-register.el: license := \"devel.lic\" + +ifneq ($(os),Windows) +$(prefix)/$(clisp)/lispbox-register.el: lisppath := (lispbox-list-to-filename (list (file-name-directory load-file-name) \"bin\" \"clisp\")) \"-ansi\" \"-K\" \"full\" \"-B\" (lispbox-list-to-filename (list (file-name-directory load-file-name) \"lib\" \"clisp\")) +endif + +ifeq ($(os),Windows) +$(prefix)/$(clisp)/lispbox-register.el: lisppath := \ +(lispbox-list-to-filename (list (file-name-directory load-file-name) \"full\" \"lisp.exe\")) \"-ansi\" \ +\"-M\" (lispbox-list-to-filename (list (file-name-directory load-file-name) \"full\" \"lispinit.mem\")) \ +\"-B\" (lispbox-list-to-filename (list (file-name-directory load-file-name) \"full/\")) +endif + + + +$(prefix)/$(sbcl)/lispbox-register.el: lisppath := (lispbox-list-to-filename (list (file-name-directory load-file-name) \"bin\" \"sbcl\")) +$(prefix)/$(openmcl)/lispbox-register.el: lisppath := (lispbox-list-to-filename (list (file-name-directory load-file-name) \"scripts\" \"openmcl\")) + +$(prefix)/%/lispbox-register.el: $(lisp) + echo "(push (list '$(lisp) (list $(lisppath))) slime-lisp-implementations)" > $@ + if [ ! -z "$(license)" ]; \ + then echo "(lispbox-install-lisp-license (list $(license)) \"$(*)\")" >> $@; \ + fi + +ifeq ($(os),Darwin) +$(prefix)/Emacs.app/Contents/Info.plist: Info.plist $(emacs) + cp Info.plist $(prefix)/Emacs.app/Contents/ +endif + +# Unpacking pre-built staging archives into prefix. + +components := $(emacs) $(allegro) $(clisp) $(sbcl) $(slime) $(practicals) $(portableaserve) +ifeq ($(os),Darwin) +components += $(openmcl) +endif + + +$(components): %: staging-archives/%.tar.gz $(prefix) + cat $< | (cd $(prefix); gzip -cdq | tar xf -) + +$(sbcl): staging-archives/$(sbcl).tar.gz $(prefix) + cat $< | (cd $(prefix); gzip -cdq | tar xf -) + +# Building staging archives if necessary + +staging-archives/$(emacs).tar.gz: makefile := GNUmakefile.emacs +staging-archives/$(allegro).tar.gz: makefile := GNUmakefile.allegro +staging-archives/$(clisp).tar.gz: makefile := GNUmakefile.clisp +staging-archives/$(openmcl).tar.gz: makefile := GNUmakefile.openmcl +staging-archives/$(sbcl).tar.gz: makefile := GNUmakefile.sbcl +staging-archives/$(slime).tar.gz: makefile := GNUmakefile.slime +staging-archives/$(practicals).tar.gz: makefile := GNUmakefile.practicals +staging-archives/$(portableaserve).tar.gz: makefile := GNUmakefile.portableaserve + +staging-archives/%.tar.gz: + $(MAKE) -f $(makefile) THING=$* + +### EMACS ### + +emacs: $(emacs) + +slime-docs: emacs + cd $(prefix)/$(slime)/doc; \ + $(MAKE) infodir=$(prefix)/$(emacs)/info install-info + + diff --git a/GNUmakefile.allegro b/GNUmakefile.allegro new file mode 100644 index 0000000..0b04748 --- /dev/null +++ b/GNUmakefile.allegro @@ -0,0 +1,8 @@ +all: staging-archives/$(THING).tar.gz + +include GNUmakefile.base + +staging-archives/$(THING).tar.gz: binary-archives/$(THING).bz2 $(prefix) + cat $< | (cd $(prefix); tar xjf -) + chmod 0777 $(prefix)/$(THING) + (cd $(prefix); tar czf - $(THING)) > $@ diff --git a/GNUmakefile.base b/GNUmakefile.base new file mode 100644 index 0000000..cb50013 --- /dev/null +++ b/GNUmakefile.base @@ -0,0 +1,9 @@ +# +# Common bits needed by various component make files. +# + +include GNUmakefile.vars + +$(prefix) staging: + mkdir -p $@ + diff --git a/GNUmakefile.clisp b/GNUmakefile.clisp new file mode 100644 index 0000000..662e4cf --- /dev/null +++ b/GNUmakefile.clisp @@ -0,0 +1,34 @@ + +all: staging-archives/$(THING).tar.gz + +include GNUmakefile.base + +ifneq (,$(findstring $(os),Linux Darwin)) + +staging-archives/$(THING).tar.gz: $(prefix)/$(THING) + (cd $(prefix); tar czf - $(THING)) > $@ + +$(prefix)/$(THING): staging/$(THING)/src/clisp + cd staging/$(THING)/src; $(MAKE) install + +staging/$(THING)/src/clisp: staging/$(THING) + cd staging/$(THING); ./configure --prefix=$(prefix)/$(THING) --build --without-readline + +# For 2.36 +# cd staging/$(THING); ./configure --prefix=$(prefix)/$(THING) --build --without-readline --ignore-absence-of-libsigsegv + +staging/$(THING): source-archives/$(THING).tar.gz staging + cat $< | (cd staging; tar xzf -) + +endif + +ifeq ($(os),Windows) + +staging-archives/$(THING).tar.gz: staging/$(THING) + (cd staging; tar czf - $(THING)) > $@ + +staging/$(THING): binary-archives/$(THING)-win32-no-pg.zip staging + unzip $< -d staging/ + chmod +x $@/full/lisp.exe + +endif \ No newline at end of file diff --git a/GNUmakefile.distros b/GNUmakefile.distros new file mode 100644 index 0000000..837c146 --- /dev/null +++ b/GNUmakefile.distros @@ -0,0 +1,17 @@ +include GNUmakefile.vars + +lisps := clisp + +ifneq ($(os),Windows) +lisps += allegro sbcl +endif + +ifeq ($(os),Darwin) +lisps += openmcl +endif + +all: $(lisps) + +$(lisps): +# $(MAKE) clean all LISPBOX_LISP=$@ NO_EMACS=true + $(MAKE) clean all LISPBOX_LISP=$@ diff --git a/GNUmakefile.emacs b/GNUmakefile.emacs new file mode 100644 index 0000000..c8495f3 --- /dev/null +++ b/GNUmakefile.emacs @@ -0,0 +1,65 @@ +# +# Makefile to build binary archive Emacs. +# + +all: staging-archives/$(THING).tar.gz + +include GNUmakefile.base + +ifeq ($(os),Linux) + +staging-archives/$(THING).tar.gz: $(prefix)/$(THING) + (cd $(prefix); tar czf - $(THING)) > $@ + +$(prefix)/$(THING): staging/$(THING)/src/thing + cd staging/$(THING); $(MAKE) install + +staging/$(THING)/src/thing: staging/$(THING)/src/Makefile + cd staging/$(THING); $(MAKE) + +staging/$(THING)/src/Makefile: staging/$(THING) + cd staging/$(THING); ./configure --with-x --prefix=$(prefix)/$(THING) + +staging/$(THING): source-archives/$(THING).tar.gz + cat $< | (cd staging; tar xzf -) + +endif + +ifeq ($(os),Darwin) + +EMACS_VERSION := emacs-20051204.220257 +sourcetar := $(EMACS_VERSION).tar.gz + +staging-archives/$(THING).tar.gz: staging/Applications/$(THING) + (cd staging/Applications/; tar czf - $(THING)) > $@ + +staging/Applications/Emacs.app: staging/Emacs.pax + cd staging; pax -r -f Emacs.pax './Applications/Emacs.app' + +staging/Emacs.pax: staging/Emacs.pax.gz + cd staging; gunzip Emacs.pax.gz + +.SECONDARY: /Volumes/Emacs + +staging/Emacs.pax.gz: /Volumes/Emacs + cp /Volumes/Emacs/Emacs.pkg/Contents/Resources/Emacs.pax.gz staging/Emacs.pax.gz + +/Volumes/Emacs: staging/$(EMACS_VERSION)/mac/EmacsInstaller.dmg + hdiutil attach staging/$(EMACS_VERSION)/mac/EmacsInstaller.dmg + +staging/$(EMACS_VERSION)/mac/EmacsInstaller.dmg: source-archives/$(sourcetar) + mkdir -p staging + cat $< | (cd staging; tar xzf - ) + cd staging/$(EMACS_VERSION)/mac; ./make-package --self-contained + +endif + +ifeq ($(os),Windows) + +staging-archives/$(THING).tar.gz: staging/$(THING) + (cd staging; tar czf - $(THING)) > $@ + +staging/$(THING): binary-archives/$(THING)-fullbin-i386.tar.gz + cat $< | (cd staging; tar xzf -) + +endif diff --git a/GNUmakefile.openmcl b/GNUmakefile.openmcl new file mode 100644 index 0000000..361486e --- /dev/null +++ b/GNUmakefile.openmcl @@ -0,0 +1,9 @@ +VERSION=$(subst openmcl-,,$(THING)) + +all: staging-archives/$(THING).tar.gz + +include GNUmakefile.base + +staging-archives/$(THING).tar.gz: binary-archives/openmcl-darwinppc-all-$(VERSION).tar.gz $(prefix) + cat $< | (cd $(prefix); tar xzf -; mv ccl $(THING)) + (cd $(prefix); tar czf - $(THING)) > $@ diff --git a/GNUmakefile.portableaserve b/GNUmakefile.portableaserve new file mode 100644 index 0000000..9b06830 --- /dev/null +++ b/GNUmakefile.portableaserve @@ -0,0 +1,6 @@ +all: staging-archives/$(THING).tar.gz + +include GNUmakefile.base + +staging-archives/$(THING).tar.gz: binary-archives/$(THING).tar.gz + cp $< $@ diff --git a/GNUmakefile.practicals b/GNUmakefile.practicals new file mode 100644 index 0000000..9b06830 --- /dev/null +++ b/GNUmakefile.practicals @@ -0,0 +1,6 @@ +all: staging-archives/$(THING).tar.gz + +include GNUmakefile.base + +staging-archives/$(THING).tar.gz: binary-archives/$(THING).tar.gz + cp $< $@ diff --git a/GNUmakefile.sbcl b/GNUmakefile.sbcl new file mode 100644 index 0000000..ff995c1 --- /dev/null +++ b/GNUmakefile.sbcl @@ -0,0 +1,15 @@ + +all: staging-archives/$(THING).tar.gz + +include GNUmakefile.base + +staging-archives/$(THING).tar.gz: $(prefix)/$(THING) + (cd $(prefix); tar czf - $(THING)) > $@ + +$(prefix)/$(THING): source-archives/$(THING)-source.tar.bz2 staging + cat $< | (cd staging; tar xjf -) + cd staging/$(THING); $(SH) make.sh; INSTALL_ROOT=$@ $(SH) install.sh + +foo: + (cd tests && $(SH) run-tests.sh); \ + (cd doc/manual && $(MAKE) -k) diff --git a/GNUmakefile.sbcl.ORIG b/GNUmakefile.sbcl.ORIG new file mode 100644 index 0000000..3a0a34d --- /dev/null +++ b/GNUmakefile.sbcl.ORIG @@ -0,0 +1,27 @@ + +all: staging-archives/$(THING).tar.gz + +include GNUmakefile.base + +staging-archives/$(THING).tar.gz: $(prefix)/$(THING) + (cd $(prefix); tar czf - $(THING)) > $@ + +$(prefix)/$(THING): source-archives/$(THING)-source.tar.bz2 staging + cat $< | (cd staging; tar xjf -) + cd staging/$(THING); $(SH) make.sh; INSTALL_ROOT=$@ $(SH) install.sh + +ifeq ($(os),Darwin) +$(prefix)/$(THING): binary-archives/$(THING)-powerpc-darwin-binary.tar.bz2 staging + cat $< | (cd staging; tar xjf -) + cd staging/$(THING)-powerpc-darwin; INSTALL_ROOT=$@ $(SH) install.sh +endif + +ifeq ($(os),Linux) +$(prefix)/$(THING): binary-archives/$(THING)-x86-linux-binary.tar.bz2 staging + cat $< | (cd staging; tar xjf -) + cd staging/$(THING)-x86-linux; INSTALL_ROOT=$@ $(SH) install.sh +endif + +foo: + (cd tests && $(SH) run-tests.sh); \ + (cd doc/manual && $(MAKE) -k) diff --git a/GNUmakefile.slime b/GNUmakefile.slime new file mode 100644 index 0000000..d917feb --- /dev/null +++ b/GNUmakefile.slime @@ -0,0 +1,15 @@ +all: staging-archives/$(THING).tar.gz + +include GNUmakefile.base + +staging-archives/$(THING).tar.gz: $(prefix)/$(THING) + (cd $(prefix); tar czf - $(THING)) > $@ + +$(prefix)/$(THING): staging/$(THING) $(prefix) + cp -r $< $@ + +staging/$(THING): source-archives/$(THING).tar.gz staging + cat $< | (cd staging; tar xzf -) + cd staging/$(THING)/doc; $(MAKE); $(MAKE) clean + + diff --git a/GNUmakefile.sourcedistro b/GNUmakefile.sourcedistro new file mode 100644 index 0000000..152f036 --- /dev/null +++ b/GNUmakefile.sourcedistro @@ -0,0 +1,18 @@ +# +# N.B. Your svn client must be updated to the revion you want to build. +# + +major := 0 +minor := 7 +url := $(shell svn info | perl -ne '/URL: (.+)/ and print $$1, $$/') +revision := $(shell svn info | perl -ne '/Revision: (\d+)/ and print $$1, $$/') +version := $(major).$(minor).$(revision) + +all: lispbox-$(version).tar.gz + +lispbox-$(version).tar.gz: /tmp/lispbox-$(version) + (cd /tmp; tar czf - lispbox-$(version)) > $@ + +/tmp/lispbox-$(version): + svn export -r $(revision) $(url) $@ + diff --git a/GNUmakefile.vars b/GNUmakefile.vars new file mode 100644 index 0000000..5008b54 --- /dev/null +++ b/GNUmakefile.vars @@ -0,0 +1,35 @@ +# +# Variables needed by other make files. +# + +LISPBOX_VERSION := 0.7 +TOP := /tmp +LISPBOX_HOME := lispbox-$(LISPBOX_VERSION) +SH := /bin/sh + +os := $(shell uname) +prefix := $(TOP)/$(LISPBOX_HOME) +empty := +space := $(empty) # don't remove this comment + +export GZIP = -q + +ifeq ($(os),Linux) +P4ROOT := /home/peter/localperforce +CVSROOT := /home/peter/cvs +archive_suffix := tar +unpack_archive := tar xf - +endif + +ifeq ($(os),Darwin) +P4ROOT := /Users/peter/perforce/xeon +CVSROOT := /Users/peter/cvs +archive_suffix := pax +unpack_archive := pax -r +endif + +ifeq ($(os),CYGWIN_NT-5.1) +os := Windows +archive_suffix := tar +endif + diff --git a/Info.plist b/Info.plist new file mode 100644 index 0000000..e8ddd53 --- /dev/null +++ b/Info.plist @@ -0,0 +1,39 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleDocumentTypes + + + CFBundleTypeExtensions + + * + + CFBundleTypeName + NSStringPboardType + CFBundleTypeOSTypes + + **** + + CFBundleTypeRole + Editor + + + CFBundleExecutable + lispbox.sh + CFBundleIconFile + Emacs.icns + CFBundleIdentifier + net.common-lisp.LIAB + CFBundleInfoDictionaryVersion + 6.0 + CFBundlePackageType + APPL + CFBundleSignature + LIAB + CFBundleVersion + 0.2 + + diff --git a/OSXpackage.mk b/OSXpackage.mk new file mode 100644 index 0000000..caa1d19 --- /dev/null +++ b/OSXpackage.mk @@ -0,0 +1,90 @@ +include GNUmakefile.vars + +packagedir := $(TOP)/Lispbox.pkg +rootdir := $(TOP)/lispbox-$(LISPBOX_VERSION) +builddir := $(TOP) +version := $(LISPBOX_VERSION) +title := Lispbox + +files := $(addprefix $(packagedir)/Contents/Resources/Lispbox., pax.gz bom sizes) +files += $(addprefix $(packagedir)/Contents/Resources/, English.lproj/Lispbox.info License.txt ReadMe.txt) +files += $(packagedir)/Contents/PkgInfo + +compressed_size = $(shell du -s $(packagedir) | cut -f1) +#sectors = $(shell echo 2.1*$(compressed_size) | bc) +sectors = $(shell echo 3.0*$(compressed_size) | bc) +mount_location := `hdid -nomount $(builddir)/LispboxRW.dmg | grep HFS | cut -f1` + +all: $(NAME) + +clean: + rm -rf $(packagedir) + rm -f $(builddir)/LispboxInstaller.dmg + rm -rf $(TOP)/staging/ + rm -f $(builddir)/LispboxRW.dmg + +$(NAME): $(builddir)/LispboxInstaller.dmg + cp $< $@ + +$(packagedir)/Contents/Resources/English.lproj: + mkdir -p $@ + +$(packagedir)/Contents/PkgInfo: + echo -n 'pmkrpkg1' > $@ + +$(packagedir)/Contents/Resources/License.txt: + cp COPYING $@ + +$(packagedir)/Contents/Resources/ReadMe.txt: + cp README $@ + +$(packagedir)/Contents/Resources/English.lproj/Lispbox.info: $(packagedir)/Contents/Resources/English.lproj + echo "Title $(title)" > $@ + echo "Version $(version)" >> $@ + echo "Description Install $(title) $(version)" >> $@ + echo 'DefaultLocation /' >> $@ + echo 'DeleteWarning' >> $@ + echo 'NeedsAuthorization YES' >> $@ + echo 'Required NO' >> $@ + echo 'Relocatable NO' >> $@ + echo 'RequiresReboot NO' >> $@ + echo 'UseUserMask NO' >> $@ + echo 'OverwritePermissions NO' >> $@ + echo 'InstallFat NO' >> $@ + +$(packagedir)/Contents/Resources/Lispbox.pax.gz: $(packagedir)/Contents/Resources/Lispbox.pax + gzip $< + +$(packagedir)/Contents/Resources/Lispbox.pax: $(TOP)/staging/Applications/Lispbox + mkdir -p $(dir $@) + cd $(TOP)/staging; pax -w -f $@ . + +$(packagedir)/Contents/Resources/Lispbox.bom: $(TOP)/staging/Applications/Lispbox + mkbom $(TOP)/staging $@ + +$(TOP)/staging/Applications/Lispbox: + mkdir -p $(dir $@) + chown -R root:admin $(rootdir) + cp -R $(rootdir) $@ + find $@/$(LISPBOX_LISP) \( -name '*.o' -o -name '*.fasl' -o -name '*.so' \) -exec touch {} \; + +$(packagedir)/Contents/Resources/Lispbox.sizes: $(packagedir)/Contents/Resources/License.txt $(packagedir)/Contents/Resources/ReadMe.txt + echo "NumFiles $(shell du -a $(rootdir) | wc -l)" > $@ + echo "InstalledSize $(shell du -s $(rootdir) | cut -f1)" >> $@ + echo "CompressedSize $(compressed_size)" >> $@ + +$(builddir)/LispboxInstaller.dmg: $(files) + if [ -e /Volumes/Lispbox ]; then hdiutil eject $(mount_location); fi + hdiutil create -ov $(builddir)/LispboxRW -sectors $(sectors) + /sbin/newfs_hfs -v Lispbox $(mount_location) + hdiutil eject $(mount_location) + hdid $(builddir)/LispboxRW.dmg + df + chown -R root:admin $(packagedir) + cp -R $(packagedir) /Volumes/Lispbox + hdiutil eject $(mount_location) + hdiutil resize $(builddir)/LispboxRW.dmg -sectors min + hdiutil convert $(builddir)/LispboxRW.dmg -format UDRO -o $(builddir)/LispboxInstaller.dmg + + + diff --git a/README b/README new file mode 100644 index 0000000..2472e41 --- /dev/null +++ b/README @@ -0,0 +1,76 @@ +Lispbox is a version of Lisp in a Box, which was +originally created by Matthew Danish and Mikel Evins, +customized for use with Practical Common Lisp. + +The purpose of Lispbox (and Lisp in a Box) is to get +you up and running in a good Lisp environment as +quickly as possible. When you start Lispbox it launches +the text editor Emacs with SLIME (the Superior Lisp +Interaction Mode for Emacs) already installed and +starts Common Lisp for you. Lisp in a Box is designed +to not interfere with your existing Emacs installation, +if you have one. If you are already an Emacs user, you +may wish to install the no-Emacs version designed to +work with an existing Emacs installation. + +For more about what Lispbox is, read on; otherwise hop +over to the download page and start downloading. What +Lispbox gives you + +A full Lispbox distribtion contains: + + * Emacs, the powerful, customizable text editor + + * A Common Lisp implementation of your choosing + + * SLIME, the Superior Lisp Integration Mode for + Emacs + + * ASDF, Another System Definition Facility, used to + load Common Lisp libraries. + + * The practical code from Practical Common Lisp + ready to be loaded using ASDF. + + * A bit of glue code to make it all a bit easier to + use. + +When you run the Lispbox application it will start +Emacs and start Common Lisp in SLIME and you're ready +to start hacking. You can use ASDF to load the various +libraries and applications from Practical Common Lisp. +Lispbox special features + +The environment provided by Lispbox has a few special +features beyond what you'd get from combining Emacs, +SLIME, ASDF, and a Common Lisp implementation. These +features are designed to make it easier to use, +particularly for new Lispers. + + * The package CL-USER is "cleaned" of any + implementation-dependent packages. This makes it + easier to follow along the code in the book + (particularly in the early chapters before I've + introduced packages) without running into name + conflicts with names exported from + implementaton-defined packages that might + otherwise be inherited by CL-USER. This does have + the consequence that certain + implementation-specific extensions are not + automatically available. But they can easily be + added back once you know about Common Lisp's + package system. + + * Lispbox includes some extensions to ASDF that + modify how it finds ASD files and where it stores + the files generated by COMPILE-FILE. The former + makes it slightly easier to install new Common + Lisp libraries and, more important, provides a + mechanism that works the same on OS X, GNU/Linux, + and Windows. The latter makes it easier to + experiment with different Lisp implementations + since it causes the files generated by + COMPILE-FILE to be placed in an + implementation/operating system/architecture + dependent directory. + diff --git a/README.source b/README.source new file mode 100644 index 0000000..d362476 --- /dev/null +++ b/README.source @@ -0,0 +1,64 @@ +This is the source distribution of Lispbox. This is only useful for +people who want to build a Lispbox distribution. To build a distro you +will need GNU make, and a Bourne shell (such as bash). + +Additionally you need the various components that make up Lispbox, in +either source or binary form. The basic idea behind building a Lispbox +distribution is that we start from the source or binary distributions +of the various components and install them (building if necessary) +into a staging directory to which we then add various bits of +Lispbox-specific glue code and then package the whole thing up in an +appropriate manner for a given operating system--as a tar.gz on +GNU/Linux, as a .dmg on OS X, and as double-clickable installer on +Windows. + +The GNUmakefile included here is used to build each component and then +assemble the components into a Lispbox distribution with the Lispbox +specific glue code. To speed the build process the main makefile looks +first for a pre-built version in the directory binary-archives. For +some components, which are available only in binary form, this +pre-built version may be the actual binary archive provided by the +component's "vendor". For others, it may be a tar.gz built from the +source of the compenent by the Lispbox GNUmakefile. For each component +that can be built from source and included in Lispbox there is an +auxilliary GNUmakefile (e.g. GNUmakefile.emacs, GNUmakefile.sbcl, +etc.) that knows how to unpack and build that component and eventually +produce a tar.gz in binary-archives that can be unpacked in the +Lispbox staging directory. (This dramatically speeds up the time it +takes to build a Lispbox distro by avoiding repeatedly building +components whose source has not changed.) + + Allegro: Allegro is only available in binary form. To build an + Allegro Lispbox you need to download the appropriate distribution + from Franz and put it in the binary-archives directory. The Lispbox + GNUmakefile knows how to unpack it into the right place. Users of an + Allegro-based Lispbox will need to obtain a license from Franz. When + an Allegro-based Lispbox starts up it checks whether there is a + licenes file installed in the right place and, if there isn't, asks + the user where they saved the license file and installs it in the + right place. + + OpenMCL: OpenMCL is tricky to build from source. Thus I prefer to use + the binary distributions provided by the OpenMCL developers. Thus the + main Lispbox GNUmakefile treats OpenMCL like Allegro, as a component + that it knows how to unpack into the right place. Download the binary + distribution you want to use and put it in the binary-archives + directory. + + SBCL: To build SBCL you need a version of SBCL already installed and + in your path. (SBCL can, in fact, be cross compiled with other Common + Lisp implementations but the Lispbox makefiles don't know how to take + advantage of that fact.) So you may need to download a binary SBCL + distribution and install it in the normal way and then download a + source distribution and put it in the source-achives directory. + + CLISP: Since CLISP can be built from scratch using just a C compiler + all you need to build a CLISP Lispbox is a source distribution of + CLISP which you should save in the source-archives directory. The + main GNUmakefile knows how to take it from there. + + SLIME: + + http://common-lisp.net/project/slime/slime-1.2.tar.gz + + diff --git a/allegro-license-linux b/allegro-license-linux new file mode 100644 index 0000000..2d9445d --- /dev/null +++ b/allegro-license-linux @@ -0,0 +1,57 @@ + +;; BEGINNING OF FILE + +;; This text should be saved to a file named devel.lic +;; in the Allegro directory. Make sure the first line +;; in the file is ``;; BEGINNING OF FILE'', and that +;; there is no other text preceding the first +;; semi-colon (;) on that line. Make sure the last +;; line in the file is ``;; END OF FILE''. + +;; This license file is for version 6.2 of Allegro +;; CL. It is not possible to use it with other +;; versions of Allegro CL. + +;; This license is valid on any computer in your +;; possession. + +;; This file contains the license necessary to execute +;; Allegro CL. Preceding the license there is a +;; comment describing the contents of the encrypted +;; block of text. Included in the encrypted text is +;; information identifying the licensee. + +;; Once your license expires, you can update your +;; license and continue using Allegro CL by running +;; the `newlicense' program. On Windows, there is a +;; menu item on the Start menu for running +;; `newlicense'. On both UNIX and Windows you can +;; find the `newlicense' program in the Allegro CL +;; directory. + +;; If you have questions or comments, please contact +;; us at support@franz.com (+1 510-452-2000, Franz +;; Inc., 555 12th Street, Suite 1450, Oakland, CA +;; 94607, USA). +;; +;; License created on March 15, 2005, 11:39:33. + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ACL version: 6.2 +;; ACL type: trial +;; Architecture: Linux, Redhat 6.x, 7.x, 8.x and 9, 32-bit +;; Licensed to: Peter Seibel, Gigamonkeys +;; Email address: peter@gigamonkeys.com +;; Expiration date: 2005-5-14 23:59:00 +;; Features: generate-application runtime +(:lisp + "msQySATCWqE39ekxdVXsp81tT9ysUgXHqgoWOB763jxkGn5q5HbH +hUg2O7h4zMHNg96SSAnKyiOQEfQ3hoTd5T7PZkWmdCDSfPz9p6hG +dRFC7WmD6OZoBr5G2JuXTSuAXJ8COto7OuqeNgdDHIEOk3kjUuaT +3SsnLS/nkuyKFA82pDI3YBLqnSFT4G99288Gv5TeYik8WD4QCM2x +6315VGRzmUDfT6exXYrntr1Gg3qurf+zipM9bBQbwtYl/cfTEtx2 +d1M0MwsEuzvY0OwbssKu1TU2edoxI8tNoK9lFKwVl+R5pyGe1sij +HRwn0xCERynV4devPaUKrgoYZo30Tl4=") + +;; END OF FILE diff --git a/allegro-license-osx b/allegro-license-osx new file mode 100644 index 0000000..2e1e27b --- /dev/null +++ b/allegro-license-osx @@ -0,0 +1,57 @@ + +;; BEGINNING OF FILE + +;; This text should be saved to a file named devel.lic +;; in the Allegro directory. Make sure the first line +;; in the file is ``;; BEGINNING OF FILE'', and that +;; there is no other text preceding the first +;; semi-colon (;) on that line. Make sure the last +;; line in the file is ``;; END OF FILE''. + +;; This license file is for version 6.2 of Allegro +;; CL. It is not possible to use it with other +;; versions of Allegro CL. + +;; This license is valid on any computer in your +;; possession. + +;; This file contains the license necessary to execute +;; Allegro CL. Preceding the license there is a +;; comment describing the contents of the encrypted +;; block of text. Included in the encrypted text is +;; information identifying the licensee. + +;; Once your license expires, you can update your +;; license and continue using Allegro CL by running +;; the `newlicense' program. On Windows, there is a +;; menu item on the Start menu for running +;; `newlicense'. On both UNIX and Windows you can +;; find the `newlicense' program in the Allegro CL +;; directory. + +;; If you have questions or comments, please contact +;; us at support@franz.com (+1 510-452-2000, Franz +;; Inc., 555 12th Street, Suite 1450, Oakland, CA +;; 94607, USA). +;; +;; License created on March 15, 2005, 11:40:21. + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ACL version: 6.2 +;; ACL type: trial +;; Architecture: Apple Mac OS X 10.3, 32-bit +;; Licensed to: Peter Seibel, Gigamonkeys +;; Email address: peter@gigamonkeys.com +;; Expiration date: 2005-5-14 23:59:00 +;; Features: generate-application runtime +(:lisp + "YpSGWH2+WIZJ7befxkMrSWzkMHTodM9KHwiIHPHa3TYOPTkjsnU7 +HCQOyEYYVvcOVLbOWlNFbT7BtBcoGFttR4U6bxPQFxtMXnU/XmEB +Y+Uq84o4B4GzvnWlBqFLMWD6L6BsQgznDCcJTQdwCh7BLeIf57e8 +sXS8ZoTgM5aSoUn3wS24BgKEaQIdwVPaebfh3HK3IutahL3WK+1L +eQf+pDzmO5jwIZUs6wZXupjY9sybbQORwUoAzzO1g1BT9s6QsZSf +6s2gAxmTCtwYqpWYI/X63+8wMKAutG7o/rPtgzeWo8FF5fk0tbeQ +sKAYFfDALkNg5bbuSEwEE7vSmsHzRVw=") + +;; END OF FILE diff --git a/allegro-url.txt b/allegro-url.txt new file mode 100644 index 0000000..18c497c --- /dev/null +++ b/allegro-url.txt @@ -0,0 +1,2 @@ +http://ftp.franz.com/ftp/pub/acl62trial/redhat6/acl62_trial.bz2 +http://ftp.franz.com/ftp/pub/acl62trial/macosx103/acl62_trial.bz2 diff --git a/asdf-extensions.lisp b/asdf-extensions.lisp new file mode 100644 index 0000000..139918b --- /dev/null +++ b/asdf-extensions.lisp @@ -0,0 +1,262 @@ +(defpackage :com.gigamonkeys.asdf-extensions + (:use :cl :asdf) + (:export :register-source-directory)) + +(in-package :com.gigamonkeys.asdf-extensions) + +;;; Method for finding ASD files that doesn't depend on symlinks. + +(defvar *top-level-directories* ()) + +(defun sysdef-crawl-directories (system) + (let ((name (asdf::coerce-name system))) + (block found + (flet ((found-p (file) + (when (and + (equal (pathname-name file) name) + (equal (pathname-type file) "asd")) + (return-from found file)))) + (dolist (dir *top-level-directories*) + (walk-directory dir #'found-p)))))) + +(defun register-source-directory (dir) + (push (pathname-as-directory dir) *top-level-directories*)) + +(setf *system-definition-search-functions* '(sysdef-crawl-directories)) + +;;; Build FASLs into a implementation specific directory. + +(defparameter *fasl-directory* + (merge-pathnames + (make-pathname + :directory `(:relative ".lispbox" "fasl" ,(swank-loader::unique-directory-name))) + (user-homedir-pathname))) + +(defmethod output-files :around ((operation compile-op) (c source-file)) + (let ((defaults (merge-pathnames + (make-relative (component-pathname c)) + *fasl-directory*))) + (flet ((relocate-fasl (file) + (make-pathname + :type (pathname-type file) :defaults defaults))) + (mapcar #'relocate-fasl (call-next-method))))) + +;; Static files + +(defmethod output-files :around ((operation compile-op) (c static-file)) + (list + (merge-pathnames (make-relative (component-pathname c)) *fasl-directory*))) + +(defmethod perform :after ((operation compile-op) (c static-file)) + (let ((source-file (component-pathname c)) + (output-file (car (output-files operation c)))) + (ensure-directories-exist output-file) + (with-open-file (in source-file :element-type '(unsigned-byte 8)) + (with-open-file (out output-file :element-type '(unsigned-byte 8) :direction :output :if-exists :supersede) + (loop for octet = (read-byte in nil nil) + while octet do (write-byte octet out)))))) + + +(defun make-relative (pathname) + (make-pathname + :directory (cons :relative (rest (pathname-directory pathname))) + :defaults pathname)) + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; Portable pathnames lib. Unfortunately we can't use ASDF to load it +;;; so we have to inline it here. + +(defun list-directory (dirname) + "Return a list of the contents of the directory named by dirname. +Names of subdirectories will be returned in `directory normal +form'. Unlike CL:DIRECTORY, LIST-DIRECTORY does not accept +wildcard pathnames; `dirname' should simply be a pathname that +names a directory. It can be in either file or directory form." + (when (wild-pathname-p dirname) + (error "Can only list concrete directory names.")) + + (let ((wildcard (directory-wildcard dirname))) + + #+(or sbcl cmu lispworks) + ;; SBCL, CMUCL, and Lispworks return subdirectories in directory + ;; form just the way we want. + (directory wildcard) + + #+openmcl + ;; OpenMCl by default doesn't return subdirectories at all. But + ;; when prodded to do so with the special argument :directories, + ;; it returns them in directory form. + (directory wildcard :directories t) + + #+allegro + ;; Allegro normally return directories in file form but we can + ;; change that with the :directories-are-files argument. + (directory wildcard :directories-are-files nil) + + #+clisp + ;; CLISP has a particularly idiosyncratic view of things. But we + ;; can bludgeon even it into doing what we want. + (nconc + ;; CLISP won't list files without an extension when :type is + ;; wild so we make a special wildcard for it. + (directory wildcard) + ;; And CLISP doesn't consider subdirectories to match unless + ;; there is a :wild in the directory component. + (directory (clisp-subdirectories-wildcard wildcard))) + + #-(or sbcl cmu lispworks openmcl allegro clisp) + (error "list-directory not implemented"))) + + + + +(defun file-exists-p (pathname) + "Similar to CL:PROBE-FILE except it always returns directory names +in `directory normal form'. Returns truename which will be in +`directory form' if file named is, in fact, a directory." + + #+(or sbcl lispworks openmcl) + ;; These implementations do "The Right Thing" as far as we are + ;; concerned. They return a truename of the file or directory if it + ;; exists and the truename of a directory is in directory normal + ;; form. + (probe-file pathname) + + #+(or allegro cmu) + ;; These implementations accept the name of a directory in either + ;; form and return the name in the form given. However the name of a + ;; file must be given in file form. So we try first with a directory + ;; name which will return NIL if either the file doesn't exist at + ;; all or exists and is not a directory. Then we try with a file + ;; form name. + (or (probe-file (pathname-as-directory pathname)) + (probe-file pathname)) + + #+clisp + ;; Once again CLISP takes a particularly unforgiving approach, + ;; signalling ERRORs at the slightest provocation. + + ;; pathname in file form and actually a file -- (probe-file file) ==> truename + ;; pathname in file form and doesn't exist -- (probe-file file) ==> NIL + ;; pathname in dir form and actually a directory -- (probe-directory file) ==> truename + ;; pathname in dir form and doesn't exist -- (probe-directory file) ==> NIL + + ;; pathname in file form and actually a directory -- (probe-file file) ==> ERROR + ;; pathname in dir form and actually a file -- (probe-directory file) ==> ERROR + (or (ignore-errors + ;; PROBE-FILE will return the truename if file exists and is a + ;; file or NIL if it doesn't exist at all. If it exists but is + ;; a directory PROBE-FILE will signal an error which we + ;; ignore. + (probe-file (pathname-as-file pathname))) + (ignore-errors + ;; PROBE-DIRECTORY returns T if the file exists and is a + ;; directory or NIL if it doesn't exist at all. If it exists + ;; but is a file, PROBE-DIRECTORY will signal an error. + (let ((directory-form (pathname-as-directory pathname))) + (when (ext:probe-directory directory-form) + directory-form)))) + + + #-(or sbcl cmu lispworks openmcl allegro clisp) + (error "list-directory not implemented")) + +(defun directory-wildcard (dirname) + (make-pathname + :name :wild + :type #-clisp :wild #+clisp nil + :defaults (pathname-as-directory dirname))) + +#+clisp +(defun clisp-subdirectories-wildcard (wildcard) + (make-pathname + :directory (append (pathname-directory wildcard) (list :wild)) + :name nil + :type nil + :defaults wildcard)) + + +(defun directory-pathname-p (p) + "Is the given pathname the name of a directory? This function can +usefully be used to test whether a name returned by LIST-DIRECTORIES +or passed to the function in WALK-DIRECTORY is the name of a directory +in the file system since they always return names in `directory normal +form'." + (flet ((component-present-p (value) + (and value (not (eql value :unspecific))))) + (and + (not (component-present-p (pathname-name p))) + (not (component-present-p (pathname-type p))) + p))) + + +(defun file-pathname-p (p) + (unless (directory-pathname-p p) p)) + +(defun pathname-as-directory (name) + "Return a pathname reperesenting the given pathname in +`directory normal form', i.e. with all the name elements in the +directory component and NIL in the name and type components. Can +not be used on wild pathnames because there's not portable way to +convert wildcards in the name and type into a single directory +component. Returns its argument if name and type are both nil or +:unspecific." + (let ((pathname (pathname name))) + (when (wild-pathname-p pathname) + (error "Can't reliably convert wild pathnames.")) + (if (not (directory-pathname-p name)) + (make-pathname + :directory (append (or (pathname-directory pathname) (list :relative)) + (list (file-namestring pathname))) + :name nil + :type nil + :defaults pathname) + pathname))) + +(defun pathname-as-file (name) + "Return a pathname reperesenting the given pathname in `file form', +i.e. with the name elements in the name and type component. Can't +convert wild pathnames because of problems mapping wild directory +component into name and type components. Returns its argument if +it is already in file form." + (let ((pathname (pathname name))) + (when (wild-pathname-p pathname) + (error "Can't reliably convert wild pathnames.")) + (if (directory-pathname-p name) + (let* ((directory (pathname-directory pathname)) + (name-and-type (pathname (first (last directory))))) + (make-pathname + :directory (butlast directory) + :name (pathname-name name-and-type) + :type (pathname-type name-and-type) + :defaults pathname)) + pathname))) + +(defun walk-directory (dirname fn &key directories (test (constantly t))) + "Walk a directory invoking `fn' on each pathname found. If `test' is +supplied fn is invoked only on pathnames for which `test' returns +true. If `directories' is t invokes `test' and `fn' on directory +pathnames as well." + (labels + ((walk (name) + (cond + ((directory-pathname-p name) + (when (and directories (funcall test name)) + (funcall fn name)) + (dolist (x (list-directory name)) (walk x))) + ((funcall test name) (funcall fn name))))) + (walk (pathname-as-directory dirname)))) + +(defun directory-p (name) + "Is `name' the name of an existing directory." + (let ((truename (file-exists-p name))) + (and truename (directory-pathname-p name)))) + +(defun file-p (name) + "Is `name' the name of an existing file, i.e. not a directory." + (let ((truename (file-exists-p name))) + (and truename (file-pathname-p name)))) + + +(pushnew :com.gigamonkeys.asdf-extensions *features*) diff --git a/asdf.lisp b/asdf.lisp new file mode 100644 index 0000000..48eae87 --- /dev/null +++ b/asdf.lisp @@ -0,0 +1,1102 @@ +;;; This is asdf: Another System Definition Facility. $Revision: 1.86 $ +;;; +;;; Feedback, bug reports, and patches are all welcome: please mail to +;;; . But note first that the canonical +;;; source for asdf is presently the cCLan CVS repository at +;;; +;;; +;;; If you obtained this copy from anywhere else, and you experience +;;; trouble using it, or find bugs, you may want to check at the +;;; location above for a more recent version (and for documentation +;;; and test files, if your copy came without them) before reporting +;;; bugs. There are usually two "supported" revisions - the CVS HEAD +;;; is the latest development version, whereas the revision tagged +;;; RELEASE may be slightly older but is considered `stable' + +;;; Copyright (c) 2001-2003 Daniel Barlow and contributors +;;; +;;; Permission is hereby granted, free of charge, to any person obtaining +;;; a copy of this software and associated documentation files (the +;;; "Software"), to deal in the Software without restriction, including +;;; without limitation the rights to use, copy, modify, merge, publish, +;;; distribute, sublicense, and/or sell copies of the Software, and to +;;; permit persons to whom the Software is furnished to do so, subject to +;;; the following conditions: +;;; +;;; The above copyright notice and this permission notice shall be +;;; included in all copies or substantial portions of the Software. +;;; +;;; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +;;; EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +;;; MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +;;; NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +;;; LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +;;; OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +;;; WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +;;; the problem with writing a defsystem replacement is bootstrapping: +;;; we can't use defsystem to compile it. Hence, all in one file + +(defpackage #:asdf + (:export #:defsystem #:oos #:operate #:find-system #:run-shell-command + #:system-definition-pathname #:find-component ; miscellaneous + #:hyperdocumentation #:hyperdoc + + #:compile-op #:load-op #:load-source-op #:test-system-version + #:test-op + #:operation ; operations + #:feature ; sort-of operation + #:version ; metaphorically sort-of an operation + + #:input-files #:output-files #:perform ; operation methods + #:operation-done-p #:explain + + #:component #:source-file + #:c-source-file #:cl-source-file #:java-source-file + #:static-file + #:doc-file + #:html-file + #:text-file + #:source-file-type + #:module ; components + #:system + #:unix-dso + + #:module-components ; component accessors + #:component-pathname + #:component-relative-pathname + #:component-name + #:component-version + #:component-parent + #:component-property + #:component-system + + #:component-depends-on + + #:system-description + #:system-long-description + #:system-author + #:system-maintainer + #:system-license + + #:operation-on-warnings + #:operation-on-failure + + ;#:*component-parent-pathname* + #:*system-definition-search-functions* + #:*central-registry* ; variables + #:*compile-file-warnings-behaviour* + #:*compile-file-failure-behaviour* + #:*asdf-revision* + + #:operation-error #:compile-failed #:compile-warned #:compile-error + #:error-component #:error-operation + #:system-definition-error + #:missing-component + #:missing-dependency + #:circular-dependency ; errors + + #:retry + #:accept ; restarts + + ) + (:use :cl)) + +#+nil +(error "The author of this file habitually uses #+nil to comment out forms. But don't worry, it was unlikely to work in the New Implementation of Lisp anyway") + + +(in-package #:asdf) + +(defvar *asdf-revision* (let* ((v "$Revision: 1.86 $") + (colon (or (position #\: v) -1)) + (dot (position #\. v))) + (and v colon dot + (list (parse-integer v :start (1+ colon) + :junk-allowed t) + (parse-integer v :start (1+ dot) + :junk-allowed t))))) + +(defvar *compile-file-warnings-behaviour* :warn) +(defvar *compile-file-failure-behaviour* #+sbcl :error #-sbcl :warn) + +(defvar *verbose-out* nil) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; utility stuff + +(defmacro aif (test then &optional else) + `(let ((it ,test)) (if it ,then ,else))) + +(defun pathname-sans-name+type (pathname) + "Returns a new pathname with same HOST, DEVICE, DIRECTORY as PATHNAME, +and NIL NAME and TYPE components" + (make-pathname :name nil :type nil :defaults pathname)) + +(define-modify-macro appendf (&rest args) + append "Append onto list") + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; classes, condiitons + +(define-condition system-definition-error (error) () + ;; [this use of :report should be redundant, but unfortunately it's not. + ;; cmucl's lisp::output-instance prefers the kernel:slot-class-print-function + ;; over print-object; this is always conditions::%print-condition for + ;; condition objects, which in turn does inheritance of :report options at + ;; run-time. fortunately, inheritance means we only need this kludge here in + ;; order to fix all conditions that build on it. -- rgr, 28-Jul-02.] + #+cmu (:report print-object)) + +(define-condition formatted-system-definition-error (system-definition-error) + ((format-control :initarg :format-control :reader format-control) + (format-arguments :initarg :format-arguments :reader format-arguments)) + (:report (lambda (c s) + (apply #'format s (format-control c) (format-arguments c))))) + +(define-condition circular-dependency (system-definition-error) + ((components :initarg :components :reader circular-dependency-components))) + +(define-condition missing-component (system-definition-error) + ((requires :initform "(unnamed)" :reader missing-requires :initarg :requires) + (version :initform nil :reader missing-version :initarg :version) + (parent :initform nil :reader missing-parent :initarg :parent))) + +(define-condition missing-dependency (missing-component) + ((required-by :initarg :required-by :reader missing-required-by))) + +(define-condition operation-error (error) + ((component :reader error-component :initarg :component) + (operation :reader error-operation :initarg :operation)) + (:report (lambda (c s) + (format s "~@" + (error-operation c) (error-component c))))) +(define-condition compile-error (operation-error) ()) +(define-condition compile-failed (compile-error) ()) +(define-condition compile-warned (compile-error) ()) + +(defclass component () + ((name :accessor component-name :initarg :name :documentation + "Component name: designator for a string composed of portable pathname characters") + (version :accessor component-version :initarg :version) + (in-order-to :initform nil :initarg :in-order-to) + ;;; XXX crap name + (do-first :initform nil :initarg :do-first) + ;; methods defined using the "inline" style inside a defsystem form: + ;; need to store them somewhere so we can delete them when the system + ;; is re-evaluated + (inline-methods :accessor component-inline-methods :initform nil) + (parent :initarg :parent :initform nil :reader component-parent) + ;; no direct accessor for pathname, we do this as a method to allow + ;; it to default in funky ways if not supplied + (relative-pathname :initarg :pathname) + (operation-times :initform (make-hash-table ) + :accessor component-operation-times) + ;; XXX we should provide some atomic interface for updating the + ;; component properties + (properties :accessor component-properties :initarg :properties + :initform nil))) + +;;;; methods: conditions + +(defmethod print-object ((c missing-dependency) s) + (format s "~@<~A, required by ~A~@:>" + (call-next-method c nil) (missing-required-by c))) + +(defun sysdef-error (format &rest arguments) + (error 'formatted-system-definition-error :format-control format :format-arguments arguments)) + +;;;; methods: components + +(defmethod print-object ((c missing-component) s) + (format s "~@" + (missing-requires c) + (missing-version c) + (when (missing-parent c) + (component-name (missing-parent c))))) + +(defgeneric component-system (component) + (:documentation "Find the top-level system containing COMPONENT")) + +(defmethod component-system ((component component)) + (aif (component-parent component) + (component-system it) + component)) + +(defmethod print-object ((c component) stream) + (print-unreadable-object (c stream :type t :identity t) + (ignore-errors + (prin1 (component-name c) stream)))) + +(defclass module (component) + ((components :initform nil :accessor module-components :initarg :components) + ;; what to do if we can't satisfy a dependency of one of this module's + ;; components. This allows a limited form of conditional processing + (if-component-dep-fails :initform :fail + :accessor module-if-component-dep-fails + :initarg :if-component-dep-fails) + (default-component-class :accessor module-default-component-class + :initform 'cl-source-file :initarg :default-component-class))) + +(defgeneric component-pathname (component) + (:documentation "Extracts the pathname applicable for a particular component.")) + +(defun component-parent-pathname (component) + (aif (component-parent component) + (component-pathname it) + *default-pathname-defaults*)) + +(defgeneric component-relative-pathname (component) + (:documentation "Extracts the relative pathname applicable for a particular component.")) + +(defmethod component-relative-pathname ((component module)) + (or (slot-value component 'relative-pathname) + (make-pathname + :directory `(:relative ,(component-name component)) + :host (pathname-host (component-parent-pathname component))))) + +(defmethod component-pathname ((component component)) + (let ((*default-pathname-defaults* (component-parent-pathname component))) + (merge-pathnames (component-relative-pathname component)))) + +(defgeneric component-property (component property)) + +(defmethod component-property ((c component) property) + (cdr (assoc property (slot-value c 'properties) :test #'equal))) + +(defgeneric (setf component-property) (new-value component property)) + +(defmethod (setf component-property) (new-value (c component) property) + (let ((a (assoc property (slot-value c 'properties) :test #'equal))) + (if a + (setf (cdr a) new-value) + (setf (slot-value c 'properties) + (acons property new-value (slot-value c 'properties)))))) + +(defclass system (module) + ((description :accessor system-description :initarg :description) + (long-description + :accessor system-long-description :initarg :long-description) + (author :accessor system-author :initarg :author) + (maintainer :accessor system-maintainer :initarg :maintainer) + (licence :accessor system-licence :initarg :licence))) + +;;; version-satisfies + +;;; with apologies to christophe rhodes ... +(defun split (string &optional max (ws '(#\Space #\Tab))) + (flet ((is-ws (char) (find char ws))) + (nreverse + (let ((list nil) (start 0) (words 0) end) + (loop + (when (and max (>= words (1- max))) + (return (cons (subseq string start) list))) + (setf end (position-if #'is-ws string :start start)) + (push (subseq string start end) list) + (incf words) + (unless end (return list)) + (setf start (1+ end))))))) + +(defgeneric version-satisfies (component version)) + +(defmethod version-satisfies ((c component) version) + (unless (and version (slot-boundp c 'version)) + (return-from version-satisfies t)) + (let ((x (mapcar #'parse-integer + (split (component-version c) nil '(#\.)))) + (y (mapcar #'parse-integer + (split version nil '(#\.))))) + (labels ((bigger (x y) + (cond ((not y) t) + ((not x) nil) + ((> (car x) (car y)) t) + ((= (car x) (car y)) + (bigger (cdr x) (cdr y)))))) + (and (= (car x) (car y)) + (or (not (cdr y)) (bigger (cdr x) (cdr y))))))) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; finding systems + +(defvar *defined-systems* (make-hash-table :test 'equal)) +(defun coerce-name (name) + (typecase name + (component (component-name name)) + (symbol (string-downcase (symbol-name name))) + (string name) + (t (sysdef-error "~@" name)))) + +;;; for the sake of keeping things reasonably neat, we adopt a +;;; convention that functions in this list are prefixed SYSDEF- + +(defvar *system-definition-search-functions* + '(sysdef-central-registry-search)) + +(defun system-definition-pathname (system) + (some (lambda (x) (funcall x system)) + *system-definition-search-functions*)) + +(defvar *central-registry* + '(*default-pathname-defaults* + #+nil "/home/dan/src/sourceforge/cclan/asdf/systems/" + #+nil "telent:asdf;systems;")) + +(defun sysdef-central-registry-search (system) + (let ((name (coerce-name system))) + (block nil + (dolist (dir *central-registry*) + (let* ((defaults (eval dir)) + (file (and defaults + (make-pathname + :defaults defaults :version :newest + :name name :type "asd" :case :local)))) + (if (and file (probe-file file)) + (return file))))))) + + +(defun find-system (name &optional (error-p t)) + (let* ((name (coerce-name name)) + (in-memory (gethash name *defined-systems*)) + (on-disk (system-definition-pathname name))) + (when (and on-disk + (or (not in-memory) + (< (car in-memory) (file-write-date on-disk)))) + (let ((*package* (make-package (gensym #.(package-name *package*)) + :use '(:cl :asdf)))) + (format *verbose-out* + "~&~@<; ~@;loading system definition from ~A into ~A~@:>~%" + ;; FIXME: This wants to be (ENOUGH-NAMESTRING + ;; ON-DISK), but CMUCL barfs on that. + on-disk + *package*) + (load on-disk))) + (let ((in-memory (gethash name *defined-systems*))) + (if in-memory + (progn (if on-disk (setf (car in-memory) (file-write-date on-disk))) + (cdr in-memory)) + (if error-p (error 'missing-component :requires name)))))) + +(defun register-system (name system) + (format *verbose-out* "~&~@<; ~@;registering ~A as ~A~@:>~%" system name) + (setf (gethash (coerce-name name) *defined-systems*) + (cons (get-universal-time) system))) + +(defun system-registered-p (name) + (gethash (coerce-name name) *defined-systems*)) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; finding components + +(defgeneric find-component (module name &optional version) + (:documentation "Finds the component with name NAME present in the +MODULE module; if MODULE is nil, then the component is assumed to be a +system.")) + +(defmethod find-component ((module module) name &optional version) + (if (slot-boundp module 'components) + (let ((m (find name (module-components module) + :test #'equal :key #'component-name))) + (if (and m (version-satisfies m version)) m)))) + + +;;; a component with no parent is a system +(defmethod find-component ((module (eql nil)) name &optional version) + (let ((m (find-system name nil))) + (if (and m (version-satisfies m version)) m))) + +;;; component subclasses + +(defclass source-file (component) ()) + +(defclass cl-source-file (source-file) ()) +(defclass c-source-file (source-file) ()) +(defclass java-source-file (source-file) ()) +(defclass static-file (source-file) ()) +(defclass doc-file (static-file) ()) +(defclass html-file (doc-file) ()) + +(defgeneric source-file-type (component system)) +(defmethod source-file-type ((c cl-source-file) (s module)) "lisp") +(defmethod source-file-type ((c c-source-file) (s module)) "c") +(defmethod source-file-type ((c java-source-file) (s module)) "java") +(defmethod source-file-type ((c html-file) (s module)) "html") +(defmethod source-file-type ((c static-file) (s module)) nil) + +(defmethod component-relative-pathname ((component source-file)) + (let* ((*default-pathname-defaults* (component-parent-pathname component)) + (name-type + (make-pathname + :name (component-name component) + :type (source-file-type component + (component-system component))))) + (if (slot-value component 'relative-pathname) + (merge-pathnames + (slot-value component 'relative-pathname) + name-type) + name-type))) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; operations + +;;; one of these is instantiated whenever (operate ) is called + +(defclass operation () + ((forced :initform nil :initarg :force :accessor operation-forced) + (original-initargs :initform nil :initarg :original-initargs + :accessor operation-original-initargs) + (visited-nodes :initform nil :accessor operation-visited-nodes) + (visiting-nodes :initform nil :accessor operation-visiting-nodes) + (parent :initform nil :initarg :parent :accessor operation-parent))) + +(defmethod print-object ((o operation) stream) + (print-unreadable-object (o stream :type t :identity t) + (ignore-errors + (prin1 (operation-original-initargs o) stream)))) + +(defmethod shared-initialize :after ((operation operation) slot-names + &key force + &allow-other-keys) + (declare (ignore slot-names force)) + ;; empty method to disable initarg validity checking + ) + +(defgeneric perform (operation component)) +(defgeneric operation-done-p (operation component)) +(defgeneric explain (operation component)) +(defgeneric output-files (operation component)) +(defgeneric input-files (operation component)) + +(defun node-for (o c) + (cons (class-name (class-of o)) c)) + +(defgeneric operation-ancestor (operation) + (:documentation "Recursively chase the operation's parent pointer until we get to the head of the tree")) + +(defmethod operation-ancestor ((operation operation)) + (aif (operation-parent operation) + (operation-ancestor it) + operation)) + + +(defun make-sub-operation (c o dep-c dep-o) + (let* ((args (copy-list (operation-original-initargs o))) + (force-p (getf args :force))) + ;; note explicit comparison with T: any other non-NIL force value + ;; (e.g. :recursive) will pass through + (cond ((and (null (component-parent c)) + (null (component-parent dep-c)) + (not (eql c dep-c))) + (when (eql force-p t) + (setf (getf args :force) nil)) + (apply #'make-instance dep-o + :parent o + :original-initargs args args)) + ((subtypep (type-of o) dep-o) + o) + (t + (apply #'make-instance dep-o + :parent o :original-initargs args args))))) + + +(defgeneric visit-component (operation component data)) + +(defmethod visit-component ((o operation) (c component) data) + (unless (component-visited-p o c) + (push (cons (node-for o c) data) + (operation-visited-nodes (operation-ancestor o))))) + +(defgeneric component-visited-p (operation component)) + +(defmethod component-visited-p ((o operation) (c component)) + (assoc (node-for o c) + (operation-visited-nodes (operation-ancestor o)) + :test 'equal)) + +(defgeneric (setf visiting-component) (new-value operation component)) + +(defmethod (setf visiting-component) (new-value operation component) + ;; MCL complains about unused lexical variables + (declare (ignorable new-value operation component))) + +(defmethod (setf visiting-component) (new-value (o operation) (c component)) + (let ((node (node-for o c)) + (a (operation-ancestor o))) + (if new-value + (pushnew node (operation-visiting-nodes a) :test 'equal) + (setf (operation-visiting-nodes a) + (remove node (operation-visiting-nodes a) :test 'equal))))) + +(defgeneric component-visiting-p (operation component)) + +(defmethod component-visiting-p ((o operation) (c component)) + (let ((node (cons o c))) + (member node (operation-visiting-nodes (operation-ancestor o)) + :test 'equal))) + +(defgeneric component-depends-on (operation component)) + +(defmethod component-depends-on ((o operation) (c component)) + (cdr (assoc (class-name (class-of o)) + (slot-value c 'in-order-to)))) + +(defgeneric component-self-dependencies (operation component)) + +(defmethod component-self-dependencies ((o operation) (c component)) + (let ((all-deps (component-depends-on o c))) + (remove-if-not (lambda (x) + (member (component-name c) (cdr x) :test #'string=)) + all-deps))) + +(defmethod input-files ((operation operation) (c component)) + (let ((parent (component-parent c)) + (self-deps (component-self-dependencies operation c))) + (if self-deps + (mapcan (lambda (dep) + (destructuring-bind (op name) dep + (output-files (make-instance op) + (find-component parent name)))) + self-deps) + ;; no previous operations needed? I guess we work with the + ;; original source file, then + (list (component-pathname c))))) + +(defmethod input-files ((operation operation) (c module)) nil) + +(defmethod operation-done-p ((o operation) (c component)) + (let ((out-files (output-files o c)) + (in-files (input-files o c))) + (cond ((and (not in-files) (not out-files)) + ;; arbitrary decision: an operation that uses nothing to + ;; produce nothing probably isn't doing much + t) + ((not out-files) + (let ((op-done + (gethash (type-of o) + (component-operation-times c)))) + (and op-done + (>= op-done + (or (apply #'max + (mapcar #'file-write-date in-files)) 0))))) + ((not in-files) nil) + (t + (and + (every #'probe-file out-files) + (> (apply #'min (mapcar #'file-write-date out-files)) + (apply #'max (mapcar #'file-write-date in-files)) )))))) + +;;; So you look at this code and think "why isn't it a bunch of +;;; methods". And the answer is, because standard method combination +;;; runs :before methods most->least-specific, which is back to front +;;; for our purposes. And CLISP doesn't have non-standard method +;;; combinations, so let's keep it simple and aspire to portability + +(defgeneric traverse (operation component)) +(defmethod traverse ((operation operation) (c component)) + (let ((forced nil)) + (labels ((do-one-dep (required-op required-c required-v) + (let* ((dep-c (or (find-component + (component-parent c) + ;; XXX tacky. really we should build the + ;; in-order-to slot with canonicalized + ;; names instead of coercing this late + (coerce-name required-c) required-v) + (error 'missing-dependency :required-by c + :version required-v + :requires required-c))) + (op (make-sub-operation c operation dep-c required-op))) + (traverse op dep-c))) + (do-dep (op dep) + (cond ((eq op 'feature) + (or (member (car dep) *features*) + (error 'missing-dependency :required-by c + :requires (car dep) :version nil))) + (t + (dolist (d dep) + (cond ((consp d) + (assert (string-equal + (symbol-name (first d)) + "VERSION")) + (appendf forced + (do-one-dep op (second d) (third d)))) + (t + (appendf forced (do-one-dep op d nil))))))))) + (aif (component-visited-p operation c) + (return-from traverse + (if (cdr it) (list (cons 'pruned-op c)) nil))) + ;; dependencies + (if (component-visiting-p operation c) + (error 'circular-dependency :components (list c))) + (setf (visiting-component operation c) t) + (loop for (required-op . deps) in (component-depends-on operation c) + do (do-dep required-op deps)) + ;; constituent bits + (let ((module-ops + (when (typep c 'module) + (let ((at-least-one nil) + (forced nil) + (error nil)) + (loop for kid in (module-components c) + do (handler-case + (appendf forced (traverse operation kid )) + (missing-dependency (condition) + (if (eq (module-if-component-dep-fails c) :fail) + (error condition)) + (setf error condition)) + (:no-error (c) + (declare (ignore c)) + (setf at-least-one t)))) + (when (and (eq (module-if-component-dep-fails c) :try-next) + (not at-least-one)) + (error error)) + forced)))) + ;; now the thing itself + (when (or forced module-ops + (not (operation-done-p operation c)) + (let ((f (operation-forced (operation-ancestor operation)))) + (and f (or (not (consp f)) + (member (component-name + (operation-ancestor operation)) + (mapcar #'coerce-name f) + :test #'string=))))) + (let ((do-first (cdr (assoc (class-name (class-of operation)) + (slot-value c 'do-first))))) + (loop for (required-op . deps) in do-first + do (do-dep required-op deps))) + (setf forced (append (delete 'pruned-op forced :key #'car) + (delete 'pruned-op module-ops :key #'car) + (list (cons operation c)))))) + (setf (visiting-component operation c) nil) + (visit-component operation c (and forced t)) + forced))) + + +(defmethod perform ((operation operation) (c source-file)) + (sysdef-error + "~@" + (class-of operation) (class-of c))) + +(defmethod perform ((operation operation) (c module)) + nil) + +(defmethod explain ((operation operation) (component component)) + (format *verbose-out* "~&;;; ~A on ~A~%" operation component)) + +;;; compile-op + +(defclass compile-op (operation) + ((proclamations :initarg :proclamations :accessor compile-op-proclamations :initform nil) + (on-warnings :initarg :on-warnings :accessor operation-on-warnings + :initform *compile-file-warnings-behaviour*) + (on-failure :initarg :on-failure :accessor operation-on-failure + :initform *compile-file-failure-behaviour*))) + +(defmethod perform :before ((operation compile-op) (c source-file)) + (map nil #'ensure-directories-exist (output-files operation c))) + +(defmethod perform :after ((operation operation) (c component)) + (setf (gethash (type-of operation) (component-operation-times c)) + (get-universal-time))) + +;;; perform is required to check output-files to find out where to put +;;; its answers, in case it has been overridden for site policy +(defmethod perform ((operation compile-op) (c cl-source-file)) + #-:broken-fasl-loader + (let ((source-file (component-pathname c)) + (output-file (car (output-files operation c)))) + (multiple-value-bind (output warnings-p failure-p) + (compile-file source-file + :output-file output-file) + ;(declare (ignore output)) + (when warnings-p + (case (operation-on-warnings operation) + (:warn (warn + "~@" + operation c)) + (:error (error 'compile-warned :component c :operation operation)) + (:ignore nil))) + (when failure-p + (case (operation-on-failure operation) + (:warn (warn + "~@" + operation c)) + (:error (error 'compile-failed :component c :operation operation)) + (:ignore nil))) + (unless output + (error 'compile-error :component c :operation operation))))) + +(defmethod output-files ((operation compile-op) (c cl-source-file)) + #-:broken-fasl-loader (list (compile-file-pathname (component-pathname c))) + #+:broken-fasl-loader (list (component-pathname c))) + +(defmethod perform ((operation compile-op) (c static-file)) + nil) + +(defmethod output-files ((operation compile-op) (c static-file)) + nil) + +;;; load-op + +(defclass load-op (operation) ()) + +(defmethod perform ((o load-op) (c cl-source-file)) + (mapcar #'load (input-files o c))) + +(defmethod perform ((operation load-op) (c static-file)) + nil) +(defmethod operation-done-p ((operation load-op) (c static-file)) + t) + +(defmethod output-files ((o operation) (c component)) + nil) + +(defmethod component-depends-on ((operation load-op) (c component)) + (cons (list 'compile-op (component-name c)) + (call-next-method))) + +;;; load-source-op + +(defclass load-source-op (operation) ()) + +(defmethod perform ((o load-source-op) (c cl-source-file)) + (let ((source (component-pathname c))) + (setf (component-property c 'last-loaded-as-source) + (and (load source) + (get-universal-time))))) + +(defmethod perform ((operation load-source-op) (c static-file)) + nil) + +(defmethod output-files ((operation load-source-op) (c component)) + nil) + +;;; FIXME: we simply copy load-op's dependencies. this is Just Not Right. +(defmethod component-depends-on ((o load-source-op) (c component)) + (let ((what-would-load-op-do (cdr (assoc 'load-op + (slot-value c 'in-order-to))))) + (mapcar (lambda (dep) + (if (eq (car dep) 'load-op) + (cons 'load-source-op (cdr dep)) + dep)) + what-would-load-op-do))) + +(defmethod operation-done-p ((o load-source-op) (c source-file)) + (if (or (not (component-property c 'last-loaded-as-source)) + (> (file-write-date (component-pathname c)) + (component-property c 'last-loaded-as-source))) + nil t)) + +(defclass test-op (operation) ()) + +(defmethod perform ((operation test-op) (c component)) + nil) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; invoking operations + +(defun operate (operation-class system &rest args) + (let* ((op (apply #'make-instance operation-class + :original-initargs args args)) + (*verbose-out* + (if (getf args :verbose t) + *trace-output* + (make-broadcast-stream))) + (system (if (typep system 'component) system (find-system system))) + (steps (traverse op system))) + (with-compilation-unit () + (loop for (op . component) in steps do + (loop + (restart-case + (progn (perform op component) + (return)) + (retry () + :report + (lambda (s) + (format s "~@" + op component))) + (accept () + :report + (lambda (s) + (format s + "~@" + op component)) + (setf (gethash (type-of op) + (component-operation-times component)) + (get-universal-time)) + (return)))))))) + +(defun oos (&rest args) + "Alias of OPERATE function" + (apply #'operate args)) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; syntax + +(defun remove-keyword (key arglist) + (labels ((aux (key arglist) + (cond ((null arglist) nil) + ((eq key (car arglist)) (cddr arglist)) + (t (cons (car arglist) (cons (cadr arglist) + (remove-keyword + key (cddr arglist)))))))) + (aux key arglist))) + +(defmacro defsystem (name &body options) + (destructuring-bind (&key pathname (class 'system) &allow-other-keys) options + (let ((component-options (remove-keyword :class options))) + `(progn + ;; system must be registered before we parse the body, otherwise + ;; we recur when trying to find an existing system of the same name + ;; to reuse options (e.g. pathname) from + (let ((s (system-registered-p ',name))) + (cond ((and s (eq (type-of (cdr s)) ',class)) + (setf (car s) (get-universal-time))) + (s + #+clisp + (sysdef-error "Cannot redefine the existing system ~A with a different class" s) + #-clisp + (change-class (cdr s) ',class)) + (t + (register-system (quote ,name) + (make-instance ',class :name ',name))))) + (parse-component-form nil (apply + #'list + :module (coerce-name ',name) + :pathname + (or ,pathname + (pathname-sans-name+type + (resolve-symlinks *load-truename*)) + *default-pathname-defaults*) + ',component-options)))))) + + +(defun class-for-type (parent type) + (let ((class + (find-class + (or (find-symbol (symbol-name type) *package*) + (find-symbol (symbol-name type) #.(package-name *package*))) + nil))) + (or class + (and (eq type :file) + (or (module-default-component-class parent) + (find-class 'cl-source-file))) + (sysdef-error "~@" type)))) + +(defun maybe-add-tree (tree op1 op2 c) + "Add the node C at /OP1/OP2 in TREE, unless it's there already. +Returns the new tree (which probably shares structure with the old one)" + (let ((first-op-tree (assoc op1 tree))) + (if first-op-tree + (progn + (aif (assoc op2 (cdr first-op-tree)) + (if (find c (cdr it)) + nil + (setf (cdr it) (cons c (cdr it)))) + (setf (cdr first-op-tree) + (acons op2 (list c) (cdr first-op-tree)))) + tree) + (acons op1 (list (list op2 c)) tree)))) + +(defun union-of-dependencies (&rest deps) + (let ((new-tree nil)) + (dolist (dep deps) + (dolist (op-tree dep) + (dolist (op (cdr op-tree)) + (dolist (c (cdr op)) + (setf new-tree + (maybe-add-tree new-tree (car op-tree) (car op) c)))))) + new-tree)) + + +(defun remove-keys (key-names args) + (loop for ( name val ) on args by #'cddr + unless (member (symbol-name name) key-names + :key #'symbol-name :test 'equal) + append (list name val))) + +(defvar *serial-depends-on*) + +(defun parse-component-form (parent options) + (destructuring-bind + (type name &rest rest &key + ;; the following list of keywords is reproduced below in the + ;; remove-keys form. important to keep them in sync + components pathname default-component-class + perform explain output-files operation-done-p + depends-on serial in-order-to + ;; list ends + &allow-other-keys) options + (check-component-input type name depends-on components in-order-to) + (let* ((other-args (remove-keys + '(components pathname default-component-class + perform explain output-files operation-done-p + depends-on serial in-order-to) + rest)) + (ret + (or (find-component parent name) + (make-instance (class-for-type parent type))))) + (when (boundp '*serial-depends-on*) + (setf depends-on + (concatenate 'list *serial-depends-on* depends-on))) + (apply #'reinitialize-instance + ret + :name (coerce-name name) + :pathname pathname + :parent parent + other-args) + (when (typep ret 'module) + (setf (module-default-component-class ret) + (or default-component-class + (and (typep parent 'module) + (module-default-component-class parent)))) + (let ((*serial-depends-on* nil)) + (setf (module-components ret) + (loop for c-form in components + for c = (parse-component-form ret c-form) + collect c + if serial + do (push (component-name c) *serial-depends-on*))))) + + (setf (slot-value ret 'in-order-to) + (union-of-dependencies + in-order-to + `((compile-op (compile-op ,@depends-on)) + (load-op (load-op ,@depends-on)))) + (slot-value ret 'do-first) `((compile-op (load-op ,@depends-on)))) + + (loop for (n v) in `((perform ,perform) (explain ,explain) + (output-files ,output-files) + (operation-done-p ,operation-done-p)) + do (map 'nil + ;; this is inefficient as most of the stored + ;; methods will not be for this particular gf n + ;; But this is hardly performance-critical + (lambda (m) (remove-method (symbol-function n) m)) + (component-inline-methods ret)) + when v + do (destructuring-bind (op qual (o c) &body body) v + (pushnew + (eval `(defmethod ,n ,qual ((,o ,op) (,c (eql ,ret))) + ,@body)) + (component-inline-methods ret)))) + ret))) + +(defun check-component-input (type name depends-on components in-order-to) + "A partial test of the values of a component." + (unless (listp depends-on) + (sysdef-error-component ":depends-on must be a list." + type name depends-on)) + (unless (listp components) + (sysdef-error-component ":components must be NIL or a list of components." + type name components)) + (unless (and (listp in-order-to) (listp (car in-order-to))) + (sysdef-error-component ":in-order-to must be NIL or a list of components." + type name in-order-to))) + +(defun sysdef-error-component (msg type name value) + (sysdef-error (concatenate 'string msg + "~&The value specified for ~(~A~) ~A is ~W") + type name value)) + +(defun resolve-symlinks (path) + #-allegro (truename path) + #+allegro (excl:pathname-resolve-symbolic-links path) + ) + +;;; optional extras + +;;; run-shell-command functions for other lisp implementations will be +;;; gratefully accepted, if they do the same thing. If the docstring +;;; is ambiguous, send a bug report + +(defun run-shell-command (control-string &rest args) + "Interpolate ARGS into CONTROL-STRING as if by FORMAT, and +synchronously execute the result using a Bourne-compatible shell, with +output to *verbose-out*. Returns the shell's exit code." + (let ((command (apply #'format nil control-string args))) + (format *verbose-out* "; $ ~A~%" command) + #+sbcl + (sb-impl::process-exit-code + (sb-ext:run-program + "/bin/sh" + (list "-c" command) + :input nil :output *verbose-out*)) + + #+(or cmu scl) + (ext:process-exit-code + (ext:run-program + "/bin/sh" + (list "-c" command) + :input nil :output *verbose-out*)) + + #+allegro + (excl:run-shell-command command :input nil :output *verbose-out*) + + #+lispworks + (system:call-system-showing-output + command + :shell-type "/bin/sh" + :output-stream *verbose-out*) + + #+clisp ;XXX not exactly *verbose-out*, I know + (ext:run-shell-command command :output :terminal :wait t) + + #+openmcl + (nth-value 1 + (ccl:external-process-status + (ccl:run-program "/bin/sh" (list "-c" command) + :input nil :output *verbose-out* + :wait t))) + #+ecl ;; courtesy of Juan Jose Garcia Ripoll + (si:system command) + #-(or openmcl clisp lispworks allegro scl cmu sbcl ecl) + (error "RUN-SHELL-PROGRAM not implemented for this Lisp") + )) + + +(defgeneric hyperdocumentation (package name doc-type)) +(defmethod hyperdocumentation ((package symbol) name doc-type) + (hyperdocumentation (find-package package) name doc-type)) + +(defun hyperdoc (name doc-type) + (hyperdocumentation (symbol-package name) name doc-type)) + + +(pushnew :asdf *features*) + +#+sbcl +(eval-when (:compile-toplevel :load-toplevel :execute) + (when (sb-ext:posix-getenv "SBCL_BUILDING_CONTRIB") + (pushnew :sbcl-hooks-require *features*))) + +#+(and sbcl sbcl-hooks-require) +(progn + (defun module-provide-asdf (name) + (handler-bind ((style-warning #'muffle-warning)) + (let* ((*verbose-out* (make-broadcast-stream)) + (system (asdf:find-system name nil))) + (when system + (asdf:operate 'asdf:load-op name) + t)))) + + (pushnew + '(merge-pathnames "systems/" + (truename (sb-ext:posix-getenv "SBCL_HOME"))) + *central-registry*) + + (pushnew + '(merge-pathnames "site-systems/" + (truename (sb-ext:posix-getenv "SBCL_HOME"))) + *central-registry*) + + (pushnew + '(merge-pathnames ".sbcl/systems/" + (user-homedir-pathname)) + *central-registry*) + + (pushnew 'module-provide-asdf sb-ext:*module-provider-functions*)) + +(provide 'asdf) diff --git a/bc-lispbox.bat b/bc-lispbox.bat new file mode 100644 index 0000000..793cb18 --- /dev/null +++ b/bc-lispbox.bat @@ -0,0 +1,17 @@ +rem Only assign a value if none exists +if "%LISPBOX_HOME%"=="" goto nt +goto start + +:nt +if NOT %OS%==Windows_NT goto win98 +for %%i in ( "%CD%" ) do set LISPBOX_HOME=%%~si% +goto start + +:win98 +set LISPBOX_HOME=%CD% + +:start +set EMACS=%LISPBOX_HOME%/emacs-21.3/bin/runemacs.exe +set TO_EVAL="(progn (load \"lispbox\") (slime))" + +%EMACS% --no-init-file --no-site-file --eval=%TO_EVAL% \ No newline at end of file diff --git a/download.html b/download.html new file mode 100644 index 0000000..a8d298b --- /dev/null +++ b/download.html @@ -0,0 +1,88 @@ + + +Download Lispbox + + + + +

Download Lispbox

+ +

Lispbox is designed to given you +everything you need to get up and running, hacking Common Lisp, in one +easy-to-install download. However you do need to pick the right +version of Lispbox for the OS you are using and the Common Lisp +implementation you want to try. However you can also download +individual Common Lisp implementations in Lispbox-ready form to add to +an existing Lispbox installation so the choice of Lisp implementation +you start with doesn't matter a great deal.

+ +

Note on choosing a Lisp implementation. All of the Lisp +implementations available here are high-quality implementations that +can be used for learning Lisp and for writing real applications. +However if you want to be able to run all the practical examples +from Practical Common +Lisp the easiest path is to use Allegro since it supports both +Unicode and threads and has AllegroServe built in. CLISP has excellent +Unicode support but no threads. SBCL added Unicode in version 0.8.17 +but there are still, as of this writing, a few wrinkles to work out. +And it supports threads only on GNU/Linux 2.6 systems running on x86. +OpenMCL supports native threads but not Unicode. The ID3 parser +developed +in Chapter +25 works best in Lisps that support Unicode but will work fine in +non-Unicode Lisps as long as none of the MP3 files you want to parse +contain Unicode strings. And the Shoutcast server developed in +Chapters +28 and +29 +requires an implementation that supports multiple threads.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
OS X (10.4)GNU/Linux x86Windows
Allegro (get license)7.06.2not yet available
SBCL 0.9.70.9.0
OpenMCL1.0
CLISP2.33.22.33.22.34
+ +

To choose the appropriate Lisbox pick the +operating system you are running on and the Common Lisp implementation +you want to try. The numbers in the table's cells are the version of +the Lisp implementation. If you choose Allegro you will need to get a +free licence from Franz's web site; click +on get license +to go to the Franz web site. Lispbox will help you install the license +the first time you run it.

+ +
+ + + diff --git a/emacs-env-vars.txt b/emacs-env-vars.txt new file mode 100644 index 0000000..f48095f --- /dev/null +++ b/emacs-env-vars.txt @@ -0,0 +1,28 @@ +`EMACSDATA' ("/usr/local/share/emacs/22.0.50/etc/") + Directory for the architecture-independent files that come with + Emacs. This is used to initialize the Lisp variable + `data-directory'. + +`EMACSDOC' ("/usr2/cvs/emacs/etc/") + Directory for the documentation string file, `DOC-EMACSVERSION'. + This is used to initialize the Lisp variable `doc-directory'. + +`EMACSLOADPATH' + A colon-separated list of directories(1) to search for Emacs Lisp + files--used to initialize `load-path'. + +`PATH' + A colon-separated list of directories in which executables reside. + This is used to initialize the Emacs Lisp variable `exec-path'. +`EMACSPATH' + A colon-separated list of directories to search for executable + files--used to initialize `exec-path'. +("/bin" "/usr/bin" "/usr/bin/X11" "/usr/local/bin" "/usr/bin" "/usr/X11R6/bin" "/usr/local/acl/acl62/" "/home/peter/bin" "/usr/local/acl/acl62/" "/usr/local/acl/acl62/" "/home/peter/bin" "/usr/local/acl/acl62/" "/usr/local/acl/acl62/" "/usr2/cvs/emacs/lib-src" "/usr/local/libexec/emacs/22.0.50/i686-pc-linux-gnu") + +`PWD' + If set, this should be the default directory when Emacs was + started. + +`SHELL' + The name of an interpreter used to parse and execute programs run + from inside Emacs. diff --git a/install.html b/install.html new file mode 100644 index 0000000..d20b708 --- /dev/null +++ b/install.html @@ -0,0 +1,64 @@ + + +Lispbox Installation + + + + +

Full Lispbox Installation

+ +

After you've downloaded +a Lispbox distribution, how exactly you +install it depends on which operating system you're using.

+ + +

GNU/Linux

+ +

On GNU/Linux the distribution comes as a gzipped tar file that +unpacks into a directory named lispbox-<version>. To install it, +you simply need to save the downloaded file and untar it +with tar xzf. For example, if you want to install Lispbox +in your home directory, save the downloaded file in your home +directory, cdy to your home directory and execute this +command:

+ +
+  tar xzf lispbox-0.1.tar.gz
+
+ +

This will create a lispbox-0.1 directory in your home +directory. In a full Lispbox disttribution, this directory will +contain a script lispbox.sh. You can then either +add lispbox-0.1 to your PATH or you can +invoke lispbox.sh by specifying the complete path when +you invoke it:

+ +
+  bash$ /home/peter/lispbox-0.1/lispbox.sh
+
+ +

This script will start Emacs and launch the installed Common Lisp +in SLIME.

+ +

In a no-emacs distribution, there is no startup script. Instead you +need to + + +

Mac OS X

+ +

On OS X the distribution comes as a disk image. When you download +it it should be mounted automatically. Double-click the +Lispbox.pkg icon to run the installer. It will install +Lispbox in /Applications/. Once the installation is +complete, you can double click the Emacs icon in the +new Lispbox directory to launch Emacs and start the +installed Common Lisp implementation in SLIME. + +

Windows

+ +

Not yet available

+ + +

No-Emacs Lispbox Installation

+ + diff --git a/just-lisp-snippet.html b/just-lisp-snippet.html new file mode 100644 index 0000000..5a9f676 --- /dev/null +++ b/just-lisp-snippet.html @@ -0,0 +1,40 @@ +

Just Lisp

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Lisp ImplementationMac OS XGNU/LinuxWindows
Allegro 6.2 (get license)not yet availablenot yet availablenot yet available
SBCL 0.8.20not yet availablenot yet available
OpenMCL ????not yet available
CLISP 2.33.2not yet availablenot yet availablenot yet available
+ +

Choose a file from this table if you want to +add another Common Lisp implementation to an existing Lispbox +installation. To install, simply unpack the file in your existing +Lispbox directory and invoke M-x lispbox-find-lisps.

diff --git a/lispbox-register-el.test b/lispbox-register-el.test new file mode 100644 index 0000000..581171e --- /dev/null +++ b/lispbox-register-el.test @@ -0,0 +1,2 @@ +(push (list 'clisp-2.35 (list (lispbox-list-to-filename (list (file-name-directory load-file-name) "bin" "clisp")) "-ansi" "-K" "full" "-B" (lispbox-list-to-filename (list (file-name-directory load-file-name) "lib" "clisp")))) slime-lisp-implementations) +(push (list 'clisp-2.35 (list (lispbox-list-to-filename (list (file-name-directory load-file-name) "bin" "clisp")) "-ansi" "-K" "full" "-B" (lispbox-list-to-filename (list (file-name-directory load-file-name) "lib" "clisp")))) slime-lisp-implementations) diff --git a/lispbox.html b/lispbox.html new file mode 100644 index 0000000..689b704 --- /dev/null +++ b/lispbox.html @@ -0,0 +1,197 @@ + + +Lispbox + + + + +

Lispbox

+ +

Lispbox is a version of Lisp in a Box, which was originally created +by Matthew Danish and Mikel Evins, customized for use +with Practical Common +Lisp.

+ +

The purpose of Lispbox (and Lisp in a Box) is to get you up and +running in a good Lisp environment as quickly as possible. When you +start Lispbox it launches the text editor Emacs with SLIME (the +Superior Lisp Interaction Mode for Emacs) already installed and starts +Common Lisp for you. Lisp in a Box is designed to not interfere with +your existing Emacs installation, if you have one. If you are already +an Emacs user, you may wish to install the no-Emacs version designed +to work with an existing Emacs installation.

+ +

For more about what Lispbox is, read on; otherwise hop down to +the download section and start +downloading.

+ +

What Lispbox gives you

+ +

A full Lispbox distribtion contains:

+ +
    +
  • Emacs, the powerful, customizable text editor
  • +
  • A Common Lisp implementation of your choosing
  • +
  • SLIME, the Superior Lisp Integration Mode for Emacs
  • +
  • ASDF, Another System Definition Facility, used to load Common + Lisp libraries.
  • +
  • The practical code + from Practical Common + Lisp ready to be loaded using ASDF.
  • +
  • Some glue code to make it all a bit easier to use.
  • +
+ +

When you run the Lispbox application it will start Emacs and start +Common Lisp in SLIME and you're ready to start hacking. You can use +ASDF to load the various libraries and applications from Practical +Common Lisp.

+ +

For instance, to load the test-framework from Chapter 9 you can +type:

+ +
+  (oos 'load-op :test-framework)
+
+ +

at the REPL prompt. Or you can use the SLIME +shortcut load-system available by typing a comma followed +by load-system and then, when prompted, the +name test-framework. (Coming soon: the abilility to load +the code from a specific chapter via a system named chapter-X.)

+ +

As of version 0.3 there are also ASD files named chapter-X +for each chapter. So you can, for instance, load the test framework +codeby typing:

+ +
+  (oos 'load-op :chapter-9)
+
+ + +

Lispbox special features

+ +

The environment provided by Lispbox has a few special features +beyond what you'd get from combining Emacs, SLIME, ASDF, and a Common +Lisp implementation. These features are designed to make it easier to +use, particularly for new Lispers.

+ +
    + +
  • The package CL-USER is "cleaned" of any +implementation-dependent packages. This makes it easier to follow +along the code in the book (particularly in the early chapters before +I've introduced packages) without running into name conflicts with +names exported from implementaton-defined packages that might +otherwise be inherited by CL-USER. This does have +the consequence that certain implementation-specific extensions are +not automatically available. But they can easily be added back once +you know about Common Lisp's package system.
  • + +
  • Lispbox includes some extensions to ASDF that modify how it finds +ASD files and where it stores the files generated +by COMPILE-FILE. The former makes it slightly +easier to install new Common Lisp libraries and, more important, +provides a mechanism that works the same on OS X, GNU/Linux, and +Windows. The latter makes it easier to experiment with different Lisp +implementations since it causes the files generated +by COMPILE-FILE to be placed in an +implementation/operating system/architecture dependent directory.
  • + +
+ +

Download Lispbox

+ +

Lispbox is designed to given you +everything you need to get up and running, hacking Common Lisp, in one +easy-to-install download. However you do need to pick the right +version of Lispbox for the OS you are using and the Common Lisp +implementation you want to try.

+ +

All of the Lisp implementations available here are high-quality +implementations that can be used for learning Lisp and for writing +real applications. However if you want to be able to run all the +practical examples +from Practical Common +Lisp the easiest path is to use Allegro since it supports both +Unicode and threads and has AllegroServe built in. CLISP has excellent +Unicode support but no threads. SBCL added Unicode in version 0.8.17 +but there are still, as of this writing, a few wrinkles to work out. +And it supports threads only on GNU/Linux 2.6 systems running on x86. +OpenMCL supports native threads but not Unicode. The ID3 parser +developed +in Chapter +25 works best in Lisps that support Unicode but will work fine in +non-Unicode Lisps as long as none of the MP3 files you want to parse +contain Unicode strings. And the Shoutcast server developed in +Chapters +28 and +29 +requires an implementation that supports multiple threads.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
OS X (10.4/PPC)OS X (10.4/x86)GNU/Linux x86Windows
Allegro8.0 (get license)8.0 (get license)7.0 (get license)8.0 (get license)
SBCL 0.9.70.9.7
OpenMCL1.0
CLISP2.352.362.37
+ +

To choose a Lisbox, pick the operating +system you are running and the Common Lisp implementation you want to +try. The numbers in the table's cells are the version of the Lisp +implementation. If you choose Allegro on a OS other than Windows you +will need to get a free licence from Franz's web site; click +on get license +to go to the Franz web site. Lispbox will help you install the license +the first time you run it. On Windows the installer will obtain and +install the license for you.

+ +
+ +

Since Lispbox is designed primarily for folks who haven't used +Emacs before (or who just want to try out Lisp without mucking with +their existing Emacs setup) it is designed to work completely +standalone. This should increase the liklihood that it'll Just Work. +However this does mean that it doesn't load your ~/.emacs +file if you have one. Of course if you know enough to have +a ~/.emacs you can probably figure out how to change +that. Note: I used to provide Lispbox distributions intended to be +loaded into an existing Emacs installation. I'm dropping support for +those for the time being as very few people seemed to use them and +they mostly just confused people.

+ + + diff --git a/make-distro-from-cvs.sh b/make-distro-from-cvs.sh new file mode 100755 index 0000000..146400e --- /dev/null +++ b/make-distro-from-cvs.sh @@ -0,0 +1,27 @@ +#!/bin/sh + +if [ -z "$1" ]; then + echo "Must provide CVS directory." + exit 1; +fi + +cvs=$1 + +(cd $cvs; cvs update -dAP) + +base=`basename $cvs` +label=`date -u +"%Y%m%d.%H%M%S"` + +dir="${base}-${label}" + +if [ -d ${dir} ]; then + echo "${dir} already exists." + exit 1; +fi + +mkdir -p /tmp/$dir +(cd /tmp/$dir; (cd $cvs; tar cf - .) | tar xf -) +(cd /tmp/; tar czf $dir.tar.gz $dir) +mv /tmp/$dir.tar.gz . +echo $dir.tar.gz + diff --git a/new-lispbox-register.el b/new-lispbox-register.el new file mode 100644 index 0000000..22eb5d2 --- /dev/null +++ b/new-lispbox-register.el @@ -0,0 +1,8 @@ + +(push (list + 'clisp-2.35 + (list + (lispbox-list-to-filename (list (file-name-directory load-file-name) "bin" "clisp")) + "-ansi" "-K" "full" "-B" + (lispbox-list-to-filename (list (file-name-directory load-file-name) "lib" "clisp")))) + slime-lisp-implementations) \ No newline at end of file diff --git a/new-lispbox.bat b/new-lispbox.bat new file mode 100644 index 0000000..d6052f2 --- /dev/null +++ b/new-lispbox.bat @@ -0,0 +1,31 @@ +@echo off +if NOT %OS%==Windows_NT goto checkhome +for %%i in ( "%CD%" ) do set LISPBOX_HOME=%%~si% + +echo lispbox home is set to %LISPBOX_HOME% +goto start + +:checkhome + +rem +rem if the environment variable is not defined, dereferencing +rem it produces the same string! +rem + +if %LISPBOX_HOME%==%LISPBOX_HOME% goto noenv +:start + +set EMACS=%LISPBOX_HOME%/emacs-21.3/bin/runemacs.exe +set TO_EVAL="(progn (load \"lispbox\") (slime))" + +%EMACS% --no-init-file --no-site-file --eval=%TO_EVAL% + +goto end + +:noenv + +echo LISPBOX_HOME environment variable should be set and +echo point to the installation directory of LISPBOX before +echo launching this command. + +:end \ No newline at end of file diff --git a/no-windows.html b/no-windows.html new file mode 100644 index 0000000..d9aa8ed --- /dev/null +++ b/no-windows.html @@ -0,0 +1,60 @@ + + +Why No Windows Lispbox? + + + + +

Why No Windows Lispbox?

+ +

So here's my lame yet lengthy excuse for why there's still no +Windows version of Lispbox. To start with I don't have a Windows box. +I thought I'd go over to a friend's house to do it but I've been busy +with other stuff (such as trying to make some money know that I'm not +working on the book full time) and haven't been able to. So then I +thought, Hey, much as I hate the thought of sending any money to +Redmond, I'll buy a copy of Windows and run it on VMWare on my Linux +box. Great idea. However my Linux box is all kinds of old having been +untouched since it came from Dell before I started working on the +book. Perhaps because of that or simply of some mismatch between the +Linux header files and the actual running kernel, I can't install +VMWare on it. So now the following steps are on my todo list, leading, +eventually, to Windows Lispboxen: + +

    +
  1. Make sure all my valuable data on my Linux box is backed up + somewhere.
  2. + +
  3. Move my day-to-day necessities such as email and my + development tools onto another machine so I can keep + working.
  4. + +
  5. Install Ubuntu on my Linux box. Hopefully this will get + me up to date and with proper header files so I can install + VMWare.
  6. + +
  7. Install VMWare.
  8. + +
  9. Grit teeth, buy and install Windows XP on + VMWare
  10. + +
  11. Install all the development foo I need, such as cygwin
  12. + +
  13. Dork around with Lispbox build process to make it work on + Windows
  14. + +
+ +

At that point I should be ready to build and publish Windows +Lispboxen. I readily stipulate that I suck in many ways for not +getting this done more promptly. If anyone wants to grab +the Lispbox +sources and send me some patches to help out with the step seven +they should feel more than welcome to do so.

+ +

Enough of these lame excuses! Back to main Lispbox page. + +

+ + diff --git a/notes.txt b/notes.txt new file mode 100644 index 0000000..2344653 --- /dev/null +++ b/notes.txt @@ -0,0 +1,116 @@ +-*- mode: outline; -*- + +* How this all works + +The basic theory of building Lispbox is to build or unpack all the +individual components (emacs, a Lisp, SLIME, etc.) from official +distributions (preferred) or sometimes from CVS sources and then knit +them together. + +For each component we start from some archive of either the sources or +a binary distribution, usually a tar.gz or tar.bz2 file. We need these +archives to be named so that they unpack into a directory named the +same as the archive minus the .tar.gz, or whatever, extension. If we +want to build components from CVS sources, we use the shell script +make-distro-from-cvs.sh to make a tar.gz from the contents of a CVS +directory with the current date and time as a version number. + +* Caveats + +** Libraries + +On GNU/Linux some of the components depend on libraries that I presume +are dynamically linked to the executable. Which means that the +binaries we provide won't run on boxes that don't have those libraries +installed. Here are a couple of libs I know I installed in order to +get things working on my Ubuntu Edge Eft box. + +*** For emacs + +libxt-dev (the X toolkit intrinsics). The non-dev libs were already +installed, by default I think, so maybe this will be fine, at least +for Ubuntu users. + +*** For CLISP + +libsigsegv-dev. This one should get statically linked into the CLISP +exe according to the libsigsegv web page. + + +** Emacs + +The emacs distros version numbers are confusing. The current version +of Emacs is essentially the 21.3 version originally released 24 March +2003. However in February 2006 a bug was discovered that lead to a +serious security hole on Unix platforms which caused Stallman to +release a 21.4 release which was really just 21.3 plus a patch for +that one bug. (This caused all kinds of chaos because everyone was +expecting the long-awaited (and still waiting) Emacs release to be +21.4.) However since the bug was Unix specific the Windows binary +releases, which I use for building the Windows Lispboxen, were not +rebuilt and thus version number of the latest emacs on Windows. To +make matters worse, for reasons I don't recall, the 21.4 source +archive downloadable from the FSF is called "emacs-21.4a.tar.gz" even +though it still unpacks into a directory named "emacs-21.4". So to +prepare to build a Unix Lispbox you need to download the 21.4a archive +and rename it to "emacs-21.4.tar.gz" and set GNU_LINUX_EMACS_VERSION +to 21.4 in GNUmakefile. OS X you have to use CVS emacs (which will be +22.0 if and when it is ever released.) because 21.4 doesn't build out +of the box on OS X. (When I was originally building Lispbox in 2005 I +figured 22.0 would be released at any moment and hoped it would happen +before my book was published so I could build Lispboxen on Windows, +GNU/Linux, and OS X all using the same--and an officially +released--version of Emacs. Two years later the world is still +awaiting 22.0 and 21.3, a.k.a 21.4 is weeks away from being four-years +old.) + + +* Todo + + +- Add entries to emacs's dir file to add a Lisp in a Box section with + the info files for SLIME and such Lisp's as have them. + +- Make HTML index to HTML docs. + +- Add hook to SLIME (if there isn't one) when it shuts down. Then hook + it up to quit emacs when you quit SLIME. + +- Figure out how SLIME finds ~/.swank.lisp so it can find it in the + lispbox dir. + +- Add foo to SLIME doc makefile to cleanup docs directory after + building. And use it. + +- Add OpenMCL to OS X build. + +- How to find Lisps relative to Emacs? Set LISPBOX_HOME environment + variable. Then set variables elisp variables with the names of each + implementation. + +- Implement lispbox-install-allegro-license function. + +- Make .asd files automatically open in lisp-mode. + +- SBCL needs SBCL_HOME set. + +- CLISP works from anywhere. + +- To build an installable .pkg on Emacs seems like we can take apart + the Emacs.pkg we get by mounting the EmacsInstaller.dmg (much like + we already do) and then messing with the contents of Emacs.app and + packaging it back up. The only trick is that then all files, + including SLIME and the Common Lisp implementation need to go inside + Emacs.app (or Lispbox.app) which is maybe not as cool. Probably the + right thing to do is to make a "metapackage". Hmmm. + +- Need to do something about (require 'aserve) for non-Allegro lisps. + Include Portable Allegro Serve in those lisps. + +- *silence-mp3* in Chapter29/playlist.lisp needs to be set before + :mp3-browser system can be loadad. Just document? + +- Enhance SLIME to compile files into fasl directories like ASDF-EXTENSIONS does. + +- NoEmacs Lispbox shouldn't start Lisp right away. (I.e. lispbox.el + needs to be a bit different.) diff --git a/osx-build-flag.txt b/osx-build-flag.txt new file mode 100644 index 0000000..091a61d --- /dev/null +++ b/osx-build-flag.txt @@ -0,0 +1,179 @@ +Path: news.gmane.org!not-for-mail +From: David Reitter +Newsgroups: gmane.emacs.devel +Subject: Re: MacOSX emacs crashes after 10.4.3 update +Date: Fri, 4 Nov 2005 20:14:30 +0000 +Lines: 111 +Approved: news@gmane.org +Message-ID: <9E9973F2-1F72-4DAB-A7E3-0C718917F586@gmail.com> +References: +NNTP-Posting-Host: main.gmane.org +Mime-Version: 1.0 (Apple Message framework v746.2) +Content-Type: multipart/mixed; boundary="===============1535739518==" +X-Trace: sea.gmane.org 1131135447 3538 80.91.229.2 (4 Nov 2005 20:17:27 GMT) +X-Complaints-To: usenet@sea.gmane.org +NNTP-Posting-Date: Fri, 4 Nov 2005 20:17:27 +0000 (UTC) +Cc: emacs-devel@gnu.org +Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Fri Nov 04 21:17:23 2005 +Return-path: +Original-Received: from lists.gnu.org ([199.232.76.165]) + by ciao.gmane.org with esmtp (Exim 4.43) + id 1EY7xZ-0000r8-Ia + for ged-emacs-devel@m.gmane.org; Fri, 04 Nov 2005 21:14:49 +0100 +Original-Received: from localhost ([127.0.0.1] helo=lists.gnu.org) + by lists.gnu.org with esmtp (Exim 4.43) + id 1EY7xY-0000HN-Tp + for ged-emacs-devel@m.gmane.org; Fri, 04 Nov 2005 15:14:48 -0500 +Original-Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) + id 1EY7xM-0000H8-4b + for emacs-devel@gnu.org; Fri, 04 Nov 2005 15:14:36 -0500 +Original-Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) + id 1EY7xK-0000Gw-H8 + for emacs-devel@gnu.org; Fri, 04 Nov 2005 15:14:35 -0500 +Original-Received: from [199.232.76.173] (helo=monty-python.gnu.org) + by lists.gnu.org with esmtp (Exim 4.43) id 1EY7xK-0000Gt-9T + for emacs-devel@gnu.org; Fri, 04 Nov 2005 15:14:34 -0500 +Original-Received: from [64.233.182.205] (helo=nproxy.gmail.com) + by monty-python.gnu.org with esmtp (Exim 4.34) id 1EY7xJ-0003m0-VU + for emacs-devel@gnu.org; Fri, 04 Nov 2005 15:14:34 -0500 +Original-Received: by nproxy.gmail.com with SMTP id o60so180828nfa + for ; Fri, 04 Nov 2005 12:14:32 -0800 (PST) +DomainKey-Signature: a=rsa-sha1; q=dns; c=nofws; s=beta; d=gmail.com; + h=received:in-reply-to:references:mime-version:content-type:message-id:cc:from:subject:date:to:x-mailer; + b=UF8j80O4u5Vq6gtJRkW+otRW1GPYrOk7hpO6qXg85Yl85VNimnrj7OrypIxhYq8d1e8EStf08sNMwaYkI1c3u4/tyX/JTKV5p4y1U1pYVcXxPouo90FLZHdMXfWk9rHcGQ0ZpCVtIcLjmMy/+kfxVt+0CxWprqgXEGXDY9mlWSQ= +Original-Received: by 10.48.80.15 with SMTP id d15mr81295nfb; + Fri, 04 Nov 2005 12:14:32 -0800 (PST) +Original-Received: from ?129.215.174.81? ( [129.215.174.81]) + by mx.gmail.com with ESMTP id q27sm1653847nfc.2005.11.04.12.14.31; + Fri, 04 Nov 2005 12:14:31 -0800 (PST) +In-Reply-To: +Original-To: Ken Raeburn +X-Mailer: Apple Mail (2.746.2) +X-BeenThere: emacs-devel@gnu.org +X-Mailman-Version: 2.1.5 +Precedence: list +List-Id: "Emacs development discussions." +List-Unsubscribe: , + +List-Archive: +List-Post: +List-Help: +List-Subscribe: , + +Original-Sender: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org +Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org +Xref: news.gmane.org gmane.emacs.devel:45414 +Archived-At: + + +--===============1535739518== +Content-Type: multipart/signed; micalg=sha1; boundary=Apple-Mail-18-356732287; + protocol="application/pkcs7-signature" + + +--Apple-Mail-18-356732287 +Content-Transfer-Encoding: 7bit +Content-Type: text/plain; + charset=US-ASCII; + delsp=yes; + format=flowed + +On 4 Nov 2005, at 19:38, Ken Raeburn wrote: + +> I have an EmacsInstaller.dmg that I built on Sep 23, which +> installed an Emacs.app that worked just fine, up until earlier +> today when I updated my OS from 10.4.2 to 10.4.3. It was built +> with mac/make-package, I think with defaults except for telling it +> to build a self-contained app. Now it crashes at startup, and the +> CrashReporter log can't even give me a stack trace: + +This is unfortunate, but seems to be a known problem. Similarly, +binaries built on 10.4 generally don't run on 10.3. + +The Mac port contains a lot of code to support ancient systems / +system APIs like MacOS 8/9, apparently even without CarbonLib (never +tried, though), but there is pretty much no binary compatibility +between OS versions for Emacs. + +Have you tried setting the environment variable +MACOSX_DEPLOYMENT_TARGET=10.4 ? +E.g. + +MACOSX_DEPLOYMENT_TARGET=10.4 ./make-package (...) + +I heard that helps you build binaries that run on all 10.4 versions. + + + + + +--Apple-Mail-18-356732287 +Content-Transfer-Encoding: base64 +Content-Type: application/pkcs7-signature; + name=smime.p7s +Content-Disposition: attachment; + filename=smime.p7s + +MIAGCSqGSIb3DQEHAqCAMIACAQExCzAJBgUrDgMCGgUAMIAGCSqGSIb3DQEHAQAAoIIGOzCCAvQw +ggJdoAMCAQICAw3xWjANBgkqhkiG9w0BAQQFADBiMQswCQYDVQQGEwJaQTElMCMGA1UEChMcVGhh +d3RlIENvbnN1bHRpbmcgKFB0eSkgTHRkLjEsMCoGA1UEAxMjVGhhd3RlIFBlcnNvbmFsIEZyZWVt +YWlsIElzc3VpbmcgQ0EwHhcNMDUwMjAxMjM0NTA0WhcNMDYwMjAxMjM0NTA0WjBiMRAwDgYDVQQE +EwdSZWl0dGVyMQ4wDAYDVQQqEwVEYXZpZDEWMBQGA1UEAxMNRGF2aWQgUmVpdHRlcjEmMCQGCSqG +SIb3DQEJARYXZGF2aWQucmVpdHRlckBnbWFpbC5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw +ggEKAoIBAQDhuoehK+SM/uai1CMVwn3NgRTTwqPpEBKKrr0RKTwxn+B9KFHUK033x4cV1zF4NsHx +t8OG7uk25ZRnBdf2xGC4Dmz2LiGKKhps+EkGzxFuKA3Q8WbXv7stEsS1ALl/mapcaOXTukzKGcu9 +wYFpmSi+PMc/61Th7A9T3bBNQcC2rKuILcaB3GM4ajekoEKFEPx/sTtMhGOLLwb5JcrWhxD0ADIA +S1woY1PS3BJ4YTzPPkZMul46s7riV6CPd2gjnSn2aGvgXHTOHz7tOWmD4phVZ/THQ7nGLnIPy7gi +HfXKvJ3IlM2NcHrgAGMNHaDwSWkdNdNhFe2rsoGTvLRF/fXVAgMBAAGjNDAyMCIGA1UdEQQbMBmB +F2RhdmlkLnJlaXR0ZXJAZ21haWwuY29tMAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcNAQEEBQADgYEA +QxQdE8kyJWkgofiVLxnFYttKuNAkgP0vumRW7Jxc93TX56z3Y6j0pZiYFQcTOYkjdWFsPUSDdnIl +X26P8/ZiCDosSNAeXHaizmoNjl+RkopgKxC7Th6hY0ZrEC5e0733wzeB8O8L05JX1x7KSMrjjX/s +i5F5LSZMRP+o63kulIQwggM/MIICqKADAgECAgENMA0GCSqGSIb3DQEBBQUAMIHRMQswCQYDVQQG +EwJaQTEVMBMGA1UECBMMV2VzdGVybiBDYXBlMRIwEAYDVQQHEwlDYXBlIFRvd24xGjAYBgNVBAoT +EVRoYXd0ZSBDb25zdWx0aW5nMSgwJgYDVQQLEx9DZXJ0aWZpY2F0aW9uIFNlcnZpY2VzIERpdmlz +aW9uMSQwIgYDVQQDExtUaGF3dGUgUGVyc29uYWwgRnJlZW1haWwgQ0ExKzApBgkqhkiG9w0BCQEW +HHBlcnNvbmFsLWZyZWVtYWlsQHRoYXd0ZS5jb20wHhcNMDMwNzE3MDAwMDAwWhcNMTMwNzE2MjM1 +OTU5WjBiMQswCQYDVQQGEwJaQTElMCMGA1UEChMcVGhhd3RlIENvbnN1bHRpbmcgKFB0eSkgTHRk +LjEsMCoGA1UEAxMjVGhhd3RlIFBlcnNvbmFsIEZyZWVtYWlsIElzc3VpbmcgQ0EwgZ8wDQYJKoZI +hvcNAQEBBQADgY0AMIGJAoGBAMSmPFVzVftOucqZWh5owHUEcJ3f6f+jHuy9zfVb8hp2vX8MOmHy +v1HOAdTlUAow1wJjWiyJFXCO3cnwK4Vaqj9xVsuvPAsH5/EfkTYkKhPPK9Xzgnc9A74r/rsYPge/ +QIACZNenprufZdHFKlSFD0gEf6e20TxhBEAeZBlyYLf7AgMBAAGjgZQwgZEwEgYDVR0TAQH/BAgw +BgEB/wIBADBDBgNVHR8EPDA6MDigNqA0hjJodHRwOi8vY3JsLnRoYXd0ZS5jb20vVGhhd3RlUGVy +c29uYWxGcmVlbWFpbENBLmNybDALBgNVHQ8EBAMCAQYwKQYDVR0RBCIwIKQeMBwxGjAYBgNVBAMT +EVByaXZhdGVMYWJlbDItMTM4MA0GCSqGSIb3DQEBBQUAA4GBAEiM0VCD6gsuzA2jZqxnD3+vrL7C +F6FDlpSdf0whuPg2H6otnzYvwPQcUCCTcDz9reFhYsPZOhl+hLGZGwDFGguCdJ4lUJRix9sncVcl +jd2pnDmOjCBPZV+V2vf3h9bGCE6u9uo05RAaWzVNd+NWIXiC3CEZNd4ksdMdRv9dX2VPMYIC5zCC +AuMCAQEwaTBiMQswCQYDVQQGEwJaQTElMCMGA1UEChMcVGhhd3RlIENvbnN1bHRpbmcgKFB0eSkg +THRkLjEsMCoGA1UEAxMjVGhhd3RlIFBlcnNvbmFsIEZyZWVtYWlsIElzc3VpbmcgQ0ECAw3xWjAJ +BgUrDgMCGgUAoIIBUzAYBgkqhkiG9w0BCQMxCwYJKoZIhvcNAQcBMBwGCSqGSIb3DQEJBTEPFw0w +NTExMDQyMDE0MzFaMCMGCSqGSIb3DQEJBDEWBBToxbPbP033uTQnUpYmNVObMhWe0DB4BgkrBgEE +AYI3EAQxazBpMGIxCzAJBgNVBAYTAlpBMSUwIwYDVQQKExxUaGF3dGUgQ29uc3VsdGluZyAoUHR5 +KSBMdGQuMSwwKgYDVQQDEyNUaGF3dGUgUGVyc29uYWwgRnJlZW1haWwgSXNzdWluZyBDQQIDDfFa +MHoGCyqGSIb3DQEJEAILMWugaTBiMQswCQYDVQQGEwJaQTElMCMGA1UEChMcVGhhd3RlIENvbnN1 +bHRpbmcgKFB0eSkgTHRkLjEsMCoGA1UEAxMjVGhhd3RlIFBlcnNvbmFsIEZyZWVtYWlsIElzc3Vp +bmcgQ0ECAw3xWjANBgkqhkiG9w0BAQEFAASCAQATCs+C4U3ls1lxxDeef3kEiF6VV/b8Ok0jKyXU +/29eKt67Jqmqh1MinxxF1MRw9lYFgipJ2UIi0gV+ZzpeOCHsntN1Bup547hjnOU/H2m0sjzQI16k +JA6teCjm6zZQrANCkeaBGNA8C77T2wMJ6VGExwS2QXF0y9BgzEDwTtzm6fQVPT5lj2M7bLIxYHtC +A2YIq2o8aWhn2s8v4TD7kk4TYF7+mAFN1iwVKMhYJlhATBdGxkIfweBHe96/4ZP2h04PpDqjYa/5 +SQAi5v5V7NAkvt5NZZUH3/8IL/IttnsI8r0BHtFDBi4ivjE68Xtf1XM5qaN3tn7/qNLl9L8LY7Bp +AAAAAAAA + +--Apple-Mail-18-356732287-- + + + +--===============1535739518== +Content-Type: text/plain; charset="us-ascii" +MIME-Version: 1.0 +Content-Transfer-Encoding: 7bit +Content-Disposition: inline + +_______________________________________________ +Emacs-devel mailing list +Emacs-devel@gnu.org +http://lists.gnu.org/mailman/listinfo/emacs-devel +--===============1535739518==-- + + + + diff --git a/publish-html.sh b/publish-html.sh new file mode 100755 index 0000000..22437b1 --- /dev/null +++ b/publish-html.sh @@ -0,0 +1,3 @@ +#!/bin/sh + +make -f GNUmakefile.publish \ No newline at end of file diff --git a/relocatable-emacs.sh b/relocatable-emacs.sh new file mode 100644 index 0000000..c630c14 --- /dev/null +++ b/relocatable-emacs.sh @@ -0,0 +1,34 @@ +#!/bin/sh + +#PWD +#SHELL + +export EMACSDATA=${LISPBOX_HOME}/share/emacs/21.4/etc/ + +export EMACSDOC=${LISPBOX_HOME}/share/emacs/21.4/etc/ + +export EMACSLOADPATH=\ +${LISPBOX_HOME}/share/emacs/21.4/site-lisp:\ +${LISPBOX_HOME}/share/emacs/site-lisp:\ +${LISPBOX_HOME}/share/emacs/21.4/leim:\ +${LISPBOX_HOME}/share/emacs/21.4/lisp:\ +${LISPBOX_HOME}/share/emacs/21.4/lisp/toolbar:\ +${LISPBOX_HOME}/share/emacs/21.4/lisp/textmodes:\ +${LISPBOX_HOME}/share/emacs/21.4/lisp/progmodes:\ +${LISPBOX_HOME}/share/emacs/21.4/lisp/play:\ +${LISPBOX_HOME}/share/emacs/21.4/lisp/obsolete:\ +${LISPBOX_HOME}/share/emacs/21.4/lisp/net:\ +${LISPBOX_HOME}/share/emacs/21.4/lisp/mail:\ +${LISPBOX_HOME}/share/emacs/21.4/lisp/language:\ +${LISPBOX_HOME}/share/emacs/21.4/lisp/international:\ +${LISPBOX_HOME}/share/emacs/21.4/lisp/gnus:\ +${LISPBOX_HOME}/share/emacs/21.4/lisp/eshell:\ +${LISPBOX_HOME}/share/emacs/21.4/lisp/emulation:\ +${LISPBOX_HOME}/share/emacs/21.4/lisp/emacs-lisp:\ +${LISPBOX_HOME}/share/emacs/21.4/lisp/calendar + + +PATH=$PATH:${LISPBOX_HOME}/libexec/emacs/21.4/i686-pc-linux-gnu + + +exec ./bin/emacs --no-init-file --no-site-file diff --git a/site-init.lisp b/site-init.lisp new file mode 100644 index 0000000..f2b0758 --- /dev/null +++ b/site-init.lisp @@ -0,0 +1,54 @@ +(in-package :cl-user) + +#+allegro +(progn + (setf excl::*redefinition-pathname-comparison-hook* + (list #'(lambda (old new obj type) + (declare (ignore obj type)) + (when (and old new) + (string= + (namestring old) + (let ((str (namestring new))) + (subseq str 0 (position #\; str :from-end t)))))))) + (tpl:setq-default *debugger-hook* #'swank:swank-debugger-hook) + (tpl:setq-default *print-length* 10) + (tpl:setq-default *print-level* 5) + (tpl:setq-default *print-circle* nil)) + +(setq *debugger-hook* #'swank:swank-debugger-hook) +(setf *print-length* 10) +(setf *print-level* 5) +(setf *print-circle* nil) + +(setf swank::*swank-pprint-case* :downcase) +(setf swank::*swank-pprint-length* nil) +(setf swank::*swank-pprint-level* nil) +(setf swank::*swank-pprint-circle* nil) + +(defun lispbox-file (relative-pathname) + (merge-pathnames + relative-pathname + (make-pathname + :directory (butlast (pathname-directory *load-pathname*)) + :name nil + :type nil + :defaults *load-pathname*))) + +#-asdf +(progn + (multiple-value-bind (value error) + (ignore-errors (require :asdf)) + (if error + (load (lispbox-file (make-pathname :name "asdf" :type "lisp")))))) + +(load (lispbox-file (make-pathname :name "asdf-extensions" :type "lisp"))) + +;;; Clean up CL-USER package +(loop with cl = (find-package :cl) + for p in (package-use-list :cl-user) + unless (eql p cl) do (unuse-package p :cl-user)) +(use-package :asdf :cl-user) +(use-package :com.gigamonkeys.asdf-extensions :cl-user) + +(register-source-directory (lispbox-file (make-pathname :directory '(:relative "practicals-1.0")))) + diff --git a/style.css b/style.css new file mode 100644 index 0000000..533c7d9 --- /dev/null +++ b/style.css @@ -0,0 +1,51 @@ +body { + margin: .5in 1in; + font-size: 12pt; + font-family: sans-serif; +} +h1, h2, h3, h4, h5, h6 { font-family: Helvetica; } +h1 { font-size: 24pt; } +h2 { font-size: 18pt; } + +li { padding-top: 3pt; } + +pre { margin-left: .25in; font-size: 9pt; } + +tr.table-header { + font-weight: bold; +} + + +table { font-size: 11pt; background: #ccccff; } + +td { background: #ffdddd; padding: 3pt 6pt; } + +td.centered { text-align: center; } + +td.impl { font-weight: bold; } + +table.floater { float: left; margin: 0pt 12pt 0pt 6pt; width: 60%; } + +p.download-blurb { font-size: 11pt; } + +div.chunk { clear: both; padding-bottom: 2ex; } + +p.back { font-size: 11pt; } + +.note { + border-width: thin; + border-style: solid; + margin: 1ex; + padding: 1ex; +} + + +div.copyright { + font-size: 10pt; + font-family: times-roman; + font-style: italic; + text-align: right; + padding-top: 24pt; +} + + diff --git a/write-lispbox-el.sh b/write-lispbox-el.sh new file mode 100644 index 0000000..a9f0aba --- /dev/null +++ b/write-lispbox-el.sh @@ -0,0 +1,56 @@ +#!/bin/sh + +cat <