mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-04-30 03:40:34 +02:00
merge from master to elisp
* module/language/elisp/compile-tree-il.scm: Update for changes to tree-il (lambda-case, mainly). * module/language/elisp/spec.scm: Update GPL version to 3. Update reader for new taking a port and environment argument. * libguile/_scm.h: Bump objcode version. * libguile/vm-i-system.c: Fix conflicts. * module/Makefile.am: Fix conflicts, and add elisp modules to the build.
This commit is contained in:
commit
e42573315b
597 changed files with 39198 additions and 66642 deletions
8
.gitignore
vendored
8
.gitignore
vendored
|
@ -72,6 +72,8 @@ gdb-pre-inst-guile
|
||||||
cscope.out
|
cscope.out
|
||||||
cscope.files
|
cscope.files
|
||||||
*.log
|
*.log
|
||||||
|
gds-test.debug
|
||||||
|
gds-test.transcript
|
||||||
INSTALL
|
INSTALL
|
||||||
*.aux
|
*.aux
|
||||||
*.cp
|
*.cp
|
||||||
|
@ -106,8 +108,14 @@ INSTALL
|
||||||
/lib/time.h
|
/lib/time.h
|
||||||
/lib/unistd.h
|
/lib/unistd.h
|
||||||
/lib/unistr/.dirstamp
|
/lib/unistr/.dirstamp
|
||||||
|
/lib/arpa/inet.h
|
||||||
|
/lib/stdio.h
|
||||||
|
/lib/sys/stat.h
|
||||||
/GPATH
|
/GPATH
|
||||||
/GRTAGS
|
/GRTAGS
|
||||||
/GSYMS
|
/GSYMS
|
||||||
/GTAGS
|
/GTAGS
|
||||||
/meta/guile-tools
|
/meta/guile-tools
|
||||||
|
/meta/guile-config
|
||||||
|
/lib/locale.h
|
||||||
|
/module/ice-9/eval.go.stamp
|
||||||
|
|
1
.gnuploadrc
Normal file
1
.gnuploadrc
Normal file
|
@ -0,0 +1 @@
|
||||||
|
--user ludo@gnu.org
|
4
.x-sc_GPL_version
Normal file
4
.x-sc_GPL_version
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
^lib/
|
||||||
|
^gc-benchmarks/
|
||||||
|
^libguile/libgettext.h
|
||||||
|
^libguile/mkstemp.c
|
1
.x-sc_avoid_if_before_free
Normal file
1
.x-sc_avoid_if_before_free
Normal file
|
@ -0,0 +1 @@
|
||||||
|
^lib/
|
1
.x-sc_cast_of_alloca_return_value
Normal file
1
.x-sc_cast_of_alloca_return_value
Normal file
|
@ -0,0 +1 @@
|
||||||
|
^lib/
|
1
.x-sc_cast_of_argument_to_free
Normal file
1
.x-sc_cast_of_argument_to_free
Normal file
|
@ -0,0 +1 @@
|
||||||
|
^libguile/stime.c
|
1
.x-sc_error_message_period
Normal file
1
.x-sc_error_message_period
Normal file
|
@ -0,0 +1 @@
|
||||||
|
^gc-benchmarks/
|
6
.x-sc_error_message_uppercase
Normal file
6
.x-sc_error_message_uppercase
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
^libguile/
|
||||||
|
^guile-readline/
|
||||||
|
^gc-benchmarks/
|
||||||
|
^emacs/
|
||||||
|
^NEWS
|
||||||
|
^doc/
|
1
.x-sc_error_message_warn_fatal
Normal file
1
.x-sc_error_message_warn_fatal
Normal file
|
@ -0,0 +1 @@
|
||||||
|
^module/ice-9/match.scm
|
1
.x-sc_m4_quote_check
Normal file
1
.x-sc_m4_quote_check
Normal file
|
@ -0,0 +1 @@
|
||||||
|
m4/version-etc.m4
|
3
.x-sc_makefile_check
Normal file
3
.x-sc_makefile_check
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
lib(guile)?/
|
||||||
|
guile-readline/
|
||||||
|
srfi/
|
29
AUTHORS
29
AUTHORS
|
@ -206,8 +206,34 @@ In the subdirectory doc, changes to:
|
||||||
Many changes throughout.
|
Many changes throughout.
|
||||||
|
|
||||||
Neil Jerram:
|
Neil Jerram:
|
||||||
|
In the subdirectory emacs, wrote:
|
||||||
|
gds.el gds-scheme.el gds-server.el
|
||||||
|
gds-test.el gds-test.sh gds-test.stdin
|
||||||
|
gds-tutorial.txt gds-faq.txt
|
||||||
In the subdirectory ice-9, wrote:
|
In the subdirectory ice-9, wrote:
|
||||||
buffered-input.scm
|
buffered-input.scm gds-client.scm gds-server.scm
|
||||||
|
In the subdirectory ice-9/debugging, wrote:
|
||||||
|
example-fns.scm ice-9-debugger-extensions.scm
|
||||||
|
steps.scm trace.scm traps.scm
|
||||||
|
trc.scm
|
||||||
|
In the subdirectory lang/elisp, wrote:
|
||||||
|
base.scm example.el interface.scm
|
||||||
|
transform.scm variables.scm
|
||||||
|
In the subdirectory lang/elisp/internals, wrote:
|
||||||
|
evaluation.scm format.scm fset.scm
|
||||||
|
lambda.scm load.scm null.scm
|
||||||
|
set.scm signal.scm time.scm
|
||||||
|
trace.scm
|
||||||
|
In the subdirectory lang/elisp/primitives, wrote:
|
||||||
|
buffers.scm char-table.scm features.scm
|
||||||
|
fns.scm format.scm guile.scm
|
||||||
|
keymaps.scm lists.scm load.scm
|
||||||
|
match.scm numbers.scm pure.scm
|
||||||
|
read.scm signal.scm strings.scm
|
||||||
|
symprop.scm syntax.scm system.scm
|
||||||
|
time.scm
|
||||||
|
In the subdirectory srfi, wrote:
|
||||||
|
srfi-34.scm
|
||||||
In the subdirectory doc, wrote:
|
In the subdirectory doc, wrote:
|
||||||
deprecated.texi goops.texi scheme-ideas.texi
|
deprecated.texi goops.texi scheme-ideas.texi
|
||||||
scheme-reading.texi
|
scheme-reading.texi
|
||||||
|
@ -227,6 +253,7 @@ In the subdirectory doc, changes to:
|
||||||
scm.texi scripts.texi script-getopt.texi
|
scm.texi scripts.texi script-getopt.texi
|
||||||
In the subdirectory doc/maint, wrote:
|
In the subdirectory doc/maint, wrote:
|
||||||
docstring.el
|
docstring.el
|
||||||
|
Many other changes throughout.
|
||||||
|
|
||||||
Thien-Thi Nguyen:
|
Thien-Thi Nguyen:
|
||||||
In the top-level directory, wrote:
|
In the top-level directory, wrote:
|
||||||
|
|
127
GNUmakefile
Normal file
127
GNUmakefile
Normal file
|
@ -0,0 +1,127 @@
|
||||||
|
# Having a separate GNUmakefile lets me `include' the dynamically
|
||||||
|
# generated rules created via cfg.mk (package-local configuration)
|
||||||
|
# as well as maint.mk (generic maintainer rules).
|
||||||
|
# This makefile is used only if you run GNU Make.
|
||||||
|
# It is necessary if you want to build targets usually of interest
|
||||||
|
# only to the maintainer.
|
||||||
|
|
||||||
|
# Copyright (C) 2001, 2003, 2006-2009 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
# Systems where /bin/sh is not the default shell need this. The $(shell)
|
||||||
|
# command below won't work with e.g. stock DOS/Windows shells.
|
||||||
|
ifeq ($(wildcard /bin/s[h]),/bin/sh)
|
||||||
|
SHELL = /bin/sh
|
||||||
|
else
|
||||||
|
# will be used only with the next shell-test line, then overwritten
|
||||||
|
# by a configured-in value
|
||||||
|
SHELL = sh
|
||||||
|
endif
|
||||||
|
|
||||||
|
# If the user runs GNU make but has not yet run ./configure,
|
||||||
|
# give them a diagnostic.
|
||||||
|
_have-Makefile := $(shell test -f Makefile && echo yes)
|
||||||
|
ifeq ($(_have-Makefile),yes)
|
||||||
|
|
||||||
|
# Make tar archive easier to reproduce.
|
||||||
|
export TAR_OPTIONS = --owner=0 --group=0 --numeric-owner
|
||||||
|
|
||||||
|
# Allow the user to add to this in the Makefile.
|
||||||
|
ALL_RECURSIVE_TARGETS =
|
||||||
|
|
||||||
|
include Makefile
|
||||||
|
|
||||||
|
# Some projects override e.g., _autoreconf here.
|
||||||
|
-include $(srcdir)/cfg.mk
|
||||||
|
include $(srcdir)/maint.mk
|
||||||
|
|
||||||
|
# Allow cfg.mk to override these.
|
||||||
|
_build-aux ?= build-aux
|
||||||
|
_autoreconf ?= autoreconf
|
||||||
|
|
||||||
|
# Ensure that $(VERSION) is up to date for dist-related targets, but not
|
||||||
|
# for others: rerunning autoreconf and recompiling everything isn't cheap.
|
||||||
|
_have-git-version-gen := \
|
||||||
|
$(shell test -f $(srcdir)/$(_build-aux)/git-version-gen && echo yes)
|
||||||
|
ifeq ($(_have-git-version-gen)0,yes$(MAKELEVEL))
|
||||||
|
_is-dist-target ?= $(filter-out %clean, \
|
||||||
|
$(filter maintainer-% dist% alpha beta major,$(MAKECMDGOALS)))
|
||||||
|
_is-install-target ?= $(filter-out %check, $(filter install%,$(MAKECMDGOALS)))
|
||||||
|
ifneq (,$(_is-dist-target)$(_is-install-target))
|
||||||
|
_curr-ver := $(shell cd $(srcdir) \
|
||||||
|
&& $(_build-aux)/git-version-gen .tarball-version)
|
||||||
|
ifneq ($(_curr-ver),$(VERSION))
|
||||||
|
ifeq ($(_curr-ver),UNKNOWN)
|
||||||
|
$(info WARNING: unable to verify if $(VERSION) is the correct version)
|
||||||
|
else
|
||||||
|
ifneq (,$(_is-install-target))
|
||||||
|
# GNU Coding Standards state that 'make install' should not cause
|
||||||
|
# recompilation after 'make all'. But as long as changing the version
|
||||||
|
# string alters config.h, the cost of having 'make all' always have an
|
||||||
|
# up-to-date version is prohibitive. So, as a compromise, we merely
|
||||||
|
# warn when installing a version string that is out of date; the user
|
||||||
|
# should run 'autoreconf' (or something like 'make distcheck') to
|
||||||
|
# fix the version, 'make all' to propagate it, then 'make install'.
|
||||||
|
$(info WARNING: version string $(VERSION) is out of date;)
|
||||||
|
$(info run '$(MAKE) _version' to fix it)
|
||||||
|
else
|
||||||
|
$(info INFO: running autoreconf for new version string: $(_curr-ver))
|
||||||
|
_dummy := $(shell $(MAKE) $(AM_MAKEFLAGS) _version)
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
.PHONY: _version
|
||||||
|
_version:
|
||||||
|
cd $(srcdir) && rm -rf autom4te.cache .version && $(_autoreconf)
|
||||||
|
|
||||||
|
else
|
||||||
|
|
||||||
|
.DEFAULT_GOAL := abort-due-to-no-makefile
|
||||||
|
srcdir = .
|
||||||
|
|
||||||
|
# The package can override .DEFAULT_GOAL to run actions like autoreconf.
|
||||||
|
-include ./cfg.mk
|
||||||
|
include ./maint.mk
|
||||||
|
|
||||||
|
ifeq ($(.DEFAULT_GOAL),abort-due-to-no-makefile)
|
||||||
|
$(MAKECMDGOALS): abort-due-to-no-makefile
|
||||||
|
endif
|
||||||
|
|
||||||
|
abort-due-to-no-makefile:
|
||||||
|
@echo There seems to be no Makefile in this directory. 1>&2
|
||||||
|
@echo "You must run ./configure before running \`make'." 1>&2
|
||||||
|
@exit 1
|
||||||
|
|
||||||
|
endif
|
||||||
|
|
||||||
|
# Tell version 3.79 and up of GNU make to not build goals in this
|
||||||
|
# directory in parallel, in case someone tries to build multiple
|
||||||
|
# targets, and one of them can cause a recursive target to be invoked.
|
||||||
|
|
||||||
|
# Only set this if Automake doesn't provide it.
|
||||||
|
AM_RECURSIVE_TARGETS ?= $(RECURSIVE_TARGETS:-recursive=) \
|
||||||
|
$(RECURSIVE_CLEAN_TARGETS:-recursive=) \
|
||||||
|
dist distcheck tags ctags
|
||||||
|
|
||||||
|
ALL_RECURSIVE_TARGETS += $(AM_RECURSIVE_TARGETS)
|
||||||
|
|
||||||
|
ifneq ($(word 2, $(MAKECMDGOALS)), )
|
||||||
|
ifneq ($(filter $(ALL_RECURSIVE_TARGETS), $(MAKECMDGOALS)), )
|
||||||
|
.NOTPARALLEL:
|
||||||
|
endif
|
||||||
|
endif
|
|
@ -2,15 +2,11 @@
|
||||||
|
|
||||||
GUILE_MAJOR_VERSION=1
|
GUILE_MAJOR_VERSION=1
|
||||||
GUILE_MINOR_VERSION=9
|
GUILE_MINOR_VERSION=9
|
||||||
GUILE_MICRO_VERSION=2
|
GUILE_MICRO_VERSION=5
|
||||||
|
|
||||||
GUILE_EFFECTIVE_VERSION=${GUILE_MAJOR_VERSION}.${GUILE_MINOR_VERSION}
|
GUILE_EFFECTIVE_VERSION=${GUILE_MAJOR_VERSION}.${GUILE_MINOR_VERSION}
|
||||||
GUILE_VERSION=${GUILE_EFFECTIVE_VERSION}.${GUILE_MICRO_VERSION}
|
GUILE_VERSION=${GUILE_EFFECTIVE_VERSION}.${GUILE_MICRO_VERSION}
|
||||||
|
|
||||||
# For automake.
|
|
||||||
VERSION=${GUILE_VERSION}
|
|
||||||
PACKAGE=guile
|
|
||||||
|
|
||||||
# All of the shared lib versioning info. Right now, for this to work
|
# All of the shared lib versioning info. Right now, for this to work
|
||||||
# properly, you'll also need to add AC_SUBST calls to the right place
|
# properly, you'll also need to add AC_SUBST calls to the right place
|
||||||
# in configure.in, add the right -version-info statement to your
|
# in configure.in, add the right -version-info statement to your
|
||||||
|
@ -54,9 +50,3 @@ LIBGUILE_SRFI_SRFI_60_INTERFACE_CURRENT=3
|
||||||
LIBGUILE_SRFI_SRFI_60_INTERFACE_REVISION=0
|
LIBGUILE_SRFI_SRFI_60_INTERFACE_REVISION=0
|
||||||
LIBGUILE_SRFI_SRFI_60_INTERFACE_AGE=0
|
LIBGUILE_SRFI_SRFI_60_INTERFACE_AGE=0
|
||||||
LIBGUILE_SRFI_SRFI_60_INTERFACE="${LIBGUILE_SRFI_SRFI_60_INTERFACE_CURRENT}:${LIBGUILE_SRFI_SRFI_60_INTERFACE_REVISION}:${LIBGUILE_SRFI_SRFI_60_INTERFACE_AGE}"
|
LIBGUILE_SRFI_SRFI_60_INTERFACE="${LIBGUILE_SRFI_SRFI_60_INTERFACE_CURRENT}:${LIBGUILE_SRFI_SRFI_60_INTERFACE_REVISION}:${LIBGUILE_SRFI_SRFI_60_INTERFACE_AGE}"
|
||||||
|
|
||||||
LIBGUILE_I18N_MAJOR=0
|
|
||||||
LIBGUILE_I18N_INTERFACE_CURRENT=0
|
|
||||||
LIBGUILE_I18N_INTERFACE_REVISION=0
|
|
||||||
LIBGUILE_I18N_INTERFACE_AGE=0
|
|
||||||
LIBGUILE_I18N_INTERFACE="${LIBGUILE_I18N_INTERFACE_CURRENT}:${LIBGUILE_INTERFACE_REVISION}:${LIBGUILE_I18N_INTERFACE_AGE}"
|
|
||||||
|
|
|
@ -25,7 +25,7 @@
|
||||||
AUTOMAKE_OPTIONS = 1.10
|
AUTOMAKE_OPTIONS = 1.10
|
||||||
|
|
||||||
SUBDIRS = lib meta libguile guile-readline emacs \
|
SUBDIRS = lib meta libguile guile-readline emacs \
|
||||||
srfi doc examples test-suite benchmark-suite lang am \
|
srfi doc examples test-suite benchmark-suite am \
|
||||||
module testsuite
|
module testsuite
|
||||||
|
|
||||||
include_HEADERS = libguile.h
|
include_HEADERS = libguile.h
|
||||||
|
@ -40,6 +40,8 @@ ACLOCAL_AMFLAGS = -I m4
|
||||||
|
|
||||||
DISTCLEANFILES = check-guile.log
|
DISTCLEANFILES = check-guile.log
|
||||||
|
|
||||||
|
DISTCHECK_CONFIGURE_FLAGS = --enable-error-on-warning
|
||||||
|
|
||||||
dist-hook: gen-ChangeLog
|
dist-hook: gen-ChangeLog
|
||||||
|
|
||||||
clean-local:
|
clean-local:
|
||||||
|
|
368
NEWS
368
NEWS
|
@ -8,31 +8,157 @@ Please send Guile bug reports to bug-guile@gnu.org.
|
||||||
(During the 1.9 series, we will keep an incremental NEWS for the latest
|
(During the 1.9 series, we will keep an incremental NEWS for the latest
|
||||||
prerelease, and a full NEWS corresponding to 1.8 -> 2.0.)
|
prerelease, and a full NEWS corresponding to 1.8 -> 2.0.)
|
||||||
|
|
||||||
Changes in 1.9.3 (since the 1.9.2 prerelease):
|
Changes in 1.9.5 (since the 1.9.4 prerelease):
|
||||||
|
|
||||||
** Removed deprecated uniform array procedures: scm_make_uve,
|
** Compiled procedures may now have more than one arity.
|
||||||
scm_array_prototype, scm_list_to_uniform_array,
|
|
||||||
scm_dimensions_to_uniform_array, scm_make_ra, scm_shap2ra, scm_cvref,
|
|
||||||
scm_ra_set_contp, scm_aind, scm_raprin1
|
|
||||||
|
|
||||||
These functions have been deprecated since early 2005.
|
This can be the case, for example, in case-lambda procedures. The
|
||||||
|
arities of compiled procedures may be accessed via procedures from the
|
||||||
|
`(system vm program)' module; see "Compiled Procedures", "Optional
|
||||||
|
Arguments", and "Case-lambda" in the manual.
|
||||||
|
|
||||||
** scm_array_p has one argument, not two
|
** `case-lambda' is now available in the default environment.
|
||||||
|
|
||||||
Use of the second argument produced a deprecation warning, so it is
|
The binding in the default environment is equivalent to the one from the
|
||||||
unlikely that any code out there actually used this functionality.
|
`(srfi srfi-16)' module. Use the srfi-16 module explicitly if you wish
|
||||||
|
to maintain compatibility with Guile 1.8 and earlier.
|
||||||
|
|
||||||
** Removed deprecated uniform array procedures:
|
** VM calling convention change: callee-parsed arguments
|
||||||
dimensions->uniform-array, list->uniform-array, array-prototype
|
|
||||||
|
|
||||||
Instead, use make-typed-array, list->typed-array, or array-type,
|
As an internal implementation detail, compiled procedures are now
|
||||||
respectively.
|
responsible for parsing their own arguments, which they receive on the
|
||||||
|
stack.
|
||||||
|
|
||||||
|
** VM support for multiple-arity dispatch
|
||||||
|
|
||||||
|
Calls to procedures with multiple arities, for example those made be
|
||||||
|
`case-lambda', now dispatch via special opcodes, without the need to
|
||||||
|
cons a rest list.
|
||||||
|
|
||||||
|
** Intermediate language support for multiple-arity procedures.
|
||||||
|
|
||||||
|
In the intermediate language, tree-il, all procedures may have one or
|
||||||
|
more arities. This allows all Guile languages to have multiple arities.
|
||||||
|
It is, however, an incompatible change, and anyone maintaining a
|
||||||
|
compiler out-of-tree would be advised to get it into Guile soon :)
|
||||||
|
|
||||||
|
** `lambda*' and `define*' are now available in the default environment
|
||||||
|
|
||||||
|
As with `case-lambda', `(ice-9 optargs)' continues to be supported, for
|
||||||
|
compatibility purposes. No semantic change has been made (we hope).
|
||||||
|
Optional and keyword arguments now dispatch via special VM operations,
|
||||||
|
without the need to cons rest arguments, making them very fast.
|
||||||
|
|
||||||
|
** Better support for Lisp `nil'.
|
||||||
|
|
||||||
|
The bit representation of `nil' has been tweaked so that it is now very
|
||||||
|
efficient to check e.g. if a value is equal to Scheme's end-of-list or
|
||||||
|
Lisp's nil. Additionally there are a heap of new, specific predicates
|
||||||
|
like scm_is_null_or_nil. Probably in the future we will #define
|
||||||
|
scm_is_null to scm_is_null_or_nil.
|
||||||
|
|
||||||
|
** No future.
|
||||||
|
|
||||||
|
Actually the future is still in the state that it was, is, and ever
|
||||||
|
shall be, Amen, except that `futures.c' and `futures.h' are no longer a
|
||||||
|
part of it. These files were experimental, never compiled, and would be
|
||||||
|
better implemented in Scheme anyway. In the future, that is.
|
||||||
|
|
||||||
|
** Support for static allocation of strings, symbols, and subrs.
|
||||||
|
|
||||||
|
Calls to snarfing CPP macros like SCM_DEFINE macro will now allocate
|
||||||
|
much of their associated data as static variables, reducing Guile's
|
||||||
|
memory footprint.
|
||||||
|
|
||||||
|
** Inline vector allocation
|
||||||
|
|
||||||
|
Instead of having vectors point out into the heap for their data, their
|
||||||
|
data is now allocated inline to the vector object itself. The same is
|
||||||
|
true for bytevectors, by default, though there is an indirection
|
||||||
|
available which should allow for making a bytevector from an existing
|
||||||
|
memory region.
|
||||||
|
|
||||||
|
** New syntax: include-from-path.
|
||||||
|
|
||||||
|
`include-from-path' is like `include', except it looks for its file in
|
||||||
|
the load path. It can be used to compile other files into a file.
|
||||||
|
|
||||||
|
** New syntax: quasisyntax.
|
||||||
|
|
||||||
|
`quasisyntax' is to `syntax' as `quasiquote' is to `quote'. See the R6RS
|
||||||
|
documentation for more information. Thanks to Andre van Tonder for the
|
||||||
|
implementation.
|
||||||
|
|
||||||
|
** Cleanups to Guile's primitive object system.
|
||||||
|
|
||||||
|
There were a number of pieces in `objects.[ch]' that tried to be a
|
||||||
|
minimal object system, but were never documented, and were quickly
|
||||||
|
obseleted by GOOPS' merge into Guile proper. So `scm_make_class_object',
|
||||||
|
`scm_make_subclass_object', `scm_metaclass_standard', and like symbols
|
||||||
|
from objects.h are no more. In the very unlikely case in which these
|
||||||
|
were useful to you, we urge you to contact guile-devel.
|
||||||
|
|
||||||
|
** GOOPS cleanups.
|
||||||
|
|
||||||
|
GOOPS had a number of concepts that were relevant to the days of Tcl,
|
||||||
|
but not any more: operators and entities, mainly. These objects were
|
||||||
|
never documented, and it is unlikely that they were ever used. Operators
|
||||||
|
were a kind of generic specific to the Tcl support. Entities were
|
||||||
|
applicable structures, but were unusable; entities will come back in the
|
||||||
|
next alpha release, but with a less stupid name.
|
||||||
|
|
||||||
|
** Faster bit operations.
|
||||||
|
|
||||||
|
The bit-twiddling operations `ash', `logand', `logior', and `logxor' now
|
||||||
|
have dedicated bytecodes. Guile is not just for symbolic computation,
|
||||||
|
it's for number crunching too.
|
||||||
|
|
||||||
|
** `inet-ntop' and `inet-pton' are always available.
|
||||||
|
|
||||||
|
Guile now use a portable implementation of `inet_pton'/`inet_ntop', so
|
||||||
|
there is no more need to use `inet-aton'/`inet-ntoa'. The latter
|
||||||
|
functions are deprecated.
|
||||||
|
|
||||||
|
** R6RS block comment support
|
||||||
|
|
||||||
|
Guile now supports R6RS nested block comments. The start of a comment is
|
||||||
|
marked with `#|', and the end with `|#'.
|
||||||
|
|
||||||
|
** `guile-2' cond-expand feature
|
||||||
|
|
||||||
|
To test if your code is running under Guile 2.0 (or its alpha releases),
|
||||||
|
test for the `guile-2' cond-expand feature. Like this:
|
||||||
|
|
||||||
|
(cond-expand (guile-2 (eval-when (compile)
|
||||||
|
;; This must be evaluated at compile time.
|
||||||
|
(fluid-set! current-reader my-reader)))
|
||||||
|
(guile
|
||||||
|
;; Earlier versions of Guile do not have a
|
||||||
|
;; separate compilation phase.
|
||||||
|
(fluid-set! current-reader my-reader)))
|
||||||
|
|
||||||
|
** ABI harmonization
|
||||||
|
|
||||||
|
`scm_search_path' now has the signature it did in 1.8, reverting an
|
||||||
|
incompatible change made in 1.9.0.
|
||||||
|
|
||||||
|
** Compile-time warnings: -Warity-mismatch
|
||||||
|
|
||||||
|
Guile can warn when you pass the wrong number of arguments to a
|
||||||
|
procedure. Pass the -Warity-mismatch on the `guile-tools compile'
|
||||||
|
command line, or add `#:warnings '(arity-mismatch)' to your `compile'
|
||||||
|
or `compile-file' invocation.
|
||||||
|
|
||||||
|
** Guile is now built without `-Werror' by default
|
||||||
|
|
||||||
|
Use the `--enable-error-on-warning' configure option to enable it.
|
||||||
|
|
||||||
** And of course, the usual collection of bugfixes
|
** And of course, the usual collection of bugfixes
|
||||||
|
|
||||||
Interested users should see the ChangeLog for more information.
|
Interested users should see the ChangeLog for more information.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Changes in 1.9.x (since the 1.8.x series):
|
Changes in 1.9.x (since the 1.8.x series):
|
||||||
|
|
||||||
* New modules (see the manual for details)
|
* New modules (see the manual for details)
|
||||||
|
@ -75,6 +201,17 @@ documented in the manual. This will be fixed before 2.0.
|
||||||
Pass the `--help' command-line option to these commands for more
|
Pass the `--help' command-line option to these commands for more
|
||||||
information.
|
information.
|
||||||
|
|
||||||
|
** Guile now adds its install prefix to the LTDL_LIBRARY_PATH
|
||||||
|
|
||||||
|
Users may now install Guile to nonstandard prefixes and just run
|
||||||
|
`/path/to/bin/guile', instead of also having to set LTDL_LIBRARY_PATH to
|
||||||
|
include `/path/to/lib'.
|
||||||
|
|
||||||
|
** Guile's Emacs integration is now more keyboard-friendly
|
||||||
|
|
||||||
|
Backtraces may now be disclosed with the keyboard in addition to the
|
||||||
|
mouse.
|
||||||
|
|
||||||
* Changes to Scheme functions and syntax
|
* Changes to Scheme functions and syntax
|
||||||
|
|
||||||
** Procedure removed: `the-environment'
|
** Procedure removed: `the-environment'
|
||||||
|
@ -108,6 +245,20 @@ For example, the old (lang elisp) modules are meant to be interpreted,
|
||||||
not compiled. This bug will be fixed before 2.0. FIXME 2.0: Should say
|
not compiled. This bug will be fixed before 2.0. FIXME 2.0: Should say
|
||||||
something here about module-transformer called for compile.
|
something here about module-transformer called for compile.
|
||||||
|
|
||||||
|
** Files loaded with `load' will now be compiled automatically.
|
||||||
|
|
||||||
|
As with files loaded via `primitive-load-path', `load' will also compile
|
||||||
|
its target if autocompilation is enabled, and a fresh compiled file is
|
||||||
|
not found.
|
||||||
|
|
||||||
|
There are two points of difference to note, however. First, `load' does
|
||||||
|
not search `GUILE_LOAD_COMPILED_PATH' for the file; it only looks in the
|
||||||
|
autocompilation directory, normally a subdirectory of ~/.cache/guile.
|
||||||
|
|
||||||
|
Secondly, autocompilation also applies to files loaded via the -l
|
||||||
|
command-line argument -- so the user may experience a slight slowdown
|
||||||
|
the first time they run a Guile script, as the script is autocompiled.
|
||||||
|
|
||||||
** New POSIX procedures: `getrlimit' and `setrlimit'
|
** New POSIX procedures: `getrlimit' and `setrlimit'
|
||||||
|
|
||||||
Note however that the interface of these functions is likely to change
|
Note however that the interface of these functions is likely to change
|
||||||
|
@ -480,6 +631,30 @@ This decision may be revisited before the 2.0 release. Feedback welcome
|
||||||
to guile-devel@gnu.org (subscription required) or bug-guile@gnu.org (no
|
to guile-devel@gnu.org (subscription required) or bug-guile@gnu.org (no
|
||||||
subscription required).
|
subscription required).
|
||||||
|
|
||||||
|
** `case-lambda' is now available in the default environment.
|
||||||
|
|
||||||
|
The binding in the default environment is equivalent to the one from the
|
||||||
|
`(srfi srfi-16)' module. Use the srfi-16 module explicitly if you wish
|
||||||
|
to maintain compatibility with Guile 1.8 and earlier.
|
||||||
|
|
||||||
|
** `lambda*' and `define*' are now available in the default environment
|
||||||
|
|
||||||
|
As with `case-lambda', `(ice-9 optargs)' continues to be supported, for
|
||||||
|
compatibility purposes. No semantic change has been made (we hope).
|
||||||
|
Optional and keyword arguments now dispatch via special VM operations,
|
||||||
|
without the need to cons rest arguments, making them very fast.
|
||||||
|
|
||||||
|
** New syntax: include-from-path.
|
||||||
|
|
||||||
|
`include-from-path' is like `include', except it looks for its file in
|
||||||
|
the load path. It can be used to compile other files into a file.
|
||||||
|
|
||||||
|
** New syntax: quasisyntax.
|
||||||
|
|
||||||
|
`quasisyntax' is to `syntax' as `quasiquote' is to `quote'. See the R6RS
|
||||||
|
documentation for more information. Thanks to Andre van Tonder for the
|
||||||
|
implementation.
|
||||||
|
|
||||||
** Unicode characters
|
** Unicode characters
|
||||||
|
|
||||||
Unicode characters may be entered in octal format via e.g. `#\454', or
|
Unicode characters may be entered in octal format via e.g. `#\454', or
|
||||||
|
@ -492,9 +667,52 @@ Internally, strings are now represented either in the `latin-1'
|
||||||
encoding, one byte per character, or in UTF-32, with four bytes per
|
encoding, one byte per character, or in UTF-32, with four bytes per
|
||||||
character. Strings manage their own allocation, switching if needed.
|
character. Strings manage their own allocation, switching if needed.
|
||||||
|
|
||||||
Currently no locale conversion is performed. Extended characters may be
|
Extended characters may be written in a literal string using the
|
||||||
written in a string using the hexadecimal escapes `\xXX', `\uXXXX', or
|
hexadecimal escapes `\xXX', `\uXXXX', or `\UXXXXXX', for 8-bit, 16-bit,
|
||||||
`\UXXXXXX', for 8-bit, 16-bit, or 24-bit codepoints, respectively.
|
or 24-bit codepoints, respectively, or entered directly in the native
|
||||||
|
encoding of the port on which the string is read.
|
||||||
|
|
||||||
|
** Unicode symbols
|
||||||
|
|
||||||
|
One may now use U+03BB (GREEK SMALL LETTER LAMBDA) as an identifier.
|
||||||
|
|
||||||
|
** Support for non-ASCII source code files
|
||||||
|
|
||||||
|
The default reader now handles source code files for some of the
|
||||||
|
non-ASCII character encodings, such as UTF-8. A non-ASCII source file
|
||||||
|
should have an encoding declaration near the top of the file. Also,
|
||||||
|
there is a new function, `file-encoding', that scans a port for a coding
|
||||||
|
declaration. See the section of the manual entitled, "Character Encoding
|
||||||
|
of Source Files".
|
||||||
|
|
||||||
|
The pre-1.9.3 reader handled 8-bit clean but otherwise unspecified source
|
||||||
|
code. This use is now discouraged.
|
||||||
|
|
||||||
|
** Support for locale transcoding when reading from and writing to ports
|
||||||
|
|
||||||
|
Ports now have an associated character encoding, and port read and write
|
||||||
|
operations do conversion to and from locales automatically. Ports also
|
||||||
|
have an associated strategy for how to deal with locale conversion
|
||||||
|
failures.
|
||||||
|
|
||||||
|
See the documentation in the manual for the four new support functions,
|
||||||
|
`set-port-encoding!', `port-encoding', `set-port-conversion-strategy!',
|
||||||
|
and `port-conversion-strategy'.
|
||||||
|
|
||||||
|
** String and SRFI-13 functions can operate on Unicode strings
|
||||||
|
|
||||||
|
** Unicode support for SRFI-14 character sets
|
||||||
|
|
||||||
|
The default character sets are no longer locale dependent and contain
|
||||||
|
characters from the whole Unicode range. There is a new predefined
|
||||||
|
character set, `char-set:designated', which contains all assigned
|
||||||
|
Unicode characters. There is a new debugging function, `%char-set-dump'.
|
||||||
|
|
||||||
|
** Character functions operate on Unicode characters
|
||||||
|
|
||||||
|
`char-upcase' and `char-downcase' use default Unicode casing rules.
|
||||||
|
Character comparisons such as `char<?' and `char-ci<?' now sort based on
|
||||||
|
Unicode code points.
|
||||||
|
|
||||||
** Global variables `scm_charnames' and `scm_charnums' are removed
|
** Global variables `scm_charnames' and `scm_charnums' are removed
|
||||||
|
|
||||||
|
@ -509,6 +727,17 @@ There was an EBCDIC compile flag that altered some of the character
|
||||||
processing. It appeared that full EBCDIC support was never completed
|
processing. It appeared that full EBCDIC support was never completed
|
||||||
and was unmaintained.
|
and was unmaintained.
|
||||||
|
|
||||||
|
** Compile-time warnings: -Wunbound-variable, -Warity-mismatch.
|
||||||
|
|
||||||
|
Guile can warn about potentially unbound free variables. Pass the
|
||||||
|
-Wunbound-variable on the `guile-tools compile' command line, or add
|
||||||
|
`#:warnings '(unbound-variable)' to your `compile' or `compile-file'
|
||||||
|
invocation.
|
||||||
|
|
||||||
|
Guile can also warn when you pass the wrong number of arguments to a
|
||||||
|
procedure, with -Warity-mismatch, or `arity-mismatch' in the
|
||||||
|
`#:warnings' as above.
|
||||||
|
|
||||||
** New macro type: syncase-macro
|
** New macro type: syncase-macro
|
||||||
|
|
||||||
XXX Need to decide whether to document this for 2.0, probably should:
|
XXX Need to decide whether to document this for 2.0, probably should:
|
||||||
|
@ -528,6 +757,39 @@ This slightly improves program startup times.
|
||||||
|
|
||||||
See `cancel-thread', `set-thread-cleanup!', and `thread-cleanup'.
|
See `cancel-thread', `set-thread-cleanup!', and `thread-cleanup'.
|
||||||
|
|
||||||
|
** GOOPS cleanups.
|
||||||
|
|
||||||
|
GOOPS had a number of concepts that were relevant to the days of Tcl,
|
||||||
|
but not any more: operators and entities, mainly. These objects were
|
||||||
|
never documented, and it is unlikely that they were ever used. Operators
|
||||||
|
were a kind of generic specific to the Tcl support. Entities were
|
||||||
|
applicable structures, but were unusable; entities will come back in the
|
||||||
|
next alpha release, but with a less stupid name.
|
||||||
|
|
||||||
|
** `inet-ntop' and `inet-pton' are always available.
|
||||||
|
|
||||||
|
Guile now use a portable implementation of `inet_pton'/`inet_ntop', so
|
||||||
|
there is no more need to use `inet-aton'/`inet-ntoa'. The latter
|
||||||
|
functions are deprecated.
|
||||||
|
|
||||||
|
** R6RS block comment support
|
||||||
|
|
||||||
|
Guile now supports R6RS nested block comments. The start of a comment is
|
||||||
|
marked with `#|', and the end with `|#'.
|
||||||
|
|
||||||
|
** `guile-2' cond-expand feature
|
||||||
|
|
||||||
|
To test if your code is running under Guile 2.0 (or its alpha releases),
|
||||||
|
test for the `guile-2' cond-expand feature. Like this:
|
||||||
|
|
||||||
|
(cond-expand (guile-2 (eval-when (compile)
|
||||||
|
;; This must be evaluated at compile time.
|
||||||
|
(fluid-set! current-reader my-reader)))
|
||||||
|
(guile
|
||||||
|
;; Earlier versions of Guile do not have a
|
||||||
|
;; separate compilation phase.
|
||||||
|
(fluid-set! current-reader my-reader)))
|
||||||
|
|
||||||
** Fix bad interaction between `false-if-exception' and stack-call.
|
** Fix bad interaction between `false-if-exception' and stack-call.
|
||||||
|
|
||||||
Exceptions thrown by `false-if-exception' were erronously causing the
|
Exceptions thrown by `false-if-exception' were erronously causing the
|
||||||
|
@ -559,14 +821,31 @@ the variable. This was an error, and was fixed.
|
||||||
As syntax-case is available by default, importing `(ice-9 syncase)' has
|
As syntax-case is available by default, importing `(ice-9 syncase)' has
|
||||||
no effect, and will trigger a deprecation warning.
|
no effect, and will trigger a deprecation warning.
|
||||||
|
|
||||||
|
** New readline history functions
|
||||||
|
|
||||||
|
The (ice-9 readline) module now provides add-history, read-history,
|
||||||
|
write-history and clear-history, which wrap the corresponding GNU
|
||||||
|
History library functions.
|
||||||
|
|
||||||
** Removed deprecated uniform array procedures:
|
** Removed deprecated uniform array procedures:
|
||||||
dimensions->uniform-array, list->uniform-array, array-prototype
|
dimensions->uniform-array, list->uniform-array, array-prototype
|
||||||
|
|
||||||
Instead, use make-typed-array, list->typed-array, or array-type,
|
Instead, use make-typed-array, list->typed-array, or array-type,
|
||||||
respectively.
|
respectively.
|
||||||
|
|
||||||
|
** Last but not least, the `λ' macro can be used in lieu of `lambda'
|
||||||
|
|
||||||
* Changes to the C interface
|
* Changes to the C interface
|
||||||
|
|
||||||
|
** Guile now uses libgc, the Boehm-Demers-Weiser garbage collector
|
||||||
|
|
||||||
|
The semantics of `scm_gc_malloc ()' have been changed, in a
|
||||||
|
backward-compatible way. A new allocation routine,
|
||||||
|
`scm_gc_malloc_pointerless ()', was added.
|
||||||
|
|
||||||
|
Libgc is a conservative GC, which we hope will make interaction with C
|
||||||
|
code easier and less error-prone.
|
||||||
|
|
||||||
** The GH interface (deprecated in version 1.6, 2001) was removed.
|
** The GH interface (deprecated in version 1.6, 2001) was removed.
|
||||||
|
|
||||||
** Internal `scm_i_' functions now have "hidden" linkage with GCC/ELF
|
** Internal `scm_i_' functions now have "hidden" linkage with GCC/ELF
|
||||||
|
@ -583,6 +862,36 @@ indicating length of the `scm_t_option' array.
|
||||||
|
|
||||||
This procedure corresponds to Scheme's `module-public-interface'.
|
This procedure corresponds to Scheme's `module-public-interface'.
|
||||||
|
|
||||||
|
** Inline vector allocation
|
||||||
|
|
||||||
|
Instead of having vectors point out into the heap for their data, their
|
||||||
|
data is now allocated inline to the vector object itself. The same is
|
||||||
|
true for bytevectors, by default, though there is an indirection
|
||||||
|
available which should allow for making a bytevector from an existing
|
||||||
|
memory region.
|
||||||
|
|
||||||
|
** Removal of Guile's primitive object system.
|
||||||
|
|
||||||
|
There were a number of pieces in `objects.[ch]' that tried to be a
|
||||||
|
minimal object system, but were never documented, and were quickly
|
||||||
|
obseleted by GOOPS' merge into Guile proper. So `scm_make_class_object',
|
||||||
|
`scm_make_subclass_object', `scm_metaclass_standard', and like symbols
|
||||||
|
from objects.h are no more. In the very unlikely case in which these
|
||||||
|
were useful to you, we urge you to contact guile-devel.
|
||||||
|
|
||||||
|
** No future.
|
||||||
|
|
||||||
|
Actually the future is still in the state that it was, is, and ever
|
||||||
|
shall be, Amen, except that `futures.c' and `futures.h' are no longer a
|
||||||
|
part of it. These files were experimental, never compiled, and would be
|
||||||
|
better implemented in Scheme anyway. In the future, that is.
|
||||||
|
|
||||||
|
** Support for static allocation of strings, symbols, and subrs.
|
||||||
|
|
||||||
|
Calls to snarfing CPP macros like SCM_DEFINE macro will now allocate
|
||||||
|
much of their associated data as static variables, reducing Guile's
|
||||||
|
memory footprint.
|
||||||
|
|
||||||
** `scm_stat' has an additional argument, `exception_on_error'
|
** `scm_stat' has an additional argument, `exception_on_error'
|
||||||
** `scm_primitive_load_path' has an additional argument `exception_on_not_found'
|
** `scm_primitive_load_path' has an additional argument `exception_on_not_found'
|
||||||
|
|
||||||
|
@ -600,11 +909,6 @@ definition depends on the application's value for `_FILE_OFFSET_BITS'.
|
||||||
|
|
||||||
These functions have been deprecated since early 2005.
|
These functions have been deprecated since early 2005.
|
||||||
|
|
||||||
** scm_array_p has one argument, not two
|
|
||||||
|
|
||||||
Use of the second argument produced a deprecation warning, so it is
|
|
||||||
unlikely that any code out there actually used this functionality.
|
|
||||||
|
|
||||||
* Changes to the distribution
|
* Changes to the distribution
|
||||||
|
|
||||||
** Guile's license is now LGPLv3+
|
** Guile's license is now LGPLv3+
|
||||||
|
@ -613,6 +917,11 @@ In other words the GNU Lesser General Public License, version 3 or
|
||||||
later (at the discretion of each person that chooses to redistribute
|
later (at the discretion of each person that chooses to redistribute
|
||||||
part of Guile).
|
part of Guile).
|
||||||
|
|
||||||
|
** GOOPS documentation folded into Guile reference manual
|
||||||
|
|
||||||
|
GOOPS, Guile's object system, used to be documented in separate manuals.
|
||||||
|
This content is now included in Guile's manual directly.
|
||||||
|
|
||||||
** `guile-config' will be deprecated in favor of `pkg-config'
|
** `guile-config' will be deprecated in favor of `pkg-config'
|
||||||
|
|
||||||
`guile-config' has been rewritten to get its information from
|
`guile-config' has been rewritten to get its information from
|
||||||
|
@ -630,10 +939,22 @@ macros should now require `guile-2.0' instead of `guile-1.8'.
|
||||||
If $(libdir) is /usr/lib, for example, Guile will install its .go files
|
If $(libdir) is /usr/lib, for example, Guile will install its .go files
|
||||||
to /usr/lib/guile/1.9/ccache. These files are architecture-specific.
|
to /usr/lib/guile/1.9/ccache. These files are architecture-specific.
|
||||||
|
|
||||||
** New dependency: GNU libunistring.
|
** Dynamically loadable extensions may be placed in a Guile-specific path
|
||||||
|
|
||||||
|
Before, Guile only searched the system library paths for extensions
|
||||||
|
(e.g. /usr/lib), which meant that the names of Guile extensions had to
|
||||||
|
be globally unique. Installing them to a Guile-specific extensions
|
||||||
|
directory is cleaner. Use `pkg-config --variable=extensionsdir
|
||||||
|
guile-2.0' to get the location of the extensions directory.
|
||||||
|
|
||||||
|
** New dependency: libgc
|
||||||
|
|
||||||
|
See http://www.hpl.hp.com/personal/Hans_Boehm/gc/, for more information.
|
||||||
|
|
||||||
|
** New dependency: GNU libunistring
|
||||||
|
|
||||||
See http://www.gnu.org/software/libunistring/, for more information. Our
|
See http://www.gnu.org/software/libunistring/, for more information. Our
|
||||||
unicode support uses routines from libunistring.
|
Unicode support uses routines from libunistring.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -643,6 +964,7 @@ Changes in 1.8.8 (since 1.8.7)
|
||||||
|
|
||||||
** Fix possible buffer overruns when parsing numbers
|
** Fix possible buffer overruns when parsing numbers
|
||||||
** Avoid clash with system setjmp/longjmp on IA64
|
** Avoid clash with system setjmp/longjmp on IA64
|
||||||
|
** Fix `wrong type arg' exceptions with IPv6 addresses
|
||||||
|
|
||||||
|
|
||||||
Changes in 1.8.7 (since 1.8.6)
|
Changes in 1.8.7 (since 1.8.6)
|
||||||
|
|
13
README
13
README
|
@ -33,6 +33,7 @@ Guile depends on the following external libraries.
|
||||||
- libintl
|
- libintl
|
||||||
- libltdl
|
- libltdl
|
||||||
- libunistring
|
- libunistring
|
||||||
|
- libgc
|
||||||
It will also use the libreadline library if it is available. For each
|
It will also use the libreadline library if it is available. For each
|
||||||
of these there is a corresponding --with-XXX-prefix option that you
|
of these there is a corresponding --with-XXX-prefix option that you
|
||||||
can use when invoking ./configure, if you have these libraries
|
can use when invoking ./configure, if you have these libraries
|
||||||
|
@ -68,12 +69,12 @@ Guile requires the following external packages:
|
||||||
- GNU MP, at least version 4.1
|
- GNU MP, at least version 4.1
|
||||||
|
|
||||||
GNU MP is used for bignum arithmetic. It is available from
|
GNU MP is used for bignum arithmetic. It is available from
|
||||||
http://swox.com/gmp
|
http://gmplib.org/ .
|
||||||
|
|
||||||
- libltdl from libtool, at least from libtool version 1.5.6
|
- libltdl from GNU Libtool, at least version 1.5.6
|
||||||
|
|
||||||
libltdl is used for loading extensions at run-time. It is
|
libltdl is used for loading extensions at run-time. It is
|
||||||
available from http://www.gnu.org/software/libtool/
|
available from http://www.gnu.org/software/libtool/ .
|
||||||
|
|
||||||
- GNU libunistring
|
- GNU libunistring
|
||||||
|
|
||||||
|
@ -81,6 +82,12 @@ Guile requires the following external packages:
|
||||||
`utf*->string' procedures. It is available from
|
`utf*->string' procedures. It is available from
|
||||||
http://www.gnu.org/software/libunistring/ .
|
http://www.gnu.org/software/libunistring/ .
|
||||||
|
|
||||||
|
- libgc, at least version 7.0
|
||||||
|
|
||||||
|
libgc (aka. the Boehm-Demers-Weiser garbage collector) is the
|
||||||
|
conservative garbage collector used by Guile. It is available
|
||||||
|
from http://www.hpl.hp.com/personal/Hans_Boehm/gc/ .
|
||||||
|
|
||||||
|
|
||||||
Special Instructions For Some Systems =====================================
|
Special Instructions For Some Systems =====================================
|
||||||
|
|
||||||
|
|
6
THANKS
6
THANKS
|
@ -30,6 +30,7 @@ For fixes or providing information which led to a fix:
|
||||||
Rob Browning
|
Rob Browning
|
||||||
Adrian Bunk
|
Adrian Bunk
|
||||||
Michael Carmack
|
Michael Carmack
|
||||||
|
R Clayton
|
||||||
Stephen Compall
|
Stephen Compall
|
||||||
Brian Crowder
|
Brian Crowder
|
||||||
Christopher Cramer
|
Christopher Cramer
|
||||||
|
@ -52,6 +53,7 @@ For fixes or providing information which led to a fix:
|
||||||
Roland Haeder
|
Roland Haeder
|
||||||
Sven Hartrumpf
|
Sven Hartrumpf
|
||||||
Eric Hanchrow
|
Eric Hanchrow
|
||||||
|
Judy Hawkins
|
||||||
Sam Hocevar
|
Sam Hocevar
|
||||||
Patrick Horgan
|
Patrick Horgan
|
||||||
Ales Hvezda
|
Ales Hvezda
|
||||||
|
@ -74,6 +76,7 @@ For fixes or providing information which led to a fix:
|
||||||
Antoine Mathys
|
Antoine Mathys
|
||||||
Dan McMahill
|
Dan McMahill
|
||||||
Roger Mc Murtrie
|
Roger Mc Murtrie
|
||||||
|
Scott McPeak
|
||||||
Tim Mooney
|
Tim Mooney
|
||||||
Han-Wen Nienhuys
|
Han-Wen Nienhuys
|
||||||
Jan Nieuwenhuizen
|
Jan Nieuwenhuizen
|
||||||
|
@ -83,6 +86,7 @@ For fixes or providing information which led to a fix:
|
||||||
Peter O'Gorman
|
Peter O'Gorman
|
||||||
Pieter Pareit
|
Pieter Pareit
|
||||||
Jack Pavlovsky
|
Jack Pavlovsky
|
||||||
|
Derek Peschel
|
||||||
Arno Peters
|
Arno Peters
|
||||||
Ron Peterson
|
Ron Peterson
|
||||||
David Pirotte
|
David Pirotte
|
||||||
|
@ -94,6 +98,7 @@ For fixes or providing information which led to a fix:
|
||||||
Werner Scheinast
|
Werner Scheinast
|
||||||
Bill Schottstaedt
|
Bill Schottstaedt
|
||||||
Frank Schwidom
|
Frank Schwidom
|
||||||
|
John Steele Scott
|
||||||
Thiemo Seufer
|
Thiemo Seufer
|
||||||
Scott Shedden
|
Scott Shedden
|
||||||
Alex Shinn
|
Alex Shinn
|
||||||
|
@ -114,6 +119,7 @@ For fixes or providing information which led to a fix:
|
||||||
Andreas Vögele
|
Andreas Vögele
|
||||||
Michael Talbot-Wilson
|
Michael Talbot-Wilson
|
||||||
Michael Tuexen
|
Michael Tuexen
|
||||||
|
Thomas Wawrzinek
|
||||||
Mark H. Weaver
|
Mark H. Weaver
|
||||||
Jon Wilson
|
Jon Wilson
|
||||||
Andy Wingo
|
Andy Wingo
|
||||||
|
|
64
acinclude.m4
64
acinclude.m4
|
@ -57,7 +57,7 @@ AC_DEFUN([GUILE_HEADER_LIBC_WITH_UNISTD],
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
if test "$guile_cv_header_libc_with_unistd" = yes; then
|
if test "$guile_cv_header_libc_with_unistd" = yes; then
|
||||||
AC_DEFINE(LIBC_H_WITH_UNISTD_H, 1,
|
AC_DEFINE([LIBC_H_WITH_UNISTD_H], 1,
|
||||||
[Define this if we should include <libc.h> when we've already
|
[Define this if we should include <libc.h> when we've already
|
||||||
included <unistd.h>. On some systems, they conflict, and libc.h
|
included <unistd.h>. On some systems, they conflict, and libc.h
|
||||||
should be omitted. See GUILE_HEADER_LIBC_WITH_UNISTD in
|
should be omitted. See GUILE_HEADER_LIBC_WITH_UNISTD in
|
||||||
|
@ -267,7 +267,7 @@ if test "x$acx_pthread_ok" = xyes; then
|
||||||
done
|
done
|
||||||
AC_MSG_RESULT($attr_name)
|
AC_MSG_RESULT($attr_name)
|
||||||
if test "$attr_name" != PTHREAD_CREATE_JOINABLE; then
|
if test "$attr_name" != PTHREAD_CREATE_JOINABLE; then
|
||||||
AC_DEFINE_UNQUOTED(PTHREAD_CREATE_JOINABLE, $attr_name,
|
AC_DEFINE_UNQUOTED([PTHREAD_CREATE_JOINABLE], $attr_name,
|
||||||
[Define to necessary symbol if this constant
|
[Define to necessary symbol if this constant
|
||||||
uses a non-standard name on your system.])
|
uses a non-standard name on your system.])
|
||||||
fi
|
fi
|
||||||
|
@ -302,7 +302,7 @@ AC_SUBST(PTHREAD_CC)
|
||||||
|
|
||||||
# Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND:
|
# Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND:
|
||||||
if test x"$acx_pthread_ok" = xyes; then
|
if test x"$acx_pthread_ok" = xyes; then
|
||||||
ifelse([$1],,AC_DEFINE(HAVE_PTHREAD,1,[Define if you have POSIX threads libraries and header files.]),[$1])
|
ifelse([$1],,AC_DEFINE([HAVE_PTHREAD],1,[Define if you have POSIX threads libraries and header files.]),[$1])
|
||||||
:
|
:
|
||||||
else
|
else
|
||||||
acx_pthread_ok=no
|
acx_pthread_ok=no
|
||||||
|
@ -311,6 +311,64 @@ fi
|
||||||
AC_LANG_RESTORE
|
AC_LANG_RESTORE
|
||||||
])dnl ACX_PTHREAD
|
])dnl ACX_PTHREAD
|
||||||
|
|
||||||
|
dnl GUILE_GNU_LD_RELRO
|
||||||
|
dnl
|
||||||
|
dnl Check whether GNU ld's read-only relocations (the `PT_GNU_RELRO'
|
||||||
|
dnl ELF segment header) are supported. This allows things like
|
||||||
|
dnl statically allocated cells (1) to eventually be remapped read-only
|
||||||
|
dnl by the loader, and (2) to be identified as pointerless by the
|
||||||
|
dnl garbage collector. Substitute `GNU_LD_FLAGS' with the relevant
|
||||||
|
dnl flags.
|
||||||
|
AC_DEFUN([GUILE_GNU_LD_RELRO], [
|
||||||
|
AC_MSG_CHECKING([whether the linker understands `-z relro'])
|
||||||
|
|
||||||
|
GNU_LD_FLAGS="-Wl,-z -Wl,relro"
|
||||||
|
|
||||||
|
save_LDFLAGS="$LDFLAGS"
|
||||||
|
LDFLAGS="$LDFLAGS $GNU_LD_FLAGS"
|
||||||
|
AC_LINK_IFELSE([AC_LANG_PROGRAM([], [])],
|
||||||
|
[AC_MSG_RESULT([yes])],
|
||||||
|
[AC_MSG_RESULT([no])
|
||||||
|
GNU_LD_FLAGS=""])
|
||||||
|
LDFLAGS="$save_LDFLAGS"
|
||||||
|
|
||||||
|
AC_SUBST([GNU_LD_FLAGS])
|
||||||
|
])
|
||||||
|
|
||||||
|
dnl GUILE_THREAD_LOCAL_STORAGE
|
||||||
|
dnl
|
||||||
|
dnl Check for compiler thread-local storage (TLS) support.
|
||||||
|
AC_DEFUN([GUILE_THREAD_LOCAL_STORAGE], [
|
||||||
|
AC_CACHE_CHECK([whether the `__thread' storage class is available],
|
||||||
|
[ac_cv_have_thread_storage_class],
|
||||||
|
[dnl On some systems, e.g., NetBSD 5.0 with GCC 4.1, `__thread' is
|
||||||
|
dnl properly compiled but fails to link due to the lack of TLS
|
||||||
|
dnl support in the C library. Thus we try to link, not just
|
||||||
|
dnl compile. Unfortunately, this test is not enough, so we
|
||||||
|
dnl explicitly check for known-broken systems. See
|
||||||
|
dnl http://lists.gnu.org/archive/html/guile-devel/2009-10/msg00138.html
|
||||||
|
dnl for details.
|
||||||
|
case "x$enable_shared--$host" in
|
||||||
|
xyes--*netbsd[0-5].[0-9].)
|
||||||
|
ac_cv_have_thread_storage_class="no"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
AC_LINK_IFELSE([AC_LANG_PROGRAM([__thread int tls_integer;],
|
||||||
|
[tls_integer = 123;])],
|
||||||
|
[ac_cv_have_thread_storage_class="yes"],
|
||||||
|
[ac_cv_have_thread_storage_class="no"])
|
||||||
|
;;
|
||||||
|
esac])
|
||||||
|
|
||||||
|
if test "x$ac_cv_have_thread_storage_class" = "xyes"; then
|
||||||
|
SCM_I_GSC_HAVE_THREAD_STORAGE_CLASS=1
|
||||||
|
else
|
||||||
|
SCM_I_GSC_HAVE_THREAD_STORAGE_CLASS=0
|
||||||
|
fi
|
||||||
|
|
||||||
|
AC_SUBST([SCM_I_GSC_HAVE_THREAD_STORAGE_CLASS])
|
||||||
|
])
|
||||||
|
|
||||||
dnl GUILE_READLINE
|
dnl GUILE_READLINE
|
||||||
dnl
|
dnl
|
||||||
dnl Check all the things needed by `guile-readline', the Readline
|
dnl Check all the things needed by `guile-readline', the Readline
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
# -*- makefile -*-
|
# -*- makefile -*-
|
||||||
GOBJECTS = $(SOURCES:%.scm=%.go)
|
GOBJECTS = $(SOURCES:%.scm=%.go)
|
||||||
|
|
||||||
|
GUILE_WARNINGS = -Wunbound-variable -Warity-mismatch
|
||||||
|
|
||||||
moddir = $(pkgdatadir)/$(GUILE_EFFECTIVE_VERSION)/$(modpath)
|
moddir = $(pkgdatadir)/$(GUILE_EFFECTIVE_VERSION)/$(modpath)
|
||||||
nobase_mod_DATA = $(SOURCES) $(NOCOMP_SOURCES)
|
nobase_mod_DATA = $(SOURCES) $(NOCOMP_SOURCES)
|
||||||
ccachedir = $(pkglibdir)/$(GUILE_EFFECTIVE_VERSION)/ccache/$(modpath)
|
ccachedir = $(pkglibdir)/$(GUILE_EFFECTIVE_VERSION)/ccache/$(modpath)
|
||||||
|
@ -30,4 +32,6 @@ install-data-hook:
|
||||||
|
|
||||||
SUFFIXES = .scm .go
|
SUFFIXES = .scm .go
|
||||||
.scm.go:
|
.scm.go:
|
||||||
GUILE_AUTO_COMPILE=0 $(top_builddir)/meta/uninstalled-env guile-tools compile -o "$@" "$<"
|
GUILE_AUTO_COMPILE=0 \
|
||||||
|
$(top_builddir)/meta/uninstalled-env \
|
||||||
|
guile-tools compile $(GUILE_WARNINGS) -o "$@" "$<"
|
||||||
|
|
|
@ -15,9 +15,13 @@ autoconf --version
|
||||||
echo ""
|
echo ""
|
||||||
automake --version
|
automake --version
|
||||||
echo ""
|
echo ""
|
||||||
libtool --version
|
if test "`uname -s`" = Darwin; then
|
||||||
|
glibtool --version
|
||||||
|
else
|
||||||
|
libtool --version
|
||||||
|
fi
|
||||||
echo ""
|
echo ""
|
||||||
${M4:-/usr/bin/m4} --version
|
${M4:-m4} --version
|
||||||
echo ""
|
echo ""
|
||||||
|
|
||||||
######################################################################
|
######################################################################
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
#! /bin/sh
|
#! /bin/sh
|
||||||
# Usage: benchmark-guile [-i GUILE-INTERPRETER] [GUILE-BENCHMARK-ARGS]
|
# Usage: benchmark-guile [-i GUILE-INTERPRETER] [GUILE-BENCHMARK-ARGS]
|
||||||
# If `-i GUILE-INTERPRETER' is omitted, use ${top_builddir}/pre-inst-guile.
|
# If `-i GUILE-INTERPRETER' is omitted, use ${top_builddir}/meta/guile.
|
||||||
# See ${top_srcdir}/benchmark-suite/guile-benchmark for documentation on GUILE-BENCHMARK-ARGS.
|
# See ${top_srcdir}/benchmark-suite/guile-benchmark for documentation on GUILE-BENCHMARK-ARGS.
|
||||||
#
|
#
|
||||||
# Example invocations:
|
# Example invocations:
|
||||||
|
@ -21,7 +21,7 @@ if [ x"$1" = x-i ] ; then
|
||||||
shift
|
shift
|
||||||
shift
|
shift
|
||||||
else
|
else
|
||||||
guile=${top_builddir}/pre-inst-guile
|
guile=${top_builddir}/meta/guile
|
||||||
fi
|
fi
|
||||||
|
|
||||||
GUILE_LOAD_PATH=$BENCHMARK_SUITE_DIR
|
GUILE_LOAD_PATH=$BENCHMARK_SUITE_DIR
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
SCM_BENCHMARKS = benchmarks/0-reference.bm \
|
SCM_BENCHMARKS = benchmarks/0-reference.bm \
|
||||||
benchmarks/bytevectors.bm \
|
benchmarks/bytevectors.bm \
|
||||||
benchmarks/continuations.bm \
|
benchmarks/continuations.bm \
|
||||||
benchmarks/if.bm \
|
benchmarks/if.bm \
|
||||||
benchmarks/logand.bm \
|
benchmarks/logand.bm \
|
||||||
benchmarks/read.bm \
|
benchmarks/read.bm \
|
||||||
|
|
|
@ -1,2 +1,6 @@
|
||||||
|
|
||||||
|
(define-module (benchmarks 0-reference)
|
||||||
|
:use-module (benchmark-suite lib))
|
||||||
|
|
||||||
(benchmark "reference benchmark for iteration counts" 330000
|
(benchmark "reference benchmark for iteration counts" 330000
|
||||||
#t)
|
#t)
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
;;; -*- mode: scheme; coding: latin-1; -*-
|
;;; coding: latin1 -*- mode: scheme; coding: latin-1; -*-
|
||||||
;;; R6RS Byte Vectors.
|
;;; R6RS Byte Vectors.
|
||||||
;;;
|
;;;
|
||||||
;;; Copyright 2009 Ludovic Courtès <ludo@gnu.org>
|
;;; Copyright 2009 Ludovic Courtès <ludo@gnu.org>
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
;;; -*- mode: scheme; coding: latin-1; -*-
|
;;; coding: latin1 -*- mode: scheme; coding: latin-1; -*-
|
||||||
;;; chars.bm
|
;;; chars.bm
|
||||||
;;;
|
;;;
|
||||||
;;; Copyright (C) 2009 Free Software Foundation, Inc.
|
;;; Copyright (C) 2009 Free Software Foundation, Inc.
|
||||||
|
|
|
@ -1,5 +1,9 @@
|
||||||
|
|
||||||
|
(define-module (benchmarks continuations)
|
||||||
|
:use-module (benchmark-suite lib))
|
||||||
|
|
||||||
(define (callee continuation)
|
(define (callee continuation)
|
||||||
(continuation #t))
|
(continuation #t))
|
||||||
|
|
||||||
(benchmark "call/cc" 300
|
(benchmark "call/cc" 12000
|
||||||
(call-with-current-continuation callee))
|
(call-with-current-continuation callee))
|
||||||
|
|
|
@ -1,3 +1,7 @@
|
||||||
|
|
||||||
|
(define-module (benchmarks if)
|
||||||
|
:use-module (benchmark-suite lib))
|
||||||
|
|
||||||
(with-benchmark-prefix "if-<expr>-then-else"
|
(with-benchmark-prefix "if-<expr>-then-else"
|
||||||
|
|
||||||
(benchmark "executing then" 330000
|
(benchmark "executing then" 330000
|
||||||
|
|
|
@ -1,3 +1,7 @@
|
||||||
|
|
||||||
|
(define-module (benchmarks logand)
|
||||||
|
:use-module (benchmark-suite lib))
|
||||||
|
|
||||||
(define bignum (1- (expt 2 128)))
|
(define bignum (1- (expt 2 128)))
|
||||||
|
|
||||||
(let* ((i 0))
|
(let* ((i 0))
|
||||||
|
|
|
@ -49,14 +49,14 @@
|
||||||
(benchmark "_IONBF" 5 ;; this one is very slow
|
(benchmark "_IONBF" 5 ;; this one is very slow
|
||||||
(exercise-read (list _IONBF)))
|
(exercise-read (list _IONBF)))
|
||||||
|
|
||||||
(benchmark "_IOLBF" 100
|
(benchmark "_IOLBF" 10
|
||||||
(exercise-read (list _IOLBF)))
|
(exercise-read (list _IOLBF)))
|
||||||
|
|
||||||
(benchmark "_IOFBF 4096" 100
|
(benchmark "_IOFBF 4096" 10
|
||||||
(exercise-read (list _IOFBF 4096)))
|
(exercise-read (list _IOFBF 4096)))
|
||||||
|
|
||||||
(benchmark "_IOFBF 8192" 100
|
(benchmark "_IOFBF 8192" 10
|
||||||
(exercise-read (list _IOFBF 8192)))
|
(exercise-read (list _IOFBF 8192)))
|
||||||
|
|
||||||
(benchmark "_IOFBF 16384" 100
|
(benchmark "_IOFBF 16384" 10
|
||||||
(exercise-read (list _IOFBF 16384))))
|
(exercise-read (list _IOFBF 16384))))
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
;;; -*- mode: scheme; coding: latin-1; -*-
|
;;; coding: latin1 -*- mode: scheme; coding: latin-1; -*-
|
||||||
;;; srfi-13.bm
|
;;; srfi-13.bm
|
||||||
;;;
|
;;;
|
||||||
;;; Copyright (C) 2009 Free Software Foundation, Inc.
|
;;; Copyright (C) 2009 Free Software Foundation, Inc.
|
||||||
|
@ -122,7 +122,7 @@ Italiam, fato profugus, Laviniaque venit")
|
||||||
(string-ref long-string k)
|
(string-ref long-string k)
|
||||||
(loop (+ k 1))))))
|
(loop (+ k 1))))))
|
||||||
|
|
||||||
(benchmark "copy" 1100
|
(benchmark "copy" 20000
|
||||||
(string-copy short-string)
|
(string-copy short-string)
|
||||||
(string-copy medium-string)
|
(string-copy medium-string)
|
||||||
(string-copy long-string)
|
(string-copy long-string)
|
||||||
|
@ -130,7 +130,7 @@ Italiam, fato profugus, Laviniaque venit")
|
||||||
(substring/copy medium-string 10 20)
|
(substring/copy medium-string 10 20)
|
||||||
(substring/copy long-string 100 200))
|
(substring/copy long-string 100 200))
|
||||||
|
|
||||||
(benchmark "pad" 6800
|
(benchmark "pad" 34000
|
||||||
(string-pad short-string 100)
|
(string-pad short-string 100)
|
||||||
(string-pad medium-string 100)
|
(string-pad medium-string 100)
|
||||||
(string-pad long-string 100))
|
(string-pad long-string 100))
|
||||||
|
|
|
@ -36,12 +36,12 @@
|
||||||
|
|
||||||
(with-benchmark-prefix "uniform-vector-read!"
|
(with-benchmark-prefix "uniform-vector-read!"
|
||||||
|
|
||||||
(benchmark "uniform-vector-write" 500
|
(benchmark "uniform-vector-write" 4000
|
||||||
(let ((output (open-output-file file-name)))
|
(let ((output (open-output-file file-name)))
|
||||||
(uniform-vector-write buf output)
|
(uniform-vector-write buf output)
|
||||||
(close output)))
|
(close output)))
|
||||||
|
|
||||||
(benchmark "uniform-vector-read!" 500
|
(benchmark "uniform-vector-read!" 20000
|
||||||
(let ((input (open-input-file file-name)))
|
(let ((input (open-input-file file-name)))
|
||||||
(setvbuf input _IONBF)
|
(setvbuf input _IONBF)
|
||||||
(uniform-vector-read! buf input)
|
(uniform-vector-read! buf input)
|
||||||
|
|
|
@ -325,7 +325,7 @@
|
||||||
|
|
||||||
;;; A short form for benchmarks.
|
;;; A short form for benchmarks.
|
||||||
(defmacro benchmark (name iterations body . rest)
|
(defmacro benchmark (name iterations body . rest)
|
||||||
`(,run-benchmark ,name ,iterations (lambda () ,body ,@rest)))
|
`(run-benchmark ,name ,iterations (lambda () ,body ,@rest)))
|
||||||
|
|
||||||
|
|
||||||
;;;; BENCHMARK NAMES
|
;;;; BENCHMARK NAMES
|
||||||
|
|
93
benchmark-suite/results/neil-arudy
Normal file
93
benchmark-suite/results/neil-arudy
Normal file
|
@ -0,0 +1,93 @@
|
||||||
|
Benchmarking /home/neil/SW/Guile/git/meta/guile ...
|
||||||
|
with GUILE_LOAD_PATH=/home/neil/SW/Guile/git/benchmark-suite
|
||||||
|
;; running guile version 1.9.3
|
||||||
|
;; calibrating the benchmarking framework...
|
||||||
|
;; framework time per iteration: 5.7220458984375e-7
|
||||||
|
("0-reference.bm: reference benchmark for iteration counts" 330000 user 0.2 benchmark 0.0111724853515625 bench/interp 0.0111724853515625 gc 0.0)
|
||||||
|
("bytevectors.bm: ref/set!: bytevector-u8-ref" 1000000 user 0.73 benchmark 0.15779541015625 bench/interp 0.15779541015625 gc 0.0)
|
||||||
|
("bytevectors.bm: ref/set!: bytevector-u16-ref (foreign)" 1000000 user 0.82 benchmark 0.24779541015625 bench/interp 0.24779541015625 gc 0.0)
|
||||||
|
("bytevectors.bm: ref/set!: bytevector-u16-ref (native)" 1000000 user 0.78 benchmark 0.20779541015625 bench/interp 0.20779541015625 gc 0.0)
|
||||||
|
("bytevectors.bm: ref/set!: bytevector-u16-native-ref" 1000000 user 0.72 benchmark 0.14779541015625 bench/interp 0.14779541015625 gc 0.0)
|
||||||
|
("bytevectors.bm: ref/set!: bytevector-u32-ref (foreign)" 1000000 user 1.61 benchmark 1.03779541015625 bench/interp 1.03779541015625 gc 0.0)
|
||||||
|
("bytevectors.bm: ref/set!: bytevector-u32-ref (native)" 1000000 user 0.8 benchmark 0.22779541015625 bench/interp 0.22779541015625 gc 0.0)
|
||||||
|
("bytevectors.bm: ref/set!: bytevector-u32-native-ref" 1000000 user 0.74 benchmark 0.16779541015625 bench/interp 0.16779541015625 gc 0.0)
|
||||||
|
("bytevectors.bm: ref/set!: bytevector-u64-ref (foreign)" 1000000 user 1.86 benchmark 1.28779541015625 bench/interp 1.28779541015625 gc 0.0)
|
||||||
|
("bytevectors.bm: ref/set!: bytevector-u64-ref (native)" 1000000 user 0.81 benchmark 0.23779541015625 bench/interp 0.23779541015625 gc 0.0)
|
||||||
|
("bytevectors.bm: ref/set!: bytevector-u64-native-ref" 1000000 user 0.73 benchmark 0.15779541015625 bench/interp 0.15779541015625 gc 0.0)
|
||||||
|
("bytevectors.bm: lists: bytevector->u8-list" 2000 user 9.87 benchmark 9.86885559082031 bench/interp 9.86885559082031 gc 0.0)
|
||||||
|
("bytevectors.bm: lists: bytevector->uint-list 16-bit" 2000 user 4.48 benchmark 4.47885559082031 bench/interp 4.47885559082031 gc 0.0)
|
||||||
|
("bytevectors.bm: lists: bytevector->uint-list 64-bit" 2000 user 3.75 benchmark 3.74885559082031 bench/interp 3.74885559082031 gc 0.0)
|
||||||
|
("bytevectors.bm: SRFI-4: u8vector-ref" 1000000 user 1.88 benchmark 1.30779541015625 bench/interp 1.30779541015625 gc 0.0)
|
||||||
|
("bytevectors.bm: SRFI-4: u16vector-ref" 1000000 user 1.9 benchmark 1.32779541015625 bench/interp 1.32779541015625 gc 0.0)
|
||||||
|
("bytevectors.bm: SRFI-4: u32vector-ref" 1000000 user 1.88 benchmark 1.30779541015625 bench/interp 1.30779541015625 gc 0.0)
|
||||||
|
("bytevectors.bm: SRFI-4: u64vector-ref" 1000000 user 1.98 benchmark 1.40779541015625 bench/interp 1.40779541015625 gc 0.0)
|
||||||
|
("chars.bm: chars: char" 1000000 user 0.63 benchmark 0.05779541015625 bench/interp 0.05779541015625 gc 0.0)
|
||||||
|
("chars.bm: chars: octal" 1000000 user 0.64 benchmark 0.06779541015625 bench/interp 0.06779541015625 gc 0.0)
|
||||||
|
("chars.bm: chars: char? eq" 1000000 user 1.19 benchmark 0.61779541015625 bench/interp 0.61779541015625 gc 0.0)
|
||||||
|
("chars.bm: chars: char=?" 1000000 user 1.45 benchmark 0.87779541015625 bench/interp 0.87779541015625 gc 0.0)
|
||||||
|
("chars.bm: chars: char<?" 1000000 user 1.45 benchmark 0.87779541015625 bench/interp 0.87779541015625 gc 0.0)
|
||||||
|
("chars.bm: chars: char-ci=?" 1000000 user 1.45 benchmark 0.87779541015625 bench/interp 0.87779541015625 gc 0.0)
|
||||||
|
("chars.bm: chars: char-ci<? " 1000000 user 1.45 benchmark 0.87779541015625 bench/interp 0.87779541015625 gc 0.0)
|
||||||
|
("chars.bm: chars: char->integer" 1000000 user 1.2 benchmark 0.62779541015625 bench/interp 0.62779541015625 gc 0.0)
|
||||||
|
("chars.bm: chars: char-alphabetic?" 1000000 user 1.36 benchmark 0.78779541015625 bench/interp 0.78779541015625 gc 0.0)
|
||||||
|
("chars.bm: chars: char-numeric?" 1000000 user 1.36 benchmark 0.78779541015625 bench/interp 0.78779541015625 gc 0.0)
|
||||||
|
("continuations.bm: call/cc" 300 user 0.03 benchmark 0.0298283386230469 bench/interp 0.0298283386230469 gc 0.0)
|
||||||
|
("if.bm: if-<expr>-then-else: executing then" 330000 user 0.23 benchmark 0.0411724853515625 bench/interp 0.0411724853515625 gc 0.0)
|
||||||
|
("if.bm: if-<expr>-then-else: executing else" 330000 user 0.23 benchmark 0.0411724853515625 bench/interp 0.0411724853515625 gc 0.0)
|
||||||
|
("if.bm: if-<expr>-then: executing then" 330000 user 0.23 benchmark 0.0411724853515625 bench/interp 0.0411724853515625 gc 0.0)
|
||||||
|
("if.bm: if-<expr>-then: executing else" 330000 user 0.24 benchmark 0.0511724853515625 bench/interp 0.0511724853515625 gc 0.0)
|
||||||
|
("if.bm: if-<iloc>-then-else: executing then" 330000 user 0.25 benchmark 0.0611724853515625 bench/interp 0.0611724853515625 gc 0.0)
|
||||||
|
("if.bm: if-<iloc>-then-else: executing else" 330000 user 0.24 benchmark 0.0511724853515625 bench/interp 0.0511724853515625 gc 0.0)
|
||||||
|
("if.bm: if-<iloc>-then: executing then" 330000 user 0.24 benchmark 0.0511724853515625 bench/interp 0.0511724853515625 gc 0.0)
|
||||||
|
("if.bm: if-<iloc>-then: executing else" 330000 user 0.24 benchmark 0.0511724853515625 bench/interp 0.0511724853515625 gc 0.0)
|
||||||
|
("if.bm: if-<bool>-then-else: executing then" 330000 user 0.23 benchmark 0.0411724853515625 bench/interp 0.0411724853515625 gc 0.0)
|
||||||
|
("if.bm: if-<bool>-then-else: executing else" 330000 user 0.23 benchmark 0.0411724853515625 bench/interp 0.0411724853515625 gc 0.0)
|
||||||
|
("if.bm: if-<bool>-then: executing then" 330000 user 0.24 benchmark 0.0511724853515625 bench/interp 0.0511724853515625 gc 0.0)
|
||||||
|
("if.bm: if-<bool>-then: executing else" 330000 user 0.23 benchmark 0.0411724853515625 bench/interp 0.0411724853515625 gc 0.0)
|
||||||
|
("logand.bm: bignum" 130000 user 0.48 benchmark 0.405613403320312 bench/interp 0.405613403320312 gc 0.0)
|
||||||
|
("read.bm: read: _IONBF" 5 user 12.71 benchmark 12.7099971389771 bench/interp 12.7099971389771 gc 0.0)
|
||||||
|
("read.bm: read: _IOLBF" 10 user 20.32 benchmark 20.3199942779541 bench/interp 20.3199942779541 gc 0.0)
|
||||||
|
("read.bm: read: _IOFBF 4096" 10 user 20.34 benchmark 20.3399942779541 bench/interp 20.3399942779541 gc 0.0)
|
||||||
|
("read.bm: read: _IOFBF 8192" 10 user 20.36 benchmark 20.3599942779541 bench/interp 20.3599942779541 gc 0.0)
|
||||||
|
("read.bm: read: _IOFBF 16384" 10 user 20.34 benchmark 20.3399942779541 bench/interp 20.3399942779541 gc 0.0)
|
||||||
|
("srfi-13.bm: strings: predicates: string?" 1190000 user 2.98 benchmark 2.29907653808594 bench/interp 2.29907653808594 gc 0.0)
|
||||||
|
("srfi-13.bm: strings: predicates: null?" 969000 user 2.56 benchmark 2.00553375244141 bench/interp 2.00553375244141 gc 0.0)
|
||||||
|
("srfi-13.bm: strings: predicates: any" 94000 user 1.89 benchmark 1.83621276855469 bench/interp 1.83621276855469 gc 0.0)
|
||||||
|
("srfi-13.bm: strings: predicates: every" 94000 user 1.53 benchmark 1.47621276855469 bench/interp 1.47621276855469 gc 0.0)
|
||||||
|
("srfi-13.bm: strings: constructors: string" 5000 user 2.02 benchmark 2.01713897705078 bench/interp 2.01713897705078 gc 0.0)
|
||||||
|
("srfi-13.bm: strings: constructors: list->" 4500 user 0.3 benchmark 0.297425079345703 bench/interp 0.297425079345703 gc 0.0)
|
||||||
|
("srfi-13.bm: strings: constructors: reverse-list->" 5000 user 0.58 benchmark 0.577138977050781 bench/interp 0.577138977050781 gc 0.0)
|
||||||
|
("srfi-13.bm: strings: constructors: make" 22000 user 0.52 benchmark 0.507411499023438 bench/interp 0.507411499023438 gc 0.0)
|
||||||
|
("srfi-13.bm: strings: constructors: tabulate" 17000 user 0.57 benchmark 0.560272521972656 bench/interp 0.560272521972656 gc 0.0)
|
||||||
|
("srfi-13.bm: strings: constructors: join" 5500 user 0.46 benchmark 0.456852874755859 bench/interp 0.456852874755859 gc 0.0)
|
||||||
|
("srfi-13.bm: strings: list/string: ->list" 7300 user 2.36 benchmark 2.35582290649414 bench/interp 2.35582290649414 gc 0.0)
|
||||||
|
("srfi-13.bm: strings: list/string: split" 60000 user 1.87 benchmark 1.83566772460938 bench/interp 1.83566772460938 gc 0.0)
|
||||||
|
("srfi-13.bm: strings: selection: ref" 660 user 1.5 benchmark 1.4996223449707 bench/interp 1.4996223449707 gc 0.0)
|
||||||
|
("srfi-13.bm: strings: selection: copy" 1100 user 0.04 benchmark 0.0393705749511719 bench/interp 0.0393705749511719 gc 0.0)
|
||||||
|
("srfi-13.bm: strings: selection: pad" 6800 user 0.17 benchmark 0.166109008789063 bench/interp 0.166109008789063 gc 0.0)
|
||||||
|
("srfi-13.bm: strings: selection: trim trim-right trim-both" 60000 user 2.67 benchmark 2.63566772460937 bench/interp 2.63566772460937 gc 0.0)
|
||||||
|
("srfi-13.bm: strings: modification: set!" 3000 user 1.42 benchmark 1.41828338623047 bench/interp 1.41828338623047 gc 0.0)
|
||||||
|
("srfi-13.bm: strings: modification: sub-move!" 230000 user 1.88 benchmark 1.74839294433594 bench/interp 1.74839294433594 gc 0.0)
|
||||||
|
("srfi-13.bm: strings: modification: fill!" 230000 user 2.31 benchmark 2.17839294433594 bench/interp 2.17839294433594 gc 0.0)
|
||||||
|
("srfi-13.bm: strings: modification: comparison: compare compare-ci" 140000 user 1.93 benchmark 1.84989135742187 bench/interp 1.84989135742187 gc 0.0)
|
||||||
|
("srfi-13.bm: strings: modification: comparison: hash hash-ci" 1000 user 0.27 benchmark 0.269427795410156 bench/interp 0.269427795410156 gc 0.0)
|
||||||
|
("srfi-13.bm: strings: searching: prefix-length suffix-length" 270 user 0.2 benchmark 0.199845504760742 bench/interp 0.199845504760742 gc 0.0)
|
||||||
|
("srfi-13.bm: strings: searching: prefix? suffix?" 270 user 0.2 benchmark 0.199845504760742 bench/interp 0.199845504760742 gc 0.0)
|
||||||
|
("srfi-13.bm: strings: searching: index index-right rindex" 100000 user 3.48 benchmark 3.42277954101562 bench/interp 3.42277954101562 gc 0.0)
|
||||||
|
("srfi-13.bm: strings: searching: skip skip-right?" 100000 user 2.14 benchmark 2.08277954101563 bench/interp 2.08277954101563 gc 0.0)
|
||||||
|
("srfi-13.bm: strings: searching: count" 10000 user 9.35 benchmark 9.34427795410156 bench/interp 9.34427795410156 gc 0.0)
|
||||||
|
("srfi-13.bm: strings: searching: contains contains-ci" 34000 user 2.29 benchmark 2.27054504394531 bench/interp 2.27054504394531 gc 0.0)
|
||||||
|
("srfi-13.bm: strings: searching: upcase downcase upcase! downcase!" 600 user 0.2 benchmark 0.199656677246094 bench/interp 0.199656677246094 gc 0.0)
|
||||||
|
("srfi-13.bm: strings: readers: read token, method 1" 1200 user 1.26 benchmark 1.25931335449219 bench/interp 1.25931335449219 gc 0.0)
|
||||||
|
("srfi-13.bm: strings: readers: read token, method 2" 1200 user 2.03 benchmark 2.02931335449219 bench/interp 2.02931335449219 gc 0.0)
|
||||||
|
("subr.bm: subr invocation: simple subr" 700000 user 0.47 benchmark 0.069456787109375 bench/interp 0.069456787109375 gc 0.0)
|
||||||
|
("subr.bm: subr invocation: generic subr" 700000 user 1.75 benchmark 1.34945678710938 bench/interp 1.34945678710938 gc 0.0)
|
||||||
|
("subr.bm: subr invocation: generic subr with rest arg" 700000 user 1.39 benchmark 0.989456787109375 bench/interp 0.989456787109375 gc 0.0)
|
||||||
|
("subr.bm: subr invocation: generic subr with rest arg and 3+ parameters" 700000 user 1.86 benchmark 1.45945678710938 bench/interp 1.45945678710938 gc 0.0)
|
||||||
|
("subr.bm: subr application: simple subr" 700000 user 0.91 benchmark 0.509456787109375 bench/interp 0.509456787109375 gc 0.0)
|
||||||
|
("subr.bm: subr application: generic subr" 700000 user 1.8 benchmark 1.39945678710938 bench/interp 1.39945678710938 gc 0.0)
|
||||||
|
("subr.bm: subr application: generic subr with rest arg" 700000 user 1.44 benchmark 1.03945678710937 bench/interp 1.03945678710937 gc 0.0)
|
||||||
|
("subr.bm: subr application: generic subr with rest arg and 3+ parameters" 700000 user 1.89 benchmark 1.48945678710937 bench/interp 1.48945678710937 gc 0.0)
|
||||||
|
("uniform-vector-read.bm: uniform-vector-read!: uniform-vector-write" 500 user 0.12 benchmark 0.119713897705078 bench/interp 0.119713897705078 gc 0.0)
|
||||||
|
("uniform-vector-read.bm: uniform-vector-read!: uniform-vector-read!" 500 user 0.02 benchmark 0.0197138977050781 bench/interp 0.0197138977050781 gc 0.0)
|
||||||
|
("uniform-vector-read.bm: uniform-vector-read!: string port" 5000 user 2.49 benchmark 2.48713897705078 bench/interp 2.48713897705078 gc 0.0)
|
500
build-aux/announce-gen
Executable file
500
build-aux/announce-gen
Executable file
|
@ -0,0 +1,500 @@
|
||||||
|
eval '(exit $?0)' && eval 'exec perl -wS "$0" ${1+"$@"}'
|
||||||
|
& eval 'exec perl -wS "$0" $argv:q'
|
||||||
|
if 0;
|
||||||
|
# Generate a release announcement message.
|
||||||
|
|
||||||
|
my $VERSION = '2009-11-20 13:36'; # UTC
|
||||||
|
# The definition above must lie within the first 8 lines in order
|
||||||
|
# for the Emacs time-stamp write hook (at end) to update it.
|
||||||
|
# If you change this file with Emacs, please let the write hook
|
||||||
|
# do its job. Otherwise, update this string manually.
|
||||||
|
|
||||||
|
# Copyright (C) 2002-2009 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
# Written by Jim Meyering
|
||||||
|
|
||||||
|
use strict;
|
||||||
|
|
||||||
|
use Getopt::Long;
|
||||||
|
use Digest::MD5;
|
||||||
|
use Digest::SHA1;
|
||||||
|
use POSIX qw(strftime);
|
||||||
|
|
||||||
|
(my $ME = $0) =~ s|.*/||;
|
||||||
|
|
||||||
|
my %valid_release_types = map {$_ => 1} qw (alpha beta stable);
|
||||||
|
my @archive_suffixes = ('tar.gz', 'tar.bz2', 'tar.lzma', 'tar.xz');
|
||||||
|
|
||||||
|
sub usage ($)
|
||||||
|
{
|
||||||
|
my ($exit_code) = @_;
|
||||||
|
my $STREAM = ($exit_code == 0 ? *STDOUT : *STDERR);
|
||||||
|
if ($exit_code != 0)
|
||||||
|
{
|
||||||
|
print $STREAM "Try `$ME --help' for more information.\n";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
my @types = sort keys %valid_release_types;
|
||||||
|
print $STREAM <<EOF;
|
||||||
|
Usage: $ME [OPTIONS]
|
||||||
|
Generate an announcement message.
|
||||||
|
|
||||||
|
OPTIONS:
|
||||||
|
|
||||||
|
These options must be specified:
|
||||||
|
|
||||||
|
--release-type=TYPE TYPE must be one of @types
|
||||||
|
--package-name=PACKAGE_NAME
|
||||||
|
--previous-version=VER
|
||||||
|
--current-version=VER
|
||||||
|
--gpg-key-id=ID The GnuPG ID of the key used to sign the tarballs
|
||||||
|
--url-directory=URL_DIR
|
||||||
|
|
||||||
|
The following are optional:
|
||||||
|
|
||||||
|
--news=NEWS_FILE
|
||||||
|
--bootstrap-tools=TOOL_LIST a comma-separated list of tools, e.g.,
|
||||||
|
autoconf,automake,bison,gnulib
|
||||||
|
--gnulib-version=VERSION report VERSION as the gnulib version, where
|
||||||
|
VERSION is the result of running git describe
|
||||||
|
in the gnulib source directory.
|
||||||
|
required if gnulib is in TOOL_LIST.
|
||||||
|
--no-print-checksums do not emit MD5 or SHA1 checksums
|
||||||
|
--archive-suffix=SUF add SUF to the list of archive suffixes
|
||||||
|
|
||||||
|
--help display this help and exit
|
||||||
|
--version output version information and exit
|
||||||
|
|
||||||
|
EOF
|
||||||
|
}
|
||||||
|
exit $exit_code;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
=item C<%size> = C<sizes (@file)>
|
||||||
|
|
||||||
|
Compute the sizes of the C<@file> and return them as a hash. Return
|
||||||
|
C<undef> if one of the computation failed.
|
||||||
|
|
||||||
|
=cut
|
||||||
|
|
||||||
|
sub sizes (@)
|
||||||
|
{
|
||||||
|
my (@file) = @_;
|
||||||
|
|
||||||
|
my $fail = 0;
|
||||||
|
my %res;
|
||||||
|
foreach my $f (@file)
|
||||||
|
{
|
||||||
|
my $cmd = "du --human $f";
|
||||||
|
my $t = `$cmd`;
|
||||||
|
# FIXME-someday: give a better diagnostic, a la $PROCESS_STATUS
|
||||||
|
$@
|
||||||
|
and (warn "$ME: command failed: `$cmd'\n"), $fail = 1;
|
||||||
|
chomp $t;
|
||||||
|
$t =~ s/^([\d.]+[MkK]).*/${1}B/;
|
||||||
|
$res{$f} = $t;
|
||||||
|
}
|
||||||
|
return $fail ? undef : %res;
|
||||||
|
}
|
||||||
|
|
||||||
|
=item C<print_locations ($title, \@url, \%size, @file)
|
||||||
|
|
||||||
|
Print a section C<$title> dedicated to the list of <@file>, which
|
||||||
|
sizes are stored in C<%size>, and which are available from the C<@url>.
|
||||||
|
|
||||||
|
=cut
|
||||||
|
|
||||||
|
sub print_locations ($\@\%@)
|
||||||
|
{
|
||||||
|
my ($title, $url, $size, @file) = @_;
|
||||||
|
print "Here are the $title:\n";
|
||||||
|
foreach my $url (@{$url})
|
||||||
|
{
|
||||||
|
for my $file (@file)
|
||||||
|
{
|
||||||
|
print " $url/$file";
|
||||||
|
print " (", $$size{$file}, ")"
|
||||||
|
if exists $$size{$file};
|
||||||
|
print "\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
print "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
=item C<print_checksums (@file)
|
||||||
|
|
||||||
|
Print the MD5 and SHA1 signature section for each C<@file>.
|
||||||
|
|
||||||
|
=cut
|
||||||
|
|
||||||
|
sub print_checksums (@)
|
||||||
|
{
|
||||||
|
my (@file) = @_;
|
||||||
|
|
||||||
|
print "Here are the MD5 and SHA1 checksums:\n";
|
||||||
|
print "\n";
|
||||||
|
|
||||||
|
foreach my $meth (qw (md5 sha1))
|
||||||
|
{
|
||||||
|
foreach my $f (@file)
|
||||||
|
{
|
||||||
|
open IN, '<', $f
|
||||||
|
or die "$ME: $f: cannot open for reading: $!\n";
|
||||||
|
binmode IN;
|
||||||
|
my $dig =
|
||||||
|
($meth eq 'md5'
|
||||||
|
? Digest::MD5->new->addfile(*IN)->hexdigest
|
||||||
|
: Digest::SHA1->new->addfile(*IN)->hexdigest);
|
||||||
|
close IN;
|
||||||
|
print "$dig $f\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
print "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
=item C<print_news_deltas ($news_file, $prev_version, $curr_version)
|
||||||
|
|
||||||
|
Print the section of the NEWS file C<$news_file> addressing changes
|
||||||
|
between versions C<$prev_version> and C<$curr_version>.
|
||||||
|
|
||||||
|
=cut
|
||||||
|
|
||||||
|
sub print_news_deltas ($$$)
|
||||||
|
{
|
||||||
|
my ($news_file, $prev_version, $curr_version) = @_;
|
||||||
|
|
||||||
|
print "\n$news_file\n\n";
|
||||||
|
|
||||||
|
# Print all lines from $news_file, starting with the first one
|
||||||
|
# that mentions $curr_version up to but not including
|
||||||
|
# the first occurrence of $prev_version.
|
||||||
|
my $in_items;
|
||||||
|
|
||||||
|
my $re_prefix = qr/(?:\* )?(?:Noteworthy c|Major c|C)(?i:hanges)/;
|
||||||
|
|
||||||
|
open NEWS, '<', $news_file
|
||||||
|
or die "$ME: $news_file: cannot open for reading: $!\n";
|
||||||
|
while (defined (my $line = <NEWS>))
|
||||||
|
{
|
||||||
|
if ( ! $in_items)
|
||||||
|
{
|
||||||
|
# Match lines like these:
|
||||||
|
# * Major changes in release 5.0.1:
|
||||||
|
# * Noteworthy changes in release 6.6 (2006-11-22) [stable]
|
||||||
|
$line =~ /^$re_prefix.*(?:[^\d.]|$)\Q$curr_version\E(?:[^\d.]|$)/o
|
||||||
|
or next;
|
||||||
|
$in_items = 1;
|
||||||
|
print $line;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
# This regexp must not match version numbers in NEWS items.
|
||||||
|
# For example, they might well say `introduced in 4.5.5',
|
||||||
|
# and we don't want that to match.
|
||||||
|
$line =~ /^$re_prefix.*(?:[^\d.]|$)\Q$prev_version\E(?:[^\d.]|$)/o
|
||||||
|
and last;
|
||||||
|
print $line;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
close NEWS;
|
||||||
|
|
||||||
|
$in_items
|
||||||
|
or die "$ME: $news_file: no matching lines for `$curr_version'\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
sub print_changelog_deltas ($$)
|
||||||
|
{
|
||||||
|
my ($package_name, $prev_version) = @_;
|
||||||
|
|
||||||
|
# Print new ChangeLog entries.
|
||||||
|
|
||||||
|
# First find all CVS-controlled ChangeLog files.
|
||||||
|
use File::Find;
|
||||||
|
my @changelog;
|
||||||
|
find ({wanted => sub {$_ eq 'ChangeLog' && -d 'CVS'
|
||||||
|
and push @changelog, $File::Find::name}},
|
||||||
|
'.');
|
||||||
|
|
||||||
|
# If there are no ChangeLog files, we're done.
|
||||||
|
@changelog
|
||||||
|
or return;
|
||||||
|
my %changelog = map {$_ => 1} @changelog;
|
||||||
|
|
||||||
|
# Reorder the list of files so that if there are ChangeLog
|
||||||
|
# files in the specified directories, they're listed first,
|
||||||
|
# in this order:
|
||||||
|
my @dir = qw ( . src lib m4 config doc );
|
||||||
|
|
||||||
|
# A typical @changelog array might look like this:
|
||||||
|
# ./ChangeLog
|
||||||
|
# ./po/ChangeLog
|
||||||
|
# ./m4/ChangeLog
|
||||||
|
# ./lib/ChangeLog
|
||||||
|
# ./doc/ChangeLog
|
||||||
|
# ./config/ChangeLog
|
||||||
|
my @reordered;
|
||||||
|
foreach my $d (@dir)
|
||||||
|
{
|
||||||
|
my $dot_slash = $d eq '.' ? $d : "./$d";
|
||||||
|
my $target = "$dot_slash/ChangeLog";
|
||||||
|
delete $changelog{$target}
|
||||||
|
and push @reordered, $target;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Append any remaining ChangeLog files.
|
||||||
|
push @reordered, sort keys %changelog;
|
||||||
|
|
||||||
|
# Remove leading `./'.
|
||||||
|
@reordered = map { s!^\./!!; $_ } @reordered;
|
||||||
|
|
||||||
|
print "\nChangeLog entries:\n\n";
|
||||||
|
# print join ("\n", @reordered), "\n";
|
||||||
|
|
||||||
|
$prev_version =~ s/\./_/g;
|
||||||
|
my $prev_cvs_tag = "\U$package_name\E-$prev_version";
|
||||||
|
|
||||||
|
my $cmd = "cvs -n diff -u -r$prev_cvs_tag -rHEAD @reordered";
|
||||||
|
open DIFF, '-|', $cmd
|
||||||
|
or die "$ME: cannot run `$cmd': $!\n";
|
||||||
|
# Print two types of lines, making minor changes:
|
||||||
|
# Lines starting with `+++ ', e.g.,
|
||||||
|
# +++ ChangeLog 22 Feb 2003 16:52:51 -0000 1.247
|
||||||
|
# and those starting with `+'.
|
||||||
|
# Don't print the others.
|
||||||
|
my $prev_printed_line_empty = 1;
|
||||||
|
while (defined (my $line = <DIFF>))
|
||||||
|
{
|
||||||
|
if ($line =~ /^\+\+\+ /)
|
||||||
|
{
|
||||||
|
my $separator = "*"x70 ."\n";
|
||||||
|
$line =~ s///;
|
||||||
|
$line =~ s/\s.*//;
|
||||||
|
$prev_printed_line_empty
|
||||||
|
or print "\n";
|
||||||
|
print $separator, $line, $separator;
|
||||||
|
}
|
||||||
|
elsif ($line =~ /^\+/)
|
||||||
|
{
|
||||||
|
$line =~ s///;
|
||||||
|
print $line;
|
||||||
|
$prev_printed_line_empty = ($line =~ /^$/);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
close DIFF;
|
||||||
|
|
||||||
|
# The exit code should be 1.
|
||||||
|
# Allow in case there are no modified ChangeLog entries.
|
||||||
|
$? == 256 || $? == 128
|
||||||
|
or warn "$ME: warning: `cmd' had unexpected exit code or signal ($?)\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
sub get_tool_versions ($$)
|
||||||
|
{
|
||||||
|
my ($tool_list, $gnulib_version) = @_;
|
||||||
|
@$tool_list
|
||||||
|
or return ();
|
||||||
|
|
||||||
|
my $fail;
|
||||||
|
my @tool_version_pair;
|
||||||
|
foreach my $t (@$tool_list)
|
||||||
|
{
|
||||||
|
if ($t eq 'gnulib')
|
||||||
|
{
|
||||||
|
push @tool_version_pair, ucfirst $t . ' ' . $gnulib_version;
|
||||||
|
next;
|
||||||
|
}
|
||||||
|
# Assume that the last "word" on the first line of
|
||||||
|
# `tool --version` output is the version string.
|
||||||
|
my ($first_line, undef) = split ("\n", `$t --version`);
|
||||||
|
if ($first_line =~ /.* (\d[\w.-]+)$/)
|
||||||
|
{
|
||||||
|
$t = ucfirst $t;
|
||||||
|
push @tool_version_pair, "$t $1";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
defined $first_line
|
||||||
|
and $first_line = '';
|
||||||
|
warn "$ME: $t: unexpected --version output\n:$first_line";
|
||||||
|
$fail = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$fail
|
||||||
|
and exit 1;
|
||||||
|
|
||||||
|
return @tool_version_pair;
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
# Neutralize the locale, so that, for instance, "du" does not
|
||||||
|
# issue "1,2" instead of "1.2", what confuses our regexps.
|
||||||
|
$ENV{LC_ALL} = "C";
|
||||||
|
|
||||||
|
my $release_type;
|
||||||
|
my $package_name;
|
||||||
|
my $prev_version;
|
||||||
|
my $curr_version;
|
||||||
|
my $gpg_key_id;
|
||||||
|
my @url_dir_list;
|
||||||
|
my @news_file;
|
||||||
|
my $bootstrap_tools;
|
||||||
|
my $gnulib_version;
|
||||||
|
my $print_checksums_p = 1;
|
||||||
|
|
||||||
|
GetOptions
|
||||||
|
(
|
||||||
|
'release-type=s' => \$release_type,
|
||||||
|
'package-name=s' => \$package_name,
|
||||||
|
'previous-version=s' => \$prev_version,
|
||||||
|
'current-version=s' => \$curr_version,
|
||||||
|
'gpg-key-id=s' => \$gpg_key_id,
|
||||||
|
'url-directory=s' => \@url_dir_list,
|
||||||
|
'news=s' => \@news_file,
|
||||||
|
'bootstrap-tools=s' => \$bootstrap_tools,
|
||||||
|
'gnulib-version=s' => \$gnulib_version,
|
||||||
|
'print-checksums!' => \$print_checksums_p,
|
||||||
|
'archive-suffix=s' => \@archive_suffixes,
|
||||||
|
|
||||||
|
help => sub { usage 0 },
|
||||||
|
version => sub { print "$ME version $VERSION\n"; exit },
|
||||||
|
) or usage 1;
|
||||||
|
|
||||||
|
my $fail = 0;
|
||||||
|
# Ensure that sure each required option is specified.
|
||||||
|
$release_type
|
||||||
|
or (warn "$ME: release type not specified\n"), $fail = 1;
|
||||||
|
$package_name
|
||||||
|
or (warn "$ME: package name not specified\n"), $fail = 1;
|
||||||
|
$prev_version
|
||||||
|
or (warn "$ME: previous version string not specified\n"), $fail = 1;
|
||||||
|
$curr_version
|
||||||
|
or (warn "$ME: current version string not specified\n"), $fail = 1;
|
||||||
|
$gpg_key_id
|
||||||
|
or (warn "$ME: GnuPG key ID not specified\n"), $fail = 1;
|
||||||
|
@url_dir_list
|
||||||
|
or (warn "$ME: URL directory name(s) not specified\n"), $fail = 1;
|
||||||
|
|
||||||
|
my @tool_list = split ',', $bootstrap_tools;
|
||||||
|
|
||||||
|
grep (/^gnulib$/, @tool_list) ^ defined $gnulib_version
|
||||||
|
and (warn "$ME: when specifying gnulib as a tool, you must also specify\n"
|
||||||
|
. "--gnulib-version=V, where V is the result of running git describe\n"
|
||||||
|
. "in the gnulib source directory.\n"), $fail = 1;
|
||||||
|
|
||||||
|
exists $valid_release_types{$release_type}
|
||||||
|
or (warn "$ME: `$release_type': invalid release type\n"), $fail = 1;
|
||||||
|
|
||||||
|
@ARGV
|
||||||
|
and (warn "$ME: too many arguments:\n", join ("\n", @ARGV), "\n"),
|
||||||
|
$fail = 1;
|
||||||
|
$fail
|
||||||
|
and usage 1;
|
||||||
|
|
||||||
|
my $my_distdir = "$package_name-$curr_version";
|
||||||
|
|
||||||
|
my $xd = "$package_name-$prev_version-$curr_version.xdelta";
|
||||||
|
|
||||||
|
my @candidates = map { "$my_distdir.$_" } @archive_suffixes;
|
||||||
|
my @tarballs = grep {-f $_} @candidates;
|
||||||
|
|
||||||
|
@tarballs
|
||||||
|
or die "$ME: none of " . join(', ', @candidates) . " were found\n";
|
||||||
|
my @sizable = @tarballs;
|
||||||
|
-f $xd
|
||||||
|
and push @sizable, $xd;
|
||||||
|
my %size = sizes (@sizable);
|
||||||
|
%size
|
||||||
|
or exit 1;
|
||||||
|
|
||||||
|
# The markup is escaped as <\# so that when this script is sent by
|
||||||
|
# mail (or part of a diff), Gnus is not triggered.
|
||||||
|
print <<EOF;
|
||||||
|
|
||||||
|
Subject: $my_distdir released [$release_type]
|
||||||
|
|
||||||
|
<\#secure method=pgpmime mode=sign>
|
||||||
|
|
||||||
|
FIXME: put comments here
|
||||||
|
|
||||||
|
EOF
|
||||||
|
|
||||||
|
print_locations ("compressed sources", @url_dir_list, %size, @tarballs);
|
||||||
|
-f $xd
|
||||||
|
and print_locations ("xdelta diffs (useful? if so, "
|
||||||
|
. "please tell bug-gnulib\@gnu.org)",
|
||||||
|
@url_dir_list, %size, $xd);
|
||||||
|
my @sig_files = map { "$_.sig" } @tarballs;
|
||||||
|
print_locations ("GPG detached signatures[*]", @url_dir_list, %size,
|
||||||
|
@sig_files);
|
||||||
|
if ($url_dir_list[0] =~ "gnu\.org")
|
||||||
|
{
|
||||||
|
print "To reduce load on the main server, use a mirror listed at:\n";
|
||||||
|
print " http://www.gnu.org/order/ftp.html\n\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
$print_checksums_p
|
||||||
|
and print_checksums (@sizable);
|
||||||
|
|
||||||
|
print <<EOF;
|
||||||
|
[*] You can use either of the above signature files to verify that
|
||||||
|
the corresponding file (without the .sig suffix) is intact. First,
|
||||||
|
be sure to download both the .sig file and the corresponding tarball.
|
||||||
|
Then, run a command like this:
|
||||||
|
|
||||||
|
gpg --verify $tarballs[0].sig
|
||||||
|
|
||||||
|
If that command fails because you don't have the required public key,
|
||||||
|
then run this command to import it:
|
||||||
|
|
||||||
|
gpg --keyserver keys.gnupg.net --recv-keys $gpg_key_id
|
||||||
|
|
||||||
|
and rerun the \`gpg --verify' command.
|
||||||
|
EOF
|
||||||
|
|
||||||
|
my @tool_versions = get_tool_versions (\@tool_list, $gnulib_version);
|
||||||
|
@tool_versions
|
||||||
|
and print "\nThis release was bootstrapped with the following tools:",
|
||||||
|
join ('', map {"\n $_"} @tool_versions), "\n";
|
||||||
|
|
||||||
|
print_news_deltas ($_, $prev_version, $curr_version)
|
||||||
|
foreach @news_file;
|
||||||
|
|
||||||
|
$release_type eq 'stable'
|
||||||
|
or print_changelog_deltas ($package_name, $prev_version);
|
||||||
|
|
||||||
|
exit 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
### Setup "GNU" style for perl-mode and cperl-mode.
|
||||||
|
## Local Variables:
|
||||||
|
## mode: perl
|
||||||
|
## perl-indent-level: 2
|
||||||
|
## perl-continued-statement-offset: 2
|
||||||
|
## perl-continued-brace-offset: 0
|
||||||
|
## perl-brace-offset: 0
|
||||||
|
## perl-brace-imaginary-offset: 0
|
||||||
|
## perl-label-offset: -2
|
||||||
|
## perl-extra-newline-before-brace: t
|
||||||
|
## perl-merge-trailing-else: nil
|
||||||
|
## eval: (add-hook 'write-file-hooks 'time-stamp)
|
||||||
|
## time-stamp-start: "my $VERSION = '"
|
||||||
|
## time-stamp-format: "%:y-%02m-%02d %02H:%02M"
|
||||||
|
## time-stamp-time-zone: "UTC"
|
||||||
|
## time-stamp-end: "'; # UTC"
|
||||||
|
## End:
|
361
build-aux/gendocs.sh
Normal file
361
build-aux/gendocs.sh
Normal file
|
@ -0,0 +1,361 @@
|
||||||
|
#!/bin/sh
|
||||||
|
# gendocs.sh -- generate a GNU manual in many formats. This script is
|
||||||
|
# mentioned in maintain.texi. See the help message below for usage details.
|
||||||
|
|
||||||
|
scriptversion=2009-09-09.22
|
||||||
|
|
||||||
|
# Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009
|
||||||
|
# Free Software Foundation, Inc.
|
||||||
|
#
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation; either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
#
|
||||||
|
# Original author: Mohit Agarwal.
|
||||||
|
# Send bug reports and any other correspondence to bug-texinfo@gnu.org.
|
||||||
|
|
||||||
|
prog=`basename "$0"`
|
||||||
|
srcdir=`pwd`
|
||||||
|
|
||||||
|
scripturl="http://savannah.gnu.org/cgi-bin/viewcvs/~checkout~/texinfo/texinfo/util/gendocs.sh"
|
||||||
|
templateurl="http://savannah.gnu.org/cgi-bin/viewcvs/~checkout~/texinfo/texinfo/util/gendocs_template"
|
||||||
|
|
||||||
|
: ${SETLANG="env LANG= LC_MESSAGES= LC_ALL= LANGUAGE="}
|
||||||
|
: ${MAKEINFO="makeinfo"}
|
||||||
|
: ${TEXI2DVI="texi2dvi -t @finalout"}
|
||||||
|
: ${DVIPS="dvips"}
|
||||||
|
: ${DOCBOOK2HTML="docbook2html"}
|
||||||
|
: ${DOCBOOK2PDF="docbook2pdf"}
|
||||||
|
: ${DOCBOOK2PS="docbook2ps"}
|
||||||
|
: ${DOCBOOK2TXT="docbook2txt"}
|
||||||
|
: ${GENDOCS_TEMPLATE_DIR="."}
|
||||||
|
: ${TEXI2HTML="texi2html"}
|
||||||
|
unset CDPATH
|
||||||
|
unset use_texi2html
|
||||||
|
|
||||||
|
version="gendocs.sh $scriptversion
|
||||||
|
|
||||||
|
Copyright 2009 Free Software Foundation, Inc.
|
||||||
|
There is NO warranty. You may redistribute this software
|
||||||
|
under the terms of the GNU General Public License.
|
||||||
|
For more information about these matters, see the files named COPYING."
|
||||||
|
|
||||||
|
usage="Usage: $prog [OPTION]... PACKAGE MANUAL-TITLE
|
||||||
|
|
||||||
|
Generate various output formats from PACKAGE.texinfo (or .texi or .txi) source.
|
||||||
|
See the GNU Maintainers document for a more extensive discussion:
|
||||||
|
http://www.gnu.org/prep/maintain_toc.html
|
||||||
|
|
||||||
|
Options:
|
||||||
|
-o OUTDIR write files into OUTDIR, instead of manual/.
|
||||||
|
--email ADR use ADR as contact in generated web pages.
|
||||||
|
--docbook convert to DocBook too (xml, txt, html, pdf and ps).
|
||||||
|
--html ARG pass indicated ARG to makeinfo or texi2html for HTML targets.
|
||||||
|
--texi2html use texi2html to generate HTML targets.
|
||||||
|
--help display this help and exit successfully.
|
||||||
|
--version display version information and exit successfully.
|
||||||
|
|
||||||
|
Simple example: $prog --email bug-gnu-emacs@gnu.org emacs \"GNU Emacs Manual\"
|
||||||
|
|
||||||
|
Typical sequence:
|
||||||
|
cd PACKAGESOURCE/doc
|
||||||
|
wget \"$scripturl\"
|
||||||
|
wget \"$templateurl\"
|
||||||
|
$prog --email BUGLIST MANUAL \"GNU MANUAL - One-line description\"
|
||||||
|
|
||||||
|
Output will be in a new subdirectory \"manual\" (by default, use -o OUTDIR
|
||||||
|
to override). Move all the new files into your web CVS tree, as
|
||||||
|
explained in the Web Pages node of maintain.texi.
|
||||||
|
|
||||||
|
Please use the --email ADDRESS option to specify your bug-reporting
|
||||||
|
address in the generated HTML pages.
|
||||||
|
|
||||||
|
MANUAL-TITLE is included as part of the HTML <title> of the overall
|
||||||
|
manual/index.html file. It should include the name of the package being
|
||||||
|
documented. manual/index.html is created by substitution from the file
|
||||||
|
$GENDOCS_TEMPLATE_DIR/gendocs_template. (Feel free to modify the
|
||||||
|
generic template for your own purposes.)
|
||||||
|
|
||||||
|
If you have several manuals, you'll need to run this script several
|
||||||
|
times with different MANUAL values, specifying a different output
|
||||||
|
directory with -o each time. Then write (by hand) an overall index.html
|
||||||
|
with links to them all.
|
||||||
|
|
||||||
|
If a manual's Texinfo sources are spread across several directories,
|
||||||
|
first copy or symlink all Texinfo sources into a single directory.
|
||||||
|
(Part of the script's work is to make a tar.gz of the sources.)
|
||||||
|
|
||||||
|
You can set the environment variables MAKEINFO, TEXI2DVI, and DVIPS to
|
||||||
|
control the programs that get executed, and GENDOCS_TEMPLATE_DIR to
|
||||||
|
control where the gendocs_template file is looked for. (With --docbook,
|
||||||
|
the environment variables DOCBOOK2HTML, DOCBOOK2PDF, DOCBOOK2PS, and
|
||||||
|
DOCBOOK2TXT are also respected.)
|
||||||
|
|
||||||
|
By default, makeinfo is run in the default (English) locale, since
|
||||||
|
that's the language of most Texinfo manuals. If you happen to have a
|
||||||
|
non-English manual and non-English web site, see the SETLANG setting
|
||||||
|
in the source.
|
||||||
|
|
||||||
|
Email bug reports or enhancement requests to bug-texinfo@gnu.org.
|
||||||
|
"
|
||||||
|
|
||||||
|
calcsize()
|
||||||
|
{
|
||||||
|
size=`ls -ksl $1 | awk '{print $1}'`
|
||||||
|
echo $size
|
||||||
|
}
|
||||||
|
|
||||||
|
MANUAL_TITLE=
|
||||||
|
PACKAGE=
|
||||||
|
EMAIL=webmasters@gnu.org # please override with --email
|
||||||
|
htmlarg=
|
||||||
|
outdir=manual
|
||||||
|
|
||||||
|
while test $# -gt 0; do
|
||||||
|
case $1 in
|
||||||
|
--email) shift; EMAIL=$1;;
|
||||||
|
--help) echo "$usage"; exit 0;;
|
||||||
|
--version) echo "$version"; exit 0;;
|
||||||
|
-o) shift; outdir=$1;;
|
||||||
|
--docbook) docbook=yes;;
|
||||||
|
--html) shift; htmlarg=$1;;
|
||||||
|
--texi2html) use_texi2html=1;;
|
||||||
|
-*)
|
||||||
|
echo "$0: Unknown option \`$1'." >&2
|
||||||
|
echo "$0: Try \`--help' for more information." >&2
|
||||||
|
exit 1;;
|
||||||
|
*)
|
||||||
|
if test -z "$PACKAGE"; then
|
||||||
|
PACKAGE=$1
|
||||||
|
elif test -z "$MANUAL_TITLE"; then
|
||||||
|
MANUAL_TITLE=$1
|
||||||
|
else
|
||||||
|
echo "$0: extra non-option argument \`$1'." >&2
|
||||||
|
exit 1
|
||||||
|
fi;;
|
||||||
|
esac
|
||||||
|
shift
|
||||||
|
done
|
||||||
|
|
||||||
|
if test -s "$srcdir/$PACKAGE.texinfo"; then
|
||||||
|
srcfile=$srcdir/$PACKAGE.texinfo
|
||||||
|
elif test -s "$srcdir/$PACKAGE.texi"; then
|
||||||
|
srcfile=$srcdir/$PACKAGE.texi
|
||||||
|
elif test -s "$srcdir/$PACKAGE.txi"; then
|
||||||
|
srcfile=$srcdir/$PACKAGE.txi
|
||||||
|
else
|
||||||
|
echo "$0: cannot find .texinfo or .texi or .txi for $PACKAGE in $srcdir." >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if test ! -r $GENDOCS_TEMPLATE_DIR/gendocs_template; then
|
||||||
|
echo "$0: cannot read $GENDOCS_TEMPLATE_DIR/gendocs_template." >&2
|
||||||
|
echo "$0: it is available from $templateurl." >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
case $outdir in
|
||||||
|
/*) dotdot_outdir="$outdir";;
|
||||||
|
*) dotdot_outdir="../$outdir";;
|
||||||
|
esac
|
||||||
|
|
||||||
|
echo Generating output formats for $srcfile
|
||||||
|
|
||||||
|
cmd="$SETLANG $MAKEINFO -o $PACKAGE.info \"$srcfile\""
|
||||||
|
echo "Generating info files... ($cmd)"
|
||||||
|
eval "$cmd"
|
||||||
|
mkdir -p $outdir/
|
||||||
|
tar czf $outdir/$PACKAGE.info.tar.gz $PACKAGE.info*
|
||||||
|
info_tgz_size=`calcsize $outdir/$PACKAGE.info.tar.gz`
|
||||||
|
# do not mv the info files, there's no point in having them available
|
||||||
|
# separately on the web.
|
||||||
|
|
||||||
|
cmd="${TEXI2DVI} \"$srcfile\""
|
||||||
|
echo "Generating dvi ... ($cmd)"
|
||||||
|
eval "$cmd"
|
||||||
|
|
||||||
|
# now, before we compress dvi:
|
||||||
|
echo Generating postscript...
|
||||||
|
${DVIPS} $PACKAGE -o
|
||||||
|
gzip -f -9 $PACKAGE.ps
|
||||||
|
ps_gz_size=`calcsize $PACKAGE.ps.gz`
|
||||||
|
mv $PACKAGE.ps.gz $outdir/
|
||||||
|
|
||||||
|
# compress/finish dvi:
|
||||||
|
gzip -f -9 $PACKAGE.dvi
|
||||||
|
dvi_gz_size=`calcsize $PACKAGE.dvi.gz`
|
||||||
|
mv $PACKAGE.dvi.gz $outdir/
|
||||||
|
|
||||||
|
cmd="${TEXI2DVI} --pdf \"$srcfile\""
|
||||||
|
echo "Generating pdf ... ($cmd)"
|
||||||
|
eval "$cmd"
|
||||||
|
pdf_size=`calcsize $PACKAGE.pdf`
|
||||||
|
mv $PACKAGE.pdf $outdir/
|
||||||
|
|
||||||
|
cmd="$SETLANG $MAKEINFO -o $PACKAGE.txt --no-split --no-headers \"$srcfile\""
|
||||||
|
echo "Generating ASCII... ($cmd)"
|
||||||
|
eval "$cmd"
|
||||||
|
ascii_size=`calcsize $PACKAGE.txt`
|
||||||
|
gzip -f -9 -c $PACKAGE.txt >$outdir/$PACKAGE.txt.gz
|
||||||
|
ascii_gz_size=`calcsize $outdir/$PACKAGE.txt.gz`
|
||||||
|
mv $PACKAGE.txt $outdir/
|
||||||
|
|
||||||
|
html_split()
|
||||||
|
{
|
||||||
|
opt="--split=$1 $htmlarg --node-files"
|
||||||
|
cmd="$SETLANG $TEXI2HTML --output $PACKAGE.html $opt \"$srcfile\""
|
||||||
|
echo "Generating html by $1... ($cmd)"
|
||||||
|
eval "$cmd"
|
||||||
|
split_html_dir=$PACKAGE.html
|
||||||
|
(
|
||||||
|
cd ${split_html_dir} || exit 1
|
||||||
|
ln -sf ${PACKAGE}.html index.html
|
||||||
|
tar -czf $dotdot_outdir/${PACKAGE}.html_$1.tar.gz -- *.html
|
||||||
|
)
|
||||||
|
eval html_$1_tgz_size=`calcsize $outdir/${PACKAGE}.html_$1.tar.gz`
|
||||||
|
rm -f $outdir/html_$1/*.html
|
||||||
|
mkdir -p $outdir/html_$1/
|
||||||
|
mv ${split_html_dir}/*.html $outdir/html_$1/
|
||||||
|
rmdir ${split_html_dir}
|
||||||
|
}
|
||||||
|
|
||||||
|
if test -z "$use_texi2html"; then
|
||||||
|
opt="--no-split --html -o $PACKAGE.html $htmlarg"
|
||||||
|
cmd="$SETLANG $MAKEINFO $opt \"$srcfile\""
|
||||||
|
echo "Generating monolithic html... ($cmd)"
|
||||||
|
rm -rf $PACKAGE.html # in case a directory is left over
|
||||||
|
eval "$cmd"
|
||||||
|
html_mono_size=`calcsize $PACKAGE.html`
|
||||||
|
gzip -f -9 -c $PACKAGE.html >$outdir/$PACKAGE.html.gz
|
||||||
|
html_mono_gz_size=`calcsize $outdir/$PACKAGE.html.gz`
|
||||||
|
mv $PACKAGE.html $outdir/
|
||||||
|
|
||||||
|
cmd="$SETLANG $MAKEINFO --html -o $PACKAGE.html $htmlarg \"$srcfile\""
|
||||||
|
echo "Generating html by node... ($cmd)"
|
||||||
|
eval "$cmd"
|
||||||
|
split_html_dir=$PACKAGE.html
|
||||||
|
(
|
||||||
|
cd ${split_html_dir} || exit 1
|
||||||
|
tar -czf $dotdot_outdir/${PACKAGE}.html_node.tar.gz -- *.html
|
||||||
|
)
|
||||||
|
html_node_tgz_size=`calcsize $outdir/${PACKAGE}.html_node.tar.gz`
|
||||||
|
rm -f $outdir/html_node/*.html
|
||||||
|
mkdir -p $outdir/html_node/
|
||||||
|
mv ${split_html_dir}/*.html $outdir/html_node/
|
||||||
|
rmdir ${split_html_dir}
|
||||||
|
else
|
||||||
|
cmd="$SETLANG $TEXI2HTML --output $PACKAGE.html $htmlarg \"$srcfile\""
|
||||||
|
echo "Generating monolithic html... ($cmd)"
|
||||||
|
rm -rf $PACKAGE.html # in case a directory is left over
|
||||||
|
eval "$cmd"
|
||||||
|
html_mono_size=`calcsize $PACKAGE.html`
|
||||||
|
gzip -f -9 -c $PACKAGE.html >$outdir/$PACKAGE.html.gz
|
||||||
|
html_mono_gz_size=`calcsize $outdir/$PACKAGE.html.gz`
|
||||||
|
mv $PACKAGE.html $outdir/
|
||||||
|
|
||||||
|
html_split node
|
||||||
|
html_split chapter
|
||||||
|
html_split section
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo Making .tar.gz for sources...
|
||||||
|
srcfiles=`ls *.texinfo *.texi *.txi *.eps 2>/dev/null`
|
||||||
|
tar cvzfh $outdir/$PACKAGE.texi.tar.gz $srcfiles
|
||||||
|
texi_tgz_size=`calcsize $outdir/$PACKAGE.texi.tar.gz`
|
||||||
|
|
||||||
|
if test -n "$docbook"; then
|
||||||
|
cmd="$SETLANG $MAKEINFO -o - --docbook \"$srcfile\" > ${srcdir}/$PACKAGE-db.xml"
|
||||||
|
echo "Generating docbook XML... $(cmd)"
|
||||||
|
eval "$cmd"
|
||||||
|
docbook_xml_size=`calcsize $PACKAGE-db.xml`
|
||||||
|
gzip -f -9 -c $PACKAGE-db.xml >$outdir/$PACKAGE-db.xml.gz
|
||||||
|
docbook_xml_gz_size=`calcsize $outdir/$PACKAGE-db.xml.gz`
|
||||||
|
mv $PACKAGE-db.xml $outdir/
|
||||||
|
|
||||||
|
cmd="${DOCBOOK2HTML} -o $split_html_db_dir ${outdir}/$PACKAGE-db.xml"
|
||||||
|
echo "Generating docbook HTML... ($cmd)"
|
||||||
|
eval "$cmd"
|
||||||
|
split_html_db_dir=html_node_db
|
||||||
|
(
|
||||||
|
cd ${split_html_db_dir} || exit 1
|
||||||
|
tar -czf $dotdot_outdir/${PACKAGE}.html_node_db.tar.gz -- *.html
|
||||||
|
)
|
||||||
|
html_node_db_tgz_size=`calcsize $outdir/${PACKAGE}.html_node_db.tar.gz`
|
||||||
|
rm -f $outdir/html_node_db/*.html
|
||||||
|
mkdir -p $outdir/html_node_db
|
||||||
|
mv ${split_html_db_dir}/*.html $outdir/html_node_db/
|
||||||
|
rmdir ${split_html_db_dir}
|
||||||
|
|
||||||
|
cmd="${DOCBOOK2TXT} ${outdir}/$PACKAGE-db.xml"
|
||||||
|
echo "Generating docbook ASCII... ($cmd)"
|
||||||
|
eval "$cmd"
|
||||||
|
docbook_ascii_size=`calcsize $PACKAGE-db.txt`
|
||||||
|
mv $PACKAGE-db.txt $outdir/
|
||||||
|
|
||||||
|
cmd="${DOCBOOK2PS} ${outdir}/$PACKAGE-db.xml"
|
||||||
|
echo "Generating docbook PS... $(cmd)"
|
||||||
|
eval "$cmd"
|
||||||
|
gzip -f -9 -c $PACKAGE-db.ps >$outdir/$PACKAGE-db.ps.gz
|
||||||
|
docbook_ps_gz_size=`calcsize $outdir/$PACKAGE-db.ps.gz`
|
||||||
|
mv $PACKAGE-db.ps $outdir/
|
||||||
|
|
||||||
|
cmd="${DOCBOOK2PDF} ${outdir}/$PACKAGE-db.xml"
|
||||||
|
echo "Generating docbook PDF... ($cmd)"
|
||||||
|
eval "$cmd"
|
||||||
|
docbook_pdf_size=`calcsize $PACKAGE-db.pdf`
|
||||||
|
mv $PACKAGE-db.pdf $outdir/
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Writing index file..."
|
||||||
|
if test -z "$use_texi2html"; then
|
||||||
|
CONDS="/%%IF *HTML_SECTION%%/,/%%ENDIF *HTML_SECTION%%/d;\
|
||||||
|
/%%IF *HTML_CHAPTER%%/,/%%ENDIF *HTML_CHAPTER%%/d"
|
||||||
|
else
|
||||||
|
CONDS="/%%ENDIF.*%%/d;/%%IF *HTML_SECTION%%/d;/%%IF *HTML_CHAPTER%%/d"
|
||||||
|
fi
|
||||||
|
curdate=`$SETLANG date '+%B %d, %Y'`
|
||||||
|
sed \
|
||||||
|
-e "s!%%TITLE%%!$MANUAL_TITLE!g" \
|
||||||
|
-e "s!%%EMAIL%%!$EMAIL!g" \
|
||||||
|
-e "s!%%PACKAGE%%!$PACKAGE!g" \
|
||||||
|
-e "s!%%DATE%%!$curdate!g" \
|
||||||
|
-e "s!%%HTML_MONO_SIZE%%!$html_mono_size!g" \
|
||||||
|
-e "s!%%HTML_MONO_GZ_SIZE%%!$html_mono_gz_size!g" \
|
||||||
|
-e "s!%%HTML_NODE_TGZ_SIZE%%!$html_node_tgz_size!g" \
|
||||||
|
-e "s!%%HTML_SECTION_TGZ_SIZE%%!$html_section_tgz_size!g" \
|
||||||
|
-e "s!%%HTML_CHAPTER_TGZ_SIZE%%!$html_chapter_tgz_size!g" \
|
||||||
|
-e "s!%%INFO_TGZ_SIZE%%!$info_tgz_size!g" \
|
||||||
|
-e "s!%%DVI_GZ_SIZE%%!$dvi_gz_size!g" \
|
||||||
|
-e "s!%%PDF_SIZE%%!$pdf_size!g" \
|
||||||
|
-e "s!%%PS_GZ_SIZE%%!$ps_gz_size!g" \
|
||||||
|
-e "s!%%ASCII_SIZE%%!$ascii_size!g" \
|
||||||
|
-e "s!%%ASCII_GZ_SIZE%%!$ascii_gz_size!g" \
|
||||||
|
-e "s!%%TEXI_TGZ_SIZE%%!$texi_tgz_size!g" \
|
||||||
|
-e "s!%%DOCBOOK_HTML_NODE_TGZ_SIZE%%!$html_node_db_tgz_size!g" \
|
||||||
|
-e "s!%%DOCBOOK_ASCII_SIZE%%!$docbook_ascii_size!g" \
|
||||||
|
-e "s!%%DOCBOOK_PS_GZ_SIZE%%!$docbook_ps_gz_size!g" \
|
||||||
|
-e "s!%%DOCBOOK_PDF_SIZE%%!$docbook_pdf_size!g" \
|
||||||
|
-e "s!%%DOCBOOK_XML_SIZE%%!$docbook_xml_size!g" \
|
||||||
|
-e "s!%%DOCBOOK_XML_GZ_SIZE%%!$docbook_xml_gz_size!g" \
|
||||||
|
-e "s,%%SCRIPTURL%%,$scripturl,g" \
|
||||||
|
-e "s!%%SCRIPTNAME%%!$prog!g" \
|
||||||
|
-e "$CONDS" \
|
||||||
|
$GENDOCS_TEMPLATE_DIR/gendocs_template >$outdir/index.html
|
||||||
|
|
||||||
|
echo "Done, see $outdir/ subdirectory for new files."
|
||||||
|
|
||||||
|
# Local variables:
|
||||||
|
# eval: (add-hook 'write-file-hooks 'time-stamp)
|
||||||
|
# time-stamp-start: "scriptversion="
|
||||||
|
# time-stamp-format: "%:y-%02m-%02d.%02H"
|
||||||
|
# time-stamp-end: "$"
|
||||||
|
# End:
|
|
@ -1,7 +1,9 @@
|
||||||
#!/usr/bin/perl
|
eval '(exit $?0)' && eval 'exec perl -wS "$0" ${1+"$@"}'
|
||||||
|
& eval 'exec perl -wS "$0" $argv:q'
|
||||||
|
if 0;
|
||||||
# Convert git log output to ChangeLog format.
|
# Convert git log output to ChangeLog format.
|
||||||
|
|
||||||
my $VERSION = '2009-06-04 08:53'; # UTC
|
my $VERSION = '2009-10-30 13:46'; # UTC
|
||||||
# The definition above must lie within the first 8 lines in order
|
# The definition above must lie within the first 8 lines in order
|
||||||
# for the Emacs time-stamp write hook (at end) to update it.
|
# for the Emacs time-stamp write hook (at end) to update it.
|
||||||
# If you change this file with Emacs, please let the write hook
|
# If you change this file with Emacs, please let the write hook
|
||||||
|
@ -60,6 +62,9 @@ OPTIONS:
|
||||||
|
|
||||||
--since=DATE convert only the logs since DATE;
|
--since=DATE convert only the logs since DATE;
|
||||||
the default is to convert all log entries.
|
the default is to convert all log entries.
|
||||||
|
--format=FMT set format string for commit subject and body;
|
||||||
|
see 'man git-log' for the list of format metacharacters;
|
||||||
|
the default is '%s%n%b%n'
|
||||||
|
|
||||||
--help display this help and exit
|
--help display this help and exit
|
||||||
--version output version information and exit
|
--version output version information and exit
|
||||||
|
@ -96,15 +101,17 @@ sub quoted_cmd(@)
|
||||||
|
|
||||||
{
|
{
|
||||||
my $since_date = '1970-01-01 UTC';
|
my $since_date = '1970-01-01 UTC';
|
||||||
|
my $format_string = '%s%n%b%n';
|
||||||
GetOptions
|
GetOptions
|
||||||
(
|
(
|
||||||
help => sub { usage 0 },
|
help => sub { usage 0 },
|
||||||
version => sub { print "$ME version $VERSION\n"; exit },
|
version => sub { print "$ME version $VERSION\n"; exit },
|
||||||
'since=s' => \$since_date,
|
'since=s' => \$since_date,
|
||||||
|
'format=s' => \$format_string,
|
||||||
) or usage 1;
|
) or usage 1;
|
||||||
|
|
||||||
my @cmd = (qw (git log --log-size), "--since=$since_date",
|
my @cmd = (qw (git log --log-size), "--since=$since_date",
|
||||||
'--pretty=format:%ct %an <%ae>%n%n%s%n%b%n', @ARGV);
|
'--pretty=format:%ct %an <%ae>%n%n'.$format_string, @ARGV);
|
||||||
open PIPE, '-|', @cmd
|
open PIPE, '-|', @cmd
|
||||||
or die ("$ME: failed to run `". quoted_cmd (@cmd) ."': $!\n"
|
or die ("$ME: failed to run `". quoted_cmd (@cmd) ."': $!\n"
|
||||||
. "(Is your Git too old? Version 1.5.1 or later is required.)\n");
|
. "(Is your Git too old? Version 1.5.1 or later is required.)\n");
|
||||||
|
@ -174,6 +181,7 @@ sub quoted_cmd(@)
|
||||||
}
|
}
|
||||||
|
|
||||||
# Local Variables:
|
# Local Variables:
|
||||||
|
# mode: perl
|
||||||
# indent-tabs-mode: nil
|
# indent-tabs-mode: nil
|
||||||
# eval: (add-hook 'write-file-hooks 'time-stamp)
|
# eval: (add-hook 'write-file-hooks 'time-stamp)
|
||||||
# time-stamp-start: "my $VERSION = '"
|
# time-stamp-start: "my $VERSION = '"
|
||||||
|
|
115
build-aux/gnu-web-doc-update
Executable file
115
build-aux/gnu-web-doc-update
Executable file
|
@ -0,0 +1,115 @@
|
||||||
|
#!/bin/sh
|
||||||
|
# Run this after each non-alpha release, to update the web documentation at
|
||||||
|
# http://www.gnu.org/software/$pkg/manual/
|
||||||
|
# This script must be run from the top-level directory,
|
||||||
|
# assumes you're using git for revision control,
|
||||||
|
# and requires a .prev-version file as well as a Makefile,
|
||||||
|
# from which it extracts the version number and package name, respectively.
|
||||||
|
# Also, it assumes all documentation is in the doc/ sub-directory.
|
||||||
|
|
||||||
|
VERSION=2009-07-21.16; # UTC
|
||||||
|
|
||||||
|
# Copyright (C) 2009 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
# Requirements: everything required to bootstrap your package,
|
||||||
|
# plus these: git, cvs, cvsu, rsync, mktemp
|
||||||
|
|
||||||
|
ME=`basename "$0"`
|
||||||
|
warn() { printf '%s: %s\n' "$ME" "$*" >&2; }
|
||||||
|
die() { warn "$*"; exit 1; }
|
||||||
|
|
||||||
|
help_version()
|
||||||
|
{
|
||||||
|
case $1 in
|
||||||
|
--help) cat <<EOF
|
||||||
|
Usage: $ME
|
||||||
|
|
||||||
|
Run this script (no options or arguments) after each non-alpha release,
|
||||||
|
to update the web documentation at http://www.gnu.org/software/\$pkg/manual/
|
||||||
|
Run it from your project's the top-level directory.
|
||||||
|
|
||||||
|
Options:
|
||||||
|
--help print this help, then exit
|
||||||
|
--version print version number, then exit
|
||||||
|
|
||||||
|
Report bugs and patches to <bug-gnulib@gnu.org>.
|
||||||
|
EOF
|
||||||
|
exit ;;
|
||||||
|
|
||||||
|
--version)
|
||||||
|
year=`echo "$VERSION" | sed 's/[^0-9].*//'`
|
||||||
|
cat <<EOF
|
||||||
|
$ME $VERSION
|
||||||
|
Copyright (C) $year Free Software Foundation, Inc,
|
||||||
|
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
|
||||||
|
This is free software: you are free to change and redistribute it.
|
||||||
|
There is NO WARRANTY, to the extent permitted by law.
|
||||||
|
EOF
|
||||||
|
exit ;;
|
||||||
|
|
||||||
|
*) die "unrecognized option: $1";;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
|
case $# in
|
||||||
|
0) ;;
|
||||||
|
1) help_version $1 ;;
|
||||||
|
*) die "$ME: too many options" ;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
prev=.prev-version
|
||||||
|
version=$(cat $prev) || die "$ME: no $prev file?"
|
||||||
|
pkg=$(sed -n 's/^PACKAGE = \(.*\)/\1/p' Makefile) || die "$ME: no Makefile?"
|
||||||
|
tmp_branch=web-doc-$version-$$
|
||||||
|
|
||||||
|
cleanup()
|
||||||
|
{
|
||||||
|
__st=$?;
|
||||||
|
rm -rf "$tmp"
|
||||||
|
git checkout master
|
||||||
|
git branch -d $tmp_branch
|
||||||
|
exit $__st
|
||||||
|
}
|
||||||
|
trap cleanup 0
|
||||||
|
trap 'exit $?' 1 2 13 15
|
||||||
|
|
||||||
|
# We must build using sources for which --version reports the
|
||||||
|
# just-released version number, not some string like 7.6.18-20761.
|
||||||
|
# That version string propagates into all documentation.
|
||||||
|
git checkout -b $tmp_branch v$version
|
||||||
|
./bootstrap && ./configure && make && make web-manual
|
||||||
|
|
||||||
|
tmp=$(mktemp -d --tmpdir=. web-doc-update.XXXXXX) || exit 1
|
||||||
|
( cd $tmp \
|
||||||
|
&& cvs -d $USER@cvs.sv.gnu.org:/webcvs/$pkg co $pkg )
|
||||||
|
rsync -avP doc/manual/ $tmp/$pkg/manual
|
||||||
|
|
||||||
|
(
|
||||||
|
cd $tmp/$pkg/manual
|
||||||
|
|
||||||
|
# Add any new files:
|
||||||
|
cvsu --types='?'|sed s/..// | xargs --no-run-if-empty -- cvs add -ko
|
||||||
|
|
||||||
|
cvs ci -m $version
|
||||||
|
)
|
||||||
|
|
||||||
|
# Local variables:
|
||||||
|
# eval: (add-hook 'write-file-hooks 'time-stamp)
|
||||||
|
# time-stamp-start: "VERSION="
|
||||||
|
# time-stamp-format: "%:y-%02m-%02d.%02H"
|
||||||
|
# time-stamp-time-zone: "UTC"
|
||||||
|
# time-stamp-end: "; # UTC"
|
||||||
|
# End:
|
412
build-aux/gnupload
Executable file
412
build-aux/gnupload
Executable file
|
@ -0,0 +1,412 @@
|
||||||
|
#!/bin/sh
|
||||||
|
# Sign files and upload them.
|
||||||
|
|
||||||
|
scriptversion=2009-04-28.21; # UTC
|
||||||
|
|
||||||
|
# Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation; either version 3, or (at your option)
|
||||||
|
# any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
# Originally written by Alexandre Duret-Lutz <adl@gnu.org>.
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
GPG='gpg --batch --no-tty'
|
||||||
|
conffile=.gnuploadrc
|
||||||
|
to=
|
||||||
|
dry_run=false
|
||||||
|
symlink_files=
|
||||||
|
delete_files=
|
||||||
|
delete_symlinks=
|
||||||
|
collect_var=
|
||||||
|
dbg=
|
||||||
|
|
||||||
|
usage="Usage: $0 [OPTIONS]... [COMMAND] FILES... [[COMMAND] FILES...]
|
||||||
|
|
||||||
|
Sign all FILES, and upload them to selected destinations, according to
|
||||||
|
<http://www.gnu.org/prep/maintain/html_node/Automated-FTP-Uploads.html>.
|
||||||
|
|
||||||
|
Commands:
|
||||||
|
--delete delete FILES from destination
|
||||||
|
--symlink create symbolic links
|
||||||
|
--rmsymlink remove symbolic links
|
||||||
|
-- treat the remaining arguments as files to upload
|
||||||
|
|
||||||
|
Options:
|
||||||
|
--help print this help text and exit
|
||||||
|
--to DEST specify one destination for FILES
|
||||||
|
(multiple --to options are allowed)
|
||||||
|
--user NAME sign with key NAME
|
||||||
|
--symlink-regex[=EXPR] use sed script EXPR to compute symbolic link names
|
||||||
|
--dry-run do nothing, show what would have been done
|
||||||
|
--version output version information and exit
|
||||||
|
|
||||||
|
If --symlink-regex is given without EXPR, then the link target name
|
||||||
|
is created by replacing the version information with \`-latest', e.g.:
|
||||||
|
|
||||||
|
foo-1.3.4.tar.gz -> foo-latest.tar.gz
|
||||||
|
|
||||||
|
Recognized destinations are:
|
||||||
|
alpha.gnu.org:DIRECTORY
|
||||||
|
savannah.gnu.org:DIRECTORY
|
||||||
|
savannah.nongnu.org:DIRECTORY
|
||||||
|
ftp.gnu.org:DIRECTORY
|
||||||
|
build directive files and upload files by FTP
|
||||||
|
download.gnu.org.ua:{alpha|ftp}/DIRECTORY
|
||||||
|
build directive files and upload files by SFTP
|
||||||
|
[user@]host:DIRECTORY upload files with scp
|
||||||
|
|
||||||
|
Options and commands are applied in order. If the file $conffile exists
|
||||||
|
in the current working directory, its contents are prepended to the
|
||||||
|
actual command line options. Use this to keep your defaults. Comments
|
||||||
|
(#) and empty lines in $conffile are allowed.
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
1. Upload automake-1.8.2b.tar.gz and automake-1.8.2b.tar.bz2 to two sites:
|
||||||
|
gnupload --to sources.redhat.com:~ftp/pub/automake \\
|
||||||
|
--to alpha.gnu.org:automake \\
|
||||||
|
automake-1.8.2b.tar.gz automake-1.8.2b.tar.bz2
|
||||||
|
|
||||||
|
2. Same as above, but also create symbolic links to automake-latest.tar.*:
|
||||||
|
gnupload --to sources.redhat.com:~ftp/pub/automake \\
|
||||||
|
--to alpha.gnu.org:automake \\
|
||||||
|
--symlink-regex \\
|
||||||
|
automake-1.8.2b.tar.gz automake-1.8.2b.tar.bz2
|
||||||
|
|
||||||
|
3. Symlink automake-1.8.2b.tar.gz to automake-latest.tar.gz and
|
||||||
|
automake-1.8.2b.tar.bz2 to automake-latest.tar.bz2 on both sites:
|
||||||
|
|
||||||
|
gnupload --to sources.redhat.com:~ftp/pub/automake \\
|
||||||
|
--to alpha.gnu.org:automake \\
|
||||||
|
--symlink automake-1.8.2b.tar.gz automake-latest.tar.gz \\
|
||||||
|
automake-1.8.2b.tar.bz2 automake-latest.tar.bz2
|
||||||
|
|
||||||
|
4. Delete automake-1.8.2a.tar.gz and .bz2, remove symlink
|
||||||
|
automake-latest.tar.gz and upload automake-1.8.2b.tar.gz:
|
||||||
|
|
||||||
|
gnupload --to sources.redhat.com:~ftp/pub/automake \\
|
||||||
|
--to alpha.gnu.org:automake \\
|
||||||
|
--delete automake-1.8.2a.tar.gz automake-1.8.2a.tar.bz2 \\
|
||||||
|
--rmsymlink automake-latest.tar.gz \\
|
||||||
|
-- \\
|
||||||
|
automake-1.8.2b.tar.gz automake-1.8.2b.tar.bz2
|
||||||
|
|
||||||
|
Report bugs to <bug-automake@gnu.org>.
|
||||||
|
Send patches to <automake-patches@gnu.org>."
|
||||||
|
|
||||||
|
# Read local configuration file
|
||||||
|
if test -r "$conffile"; then
|
||||||
|
echo "$0: Reading configuration file $conffile"
|
||||||
|
eval set x "`sed 's/#.*$//;/^$/d' \"$conffile\" | tr '\012\015' ' '` \"\$@\""
|
||||||
|
shift
|
||||||
|
fi
|
||||||
|
|
||||||
|
while test -n "$1"; do
|
||||||
|
case $1 in
|
||||||
|
-*)
|
||||||
|
collect_var=
|
||||||
|
case $1 in
|
||||||
|
--help)
|
||||||
|
echo "$usage"
|
||||||
|
exit $?
|
||||||
|
;;
|
||||||
|
--to)
|
||||||
|
if test -z "$2"; then
|
||||||
|
echo "$0: Missing argument for --to" 1>&2
|
||||||
|
exit 1
|
||||||
|
else
|
||||||
|
to="$to $2"
|
||||||
|
shift
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
--user)
|
||||||
|
if test -z "$2"; then
|
||||||
|
echo "$0: Missing argument for --user" 1>&2
|
||||||
|
exit 1
|
||||||
|
else
|
||||||
|
GPG="$GPG --local-user $2"
|
||||||
|
shift
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
--delete)
|
||||||
|
collect_var=delete_files
|
||||||
|
;;
|
||||||
|
--rmsymlink)
|
||||||
|
collect_var=delete_symlinks
|
||||||
|
;;
|
||||||
|
--symlink-regex=*)
|
||||||
|
symlink_expr=`expr "$1" : '[^=]*=\(.*\)'`
|
||||||
|
;;
|
||||||
|
--symlink-regex)
|
||||||
|
symlink_expr='s|-[0-9][0-9\.]*\(-[0-9][0-9]*\)\{0,1\}\.|-latest.|'
|
||||||
|
;;
|
||||||
|
--symlink)
|
||||||
|
collect_var=symlink_files
|
||||||
|
;;
|
||||||
|
--dry-run|-n)
|
||||||
|
dry_run=:
|
||||||
|
;;
|
||||||
|
--version)
|
||||||
|
echo "gnupload $scriptversion"
|
||||||
|
exit $?
|
||||||
|
;;
|
||||||
|
--)
|
||||||
|
shift
|
||||||
|
break
|
||||||
|
;;
|
||||||
|
-*)
|
||||||
|
echo "$0: Unknown option \`$1', try \`$0 --help'" 1>&2
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
if test -z "$collect_var"; then
|
||||||
|
break
|
||||||
|
else
|
||||||
|
eval "$collect_var=\"\$$collect_var $1\""
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
shift
|
||||||
|
done
|
||||||
|
|
||||||
|
dprint()
|
||||||
|
{
|
||||||
|
echo "Running $*..."
|
||||||
|
}
|
||||||
|
|
||||||
|
if $dry_run; then
|
||||||
|
dbg=dprint
|
||||||
|
fi
|
||||||
|
|
||||||
|
if test -z "$to"; then
|
||||||
|
echo "$0: Missing destination sites" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if test -n "$symlink_files"; then
|
||||||
|
x=`echo "$symlink_files" | sed 's/[^ ]//g;s/ //g'`
|
||||||
|
if test -n "$x"; then
|
||||||
|
echo "$0: Odd number of symlink arguments" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if test $# = 0; then
|
||||||
|
if test -z "${symlink_files}${delete_files}${delete_symlinks}"; then
|
||||||
|
echo "$0: No file to upload" 1>&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
# Make sure all files exist. We don't want to ask
|
||||||
|
# for the passphrase if the script will fail.
|
||||||
|
for file
|
||||||
|
do
|
||||||
|
if test ! -f $file; then
|
||||||
|
echo "$0: Cannot find \`$file'" 1>&2
|
||||||
|
exit 1
|
||||||
|
elif test -n "$symlink_expr"; then
|
||||||
|
linkname=`echo $file | sed "$symlink_expr"`
|
||||||
|
if test -z "$linkname"; then
|
||||||
|
echo "$0: symlink expression produces empty results" >&2
|
||||||
|
exit 1
|
||||||
|
elif test "$linkname" = $file; then
|
||||||
|
echo "$0: symlink expression does not alter file name" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Make sure passphrase is not exported in the environment.
|
||||||
|
unset passphrase
|
||||||
|
|
||||||
|
# Reset PATH to be sure that echo is a built-in. We will later use
|
||||||
|
# `echo $passphrase' to output the passphrase, so it is important that
|
||||||
|
# it is a built-in (third-party programs tend to appear in `ps'
|
||||||
|
# listings with their arguments...).
|
||||||
|
# Remember this script runs with `set -e', so if echo is not built-in
|
||||||
|
# it will exit now.
|
||||||
|
PATH=/empty echo -n "Enter GPG passphrase: "
|
||||||
|
stty -echo
|
||||||
|
read -r passphrase
|
||||||
|
stty echo
|
||||||
|
echo
|
||||||
|
|
||||||
|
if test $# -ne 0; then
|
||||||
|
for file
|
||||||
|
do
|
||||||
|
echo "Signing $file..."
|
||||||
|
rm -f $file.sig
|
||||||
|
echo "$passphrase" | $dbg $GPG --passphrase-fd 0 -ba -o $file.sig $file
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
# mkdirective DESTDIR BASE FILE STMT
|
||||||
|
# Arguments: See upload, below
|
||||||
|
mkdirective ()
|
||||||
|
{
|
||||||
|
stmt="$4"
|
||||||
|
if test -n "$3"; then
|
||||||
|
stmt="
|
||||||
|
filename: $3$stmt"
|
||||||
|
fi
|
||||||
|
|
||||||
|
cat >${2}.directive<<EOF
|
||||||
|
version: 1.1
|
||||||
|
directory: $1
|
||||||
|
comment: gnupload v. $scriptversion$stmt
|
||||||
|
EOF
|
||||||
|
if $dry_run; then
|
||||||
|
echo "File ${2}.directive:"
|
||||||
|
cat ${2}.directive
|
||||||
|
echo "File ${2}.directive:" | sed 's/./-/g'
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
mksymlink ()
|
||||||
|
{
|
||||||
|
while test $# -ne 0
|
||||||
|
do
|
||||||
|
echo "symlink: $1 $2"
|
||||||
|
shift
|
||||||
|
shift
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
# upload DEST DESTDIR BASE FILE STMT FILES
|
||||||
|
# Arguments:
|
||||||
|
# DEST Destination site;
|
||||||
|
# DESTDIR Destination directory;
|
||||||
|
# BASE Base name for the directive file;
|
||||||
|
# FILE Name of the file to distribute (may be empty);
|
||||||
|
# STMT Additional statements for the directive file;
|
||||||
|
# FILES List of files to upload.
|
||||||
|
upload ()
|
||||||
|
{
|
||||||
|
dest=$1
|
||||||
|
destdir=$2
|
||||||
|
base=$3
|
||||||
|
file=$4
|
||||||
|
stmt=$5
|
||||||
|
files=$6
|
||||||
|
|
||||||
|
rm -f $base.directive $base.directive.asc
|
||||||
|
case $dest in
|
||||||
|
alpha.gnu.org:*)
|
||||||
|
mkdirective "$destdir" "$base" "$file" "$stmt"
|
||||||
|
echo "$passphrase" | $dbg $GPG --passphrase-fd 0 --clearsign $base.directive
|
||||||
|
$dbg ncftpput ftp-upload.gnu.org /incoming/alpha $files $base.directive.asc
|
||||||
|
;;
|
||||||
|
ftp.gnu.org:*)
|
||||||
|
mkdirective "$destdir" "$base" "$file" "$stmt"
|
||||||
|
echo "$passphrase" | $dbg $GPG --passphrase-fd 0 --clearsign $base.directive
|
||||||
|
$dbg ncftpput ftp-upload.gnu.org /incoming/ftp $files $base.directive.asc
|
||||||
|
;;
|
||||||
|
savannah.gnu.org:*)
|
||||||
|
if test -z "$files"; then
|
||||||
|
echo "$0: warning: standalone directives not applicable for $dest" >&2
|
||||||
|
fi
|
||||||
|
$dbg ncftpput savannah.gnu.org /incoming/savannah/$destdir $files
|
||||||
|
;;
|
||||||
|
savannah.nongnu.org:*)
|
||||||
|
if test -z "$files"; then
|
||||||
|
echo "$0: warning: standalone directives not applicable for $dest" >&2
|
||||||
|
fi
|
||||||
|
$dbg ncftpput savannah.nongnu.org /incoming/savannah/$destdir $files
|
||||||
|
;;
|
||||||
|
download.gnu.org.ua:alpha/*|download.gnu.org.ua:ftp/*)
|
||||||
|
destdir_p1=`echo "$destdir" | sed 's,^[^/]*/,,'`
|
||||||
|
destdir_topdir=`echo "$destdir" | sed 's,/.*,,'`
|
||||||
|
mkdirective "$destdir_p1" "$base" "$file" "$stmt"
|
||||||
|
echo "$passphrase" | $dbg $GPG --passphrase-fd 0 --clearsign $base.directive
|
||||||
|
for f in $files $base.directive.asc
|
||||||
|
do
|
||||||
|
echo put $f
|
||||||
|
done | $dbg sftp -b - puszcza.gnu.org.ua:/incoming/$destdir_topdir
|
||||||
|
;;
|
||||||
|
/*)
|
||||||
|
dest_host=`echo "$dest" | sed 's,:.*,,'`
|
||||||
|
mkdirective "$destdir" "$base" "$file" "$stmt"
|
||||||
|
echo "$passphrase" | $dbg $GPG --passphrase-fd 0 --clearsign $base.directive
|
||||||
|
$dbg cp $files $base.directive.asc $dest_host
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
if test -z "$files"; then
|
||||||
|
echo "$0: warning: standalone directives not applicable for $dest" >&2
|
||||||
|
fi
|
||||||
|
$dbg scp $files $dest
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
rm -f $base.directive $base.directive.asc
|
||||||
|
}
|
||||||
|
|
||||||
|
#####
|
||||||
|
# Process any standalone directives
|
||||||
|
stmt=
|
||||||
|
if test -n "$symlink_files"; then
|
||||||
|
stmt="$stmt
|
||||||
|
`mksymlink $symlink_files`"
|
||||||
|
fi
|
||||||
|
|
||||||
|
for file in $delete_files
|
||||||
|
do
|
||||||
|
stmt="$stmt
|
||||||
|
archive: $file"
|
||||||
|
done
|
||||||
|
|
||||||
|
for file in $delete_symlinks
|
||||||
|
do
|
||||||
|
stmt="$stmt
|
||||||
|
rmsymlink: $file"
|
||||||
|
done
|
||||||
|
|
||||||
|
if test -n "$stmt"; then
|
||||||
|
for dest in $to
|
||||||
|
do
|
||||||
|
destdir=`echo $dest | sed 's/[^:]*://'`
|
||||||
|
upload "$dest" "$destdir" "`hostname`-$$" "" "$stmt"
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Process actual uploads
|
||||||
|
for dest in $to
|
||||||
|
do
|
||||||
|
for file
|
||||||
|
do
|
||||||
|
echo "Uploading $file to $dest..."
|
||||||
|
stmt=
|
||||||
|
files="$file $file.sig"
|
||||||
|
destdir=`echo $dest | sed 's/[^:]*://'`
|
||||||
|
if test -n "$symlink_expr"; then
|
||||||
|
linkname=`echo $file | sed "$symlink_expr"`
|
||||||
|
stmt="$stmt
|
||||||
|
symlink: $file $linkname
|
||||||
|
symlink: $file.sig $linkname.sig"
|
||||||
|
fi
|
||||||
|
upload "$dest" "$destdir" "$file" "$file" "$stmt" "$files"
|
||||||
|
done
|
||||||
|
done
|
||||||
|
|
||||||
|
exit 0
|
||||||
|
|
||||||
|
# Local variables:
|
||||||
|
# eval: (add-hook 'write-file-hooks 'time-stamp)
|
||||||
|
# time-stamp-start: "scriptversion="
|
||||||
|
# time-stamp-format: "%:y-%02m-%02d.%02H"
|
||||||
|
# time-stamp-time-zone: "UTC"
|
||||||
|
# time-stamp-end: "; # UTC"
|
||||||
|
# End:
|
209
build-aux/useless-if-before-free
Executable file
209
build-aux/useless-if-before-free
Executable file
|
@ -0,0 +1,209 @@
|
||||||
|
eval '(exit $?0)' && eval 'exec perl -wST "$0" ${1+"$@"}'
|
||||||
|
& eval 'exec perl -wST "$0" $argv:q'
|
||||||
|
if 0;
|
||||||
|
# Detect instances of "if (p) free (p);".
|
||||||
|
# Likewise for "if (p != NULL) free (p);". And with braces.
|
||||||
|
# Also detect "if (NULL != p) free (p);".
|
||||||
|
# And with 0 in place of NULL.
|
||||||
|
|
||||||
|
my $VERSION = '2009-04-16 15:57'; # UTC
|
||||||
|
# The definition above must lie within the first 8 lines in order
|
||||||
|
# for the Emacs time-stamp write hook (at end) to update it.
|
||||||
|
# If you change this file with Emacs, please let the write hook
|
||||||
|
# do its job. Otherwise, update this string manually.
|
||||||
|
|
||||||
|
# Copyright (C) 2008, 2009 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
# Written by Jim Meyering
|
||||||
|
|
||||||
|
use strict;
|
||||||
|
use warnings;
|
||||||
|
use Getopt::Long;
|
||||||
|
|
||||||
|
(my $ME = $0) =~ s|.*/||;
|
||||||
|
|
||||||
|
# use File::Coda; # http://meyering.net/code/Coda/
|
||||||
|
END {
|
||||||
|
defined fileno STDOUT or return;
|
||||||
|
close STDOUT and return;
|
||||||
|
warn "$ME: failed to close standard output: $!\n";
|
||||||
|
$? ||= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
sub usage ($)
|
||||||
|
{
|
||||||
|
my ($exit_code) = @_;
|
||||||
|
my $STREAM = ($exit_code == 0 ? *STDOUT : *STDERR);
|
||||||
|
if ($exit_code != 0)
|
||||||
|
{
|
||||||
|
print $STREAM "Try `$ME --help' for more information.\n";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
print $STREAM <<EOF;
|
||||||
|
Usage: $ME [OPTIONS] FILE...
|
||||||
|
|
||||||
|
Detect any instance in FILE of a useless "if" test before a free call, e.g.,
|
||||||
|
"if (p) free (p);". Any such test may be safely removed without affecting
|
||||||
|
the semantics of the C code in FILE. Use --name=FOO --name=BAR to also
|
||||||
|
detect free-like functions named FOO and BAR.
|
||||||
|
|
||||||
|
OPTIONS:
|
||||||
|
|
||||||
|
--list print only the name of each matching FILE (\0-terminated)
|
||||||
|
--name=N add name N to the list of \`free\'-like functions to detect;
|
||||||
|
may be repeated
|
||||||
|
|
||||||
|
--help display this help and exit
|
||||||
|
--version output version information and exit
|
||||||
|
|
||||||
|
Exit status:
|
||||||
|
|
||||||
|
0 one or more matches
|
||||||
|
1 no match
|
||||||
|
2 an error
|
||||||
|
|
||||||
|
EXAMPLE:
|
||||||
|
|
||||||
|
For example, this command prints all removable "if" tests before "free"
|
||||||
|
and "kfree" calls in the linux kernel sources:
|
||||||
|
|
||||||
|
git ls-files -z |xargs -0 $ME --name=kfree
|
||||||
|
|
||||||
|
EOF
|
||||||
|
}
|
||||||
|
exit $exit_code;
|
||||||
|
}
|
||||||
|
|
||||||
|
sub is_NULL ($)
|
||||||
|
{
|
||||||
|
my ($expr) = @_;
|
||||||
|
return ($expr eq 'NULL' || $expr eq '0');
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
sub EXIT_MATCH {0}
|
||||||
|
sub EXIT_NO_MATCH {1}
|
||||||
|
sub EXIT_ERROR {2}
|
||||||
|
my $err = EXIT_NO_MATCH;
|
||||||
|
|
||||||
|
my $list;
|
||||||
|
my @name = qw(free);
|
||||||
|
GetOptions
|
||||||
|
(
|
||||||
|
help => sub { usage 0 },
|
||||||
|
version => sub { print "$ME version $VERSION\n"; exit },
|
||||||
|
list => \$list,
|
||||||
|
'name=s@' => \@name,
|
||||||
|
) or usage 1;
|
||||||
|
|
||||||
|
# Make sure we have the right number of non-option arguments.
|
||||||
|
# Always tell the user why we fail.
|
||||||
|
@ARGV < 1
|
||||||
|
and (warn "$ME: missing FILE argument\n"), usage EXIT_ERROR;
|
||||||
|
|
||||||
|
my $or = join '|', @name;
|
||||||
|
my $regexp = qr/(?:$or)/;
|
||||||
|
|
||||||
|
# Set the input record separator.
|
||||||
|
# Note: this makes it impractical to print line numbers.
|
||||||
|
$/ = '"';
|
||||||
|
|
||||||
|
my $found_match = 0;
|
||||||
|
FILE:
|
||||||
|
foreach my $file (@ARGV)
|
||||||
|
{
|
||||||
|
open FH, '<', $file
|
||||||
|
or (warn "$ME: can't open `$file' for reading: $!\n"),
|
||||||
|
$err = EXIT_ERROR, next;
|
||||||
|
while (defined (my $line = <FH>))
|
||||||
|
{
|
||||||
|
while ($line =~
|
||||||
|
/\b(if\s*\(\s*([^)]+?)(?:\s*!=\s*([^)]+?))?\s*\)
|
||||||
|
# 1 2 3
|
||||||
|
(?: \s*$regexp\s*\((?:\s*\([^)]+\))?\s*([^)]+)\)|
|
||||||
|
\s*\{\s*$regexp\s*\((?:\s*\([^)]+\))?\s*([^)]+)\)\s*;\s*\}))/sxg)
|
||||||
|
{
|
||||||
|
my $all = $1;
|
||||||
|
my ($lhs, $rhs) = ($2, $3);
|
||||||
|
my ($free_opnd, $braced_free_opnd) = ($4, $5);
|
||||||
|
my $non_NULL;
|
||||||
|
if (!defined $rhs) { $non_NULL = $lhs }
|
||||||
|
elsif (is_NULL $rhs) { $non_NULL = $lhs }
|
||||||
|
elsif (is_NULL $lhs) { $non_NULL = $rhs }
|
||||||
|
else { next }
|
||||||
|
|
||||||
|
# Compare the non-NULL part of the "if" expression and the
|
||||||
|
# free'd expression, without regard to white space.
|
||||||
|
$non_NULL =~ tr/ \t//d;
|
||||||
|
my $e2 = defined $free_opnd ? $free_opnd : $braced_free_opnd;
|
||||||
|
$e2 =~ tr/ \t//d;
|
||||||
|
if ($non_NULL eq $e2)
|
||||||
|
{
|
||||||
|
$found_match = 1;
|
||||||
|
$list
|
||||||
|
and (print "$file\0"), next FILE;
|
||||||
|
print "$file: $all\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
{
|
||||||
|
close FH;
|
||||||
|
}
|
||||||
|
|
||||||
|
$found_match && $err == EXIT_NO_MATCH
|
||||||
|
and $err = EXIT_MATCH;
|
||||||
|
|
||||||
|
exit $err;
|
||||||
|
}
|
||||||
|
|
||||||
|
my $foo = <<'EOF';
|
||||||
|
# The above is to *find* them.
|
||||||
|
# This adjusts them, removing the unnecessary "if (p)" part.
|
||||||
|
|
||||||
|
# FIXME: do something like this as an option (doesn't do braces):
|
||||||
|
free=xfree
|
||||||
|
git grep -l -z "$free *(" \
|
||||||
|
| xargs -0 useless-if-before-free -l --name="$free" \
|
||||||
|
| xargs -0 perl -0x3b -pi -e \
|
||||||
|
's/\bif\s*\(\s*(\S+?)(?:\s*!=\s*(?:0|NULL))?\s*\)\s+('"$free"'\s*\((?:\s*\([^)]+\))?\s*\1\s*\))/$2/s'
|
||||||
|
|
||||||
|
# Use the following to remove redundant uses of kfree inside braces.
|
||||||
|
# Note that -0777 puts perl in slurp-whole-file mode;
|
||||||
|
# but we have plenty of memory, these days...
|
||||||
|
free=kfree
|
||||||
|
git grep -l -z "$free *(" \
|
||||||
|
| xargs -0 useless-if-before-free -l --name="$free" \
|
||||||
|
| xargs -0 perl -0777 -pi -e \
|
||||||
|
's/\bif\s*\(\s*(\S+?)(?:\s*!=\s*(?:0|NULL))?\s*\)\s*\{\s*('"$free"'\s*\((?:\s*\([^)]+\))?\s*\1\s*\);)\s*\}[^\n]*$/$2/gms'
|
||||||
|
|
||||||
|
Be careful that the result of the above transformation is valid.
|
||||||
|
If the matched string is followed by "else", then obviously, it won't be.
|
||||||
|
|
||||||
|
When modifying files, refuse to process anything other than a regular file.
|
||||||
|
EOF
|
||||||
|
|
||||||
|
## Local Variables:
|
||||||
|
## mode: perl
|
||||||
|
## indent-tabs-mode: nil
|
||||||
|
## eval: (add-hook 'write-file-hooks 'time-stamp)
|
||||||
|
## time-stamp-start: "my $VERSION = '"
|
||||||
|
## time-stamp-format: "%:y-%02m-%02d %02H:%02M"
|
||||||
|
## time-stamp-time-zone: "UTC"
|
||||||
|
## time-stamp-end: "'; # UTC"
|
||||||
|
## End:
|
116
build-aux/vc-list-files
Executable file
116
build-aux/vc-list-files
Executable file
|
@ -0,0 +1,116 @@
|
||||||
|
#!/bin/sh
|
||||||
|
# List version-controlled file names.
|
||||||
|
|
||||||
|
# Print a version string.
|
||||||
|
scriptversion=2009-07-21.16; # UTC
|
||||||
|
|
||||||
|
# Copyright (C) 2006-2009 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
|
||||||
|
# List the specified version-controlled files.
|
||||||
|
# With no argument, list them all. With a single DIRECTORY argument,
|
||||||
|
# list the version-controlled files in that directory.
|
||||||
|
|
||||||
|
# If there's an argument, it must be a single, "."-relative directory name.
|
||||||
|
# cvsu is part of the cvsutils package: http://www.red-bean.com/cvsutils/
|
||||||
|
|
||||||
|
postprocess=
|
||||||
|
case $1 in
|
||||||
|
--help) cat <<EOF
|
||||||
|
Usage: $0 [-C SRCDIR] [DIR]
|
||||||
|
|
||||||
|
Output a list of version-controlled files in DIR (default .), relative to
|
||||||
|
SRCDIR (default .). SRCDIR must be the top directory of a checkout.
|
||||||
|
|
||||||
|
Options:
|
||||||
|
--help print this help, then exit
|
||||||
|
--version print version number, then exit
|
||||||
|
-C SRCDIR change directory to SRCDIR before generating list
|
||||||
|
|
||||||
|
Report bugs and patches to <bug-gnulib@gnu.org>.
|
||||||
|
EOF
|
||||||
|
exit ;;
|
||||||
|
|
||||||
|
--version)
|
||||||
|
year=`echo "$scriptversion" | sed 's/[^0-9].*//'`
|
||||||
|
cat <<EOF
|
||||||
|
vc-list-files $scriptversion
|
||||||
|
Copyright (C) $year Free Software Foundation, Inc,
|
||||||
|
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
|
||||||
|
This is free software: you are free to change and redistribute it.
|
||||||
|
There is NO WARRANTY, to the extent permitted by law.
|
||||||
|
EOF
|
||||||
|
exit ;;
|
||||||
|
|
||||||
|
-C)
|
||||||
|
test "$2" = . || postprocess="| sed 's|^|$2/|'"
|
||||||
|
cd "$2" || exit 1
|
||||||
|
shift; shift ;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
dir=
|
||||||
|
case $# in
|
||||||
|
0) ;;
|
||||||
|
1) dir=$1 ;;
|
||||||
|
*) echo "$0: too many arguments" 1>&2
|
||||||
|
echo "Usage: $0 [-C srcdir] [DIR]" 1>&2; exit 1;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
test "x$dir" = x && dir=.
|
||||||
|
|
||||||
|
if test -d .git; then
|
||||||
|
test "x$dir" = x. \
|
||||||
|
&& dir= sed_esc= \
|
||||||
|
|| { dir="$dir/"; sed_esc=`echo "$dir"|env sed 's,\([\\/]\),\\\\\1,g'`; }
|
||||||
|
# Ignore git symlinks - either they point into the tree, in which case
|
||||||
|
# we don't need to visit the target twice, or they point somewhere
|
||||||
|
# else (often into a submodule), in which case the content does not
|
||||||
|
# belong to this package.
|
||||||
|
eval exec git ls-tree -r 'HEAD:"$dir"' \
|
||||||
|
\| sed -n '"s/^100[^ ]*./$sed_esc/p"' $postprocess
|
||||||
|
elif test -d .hg; then
|
||||||
|
eval exec hg locate '"$dir/*"' $postprocess
|
||||||
|
elif test -d .bzr; then
|
||||||
|
test "$postprocess" = '' && postprocess="| sed 's|^\./||'"
|
||||||
|
eval exec bzr ls --versioned '"$dir"' $postprocess
|
||||||
|
elif test -d CVS; then
|
||||||
|
test "$postprocess" = '' && postprocess="| sed 's|^\./||'"
|
||||||
|
if test -x build-aux/cvsu; then
|
||||||
|
eval build-aux/cvsu --find --types=AFGM '"$dir"' $postprocess
|
||||||
|
elif (cvsu --help) >/dev/null 2>&1; then
|
||||||
|
eval cvsu --find --types=AFGM '"$dir"' $postprocess
|
||||||
|
else
|
||||||
|
eval awk -F/ \''{ \
|
||||||
|
if (!$1 && $3 !~ /^-/) { \
|
||||||
|
f=FILENAME; \
|
||||||
|
if (f ~ /CVS\/Entries$/) \
|
||||||
|
f = substr(f, 1, length(f)-11); \
|
||||||
|
print f $2; \
|
||||||
|
}}'\'' \
|
||||||
|
`find "$dir" -name Entries -print` /dev/null' $postprocess
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo "$0: Failed to determine type of version control used in `pwd`" 1>&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Local variables:
|
||||||
|
# eval: (add-hook 'write-file-hooks 'time-stamp)
|
||||||
|
# time-stamp-start: "scriptversion="
|
||||||
|
# time-stamp-format: "%:y-%02m-%02d.%02H"
|
||||||
|
# time-stamp-time-zone: "UTC"
|
||||||
|
# time-stamp-end: "; # UTC"
|
||||||
|
# End:
|
1
cfg.mk
Normal file
1
cfg.mk
Normal file
|
@ -0,0 +1 @@
|
||||||
|
old_NEWS_hash = d41d8cd98f00b204e9800998ecf8427e
|
164
configure.ac
164
configure.ac
|
@ -32,8 +32,7 @@ dnl "echo -n" since -n is not portable (see autoconf manual "Limitations of
|
||||||
dnl Builtins"), in particular on solaris it results in a literal "-n" in
|
dnl Builtins"), in particular on solaris it results in a literal "-n" in
|
||||||
dnl the output.
|
dnl the output.
|
||||||
dnl
|
dnl
|
||||||
AC_INIT(patsubst(m4_esyscmd(. ./GUILE-VERSION && echo ${PACKAGE}),[
|
AC_INIT([GNU Guile],
|
||||||
]),
|
|
||||||
patsubst(m4_esyscmd(. ./GUILE-VERSION && echo ${GUILE_VERSION}),[
|
patsubst(m4_esyscmd(. ./GUILE-VERSION && echo ${GUILE_VERSION}),[
|
||||||
]),
|
]),
|
||||||
[bug-guile@gnu.org])
|
[bug-guile@gnu.org])
|
||||||
|
@ -64,6 +63,7 @@ AC_PROG_INSTALL
|
||||||
AC_PROG_CC
|
AC_PROG_CC
|
||||||
gl_EARLY
|
gl_EARLY
|
||||||
AC_PROG_CPP
|
AC_PROG_CPP
|
||||||
|
AC_PROG_SED
|
||||||
AC_PROG_AWK
|
AC_PROG_AWK
|
||||||
|
|
||||||
dnl Gnulib.
|
dnl Gnulib.
|
||||||
|
@ -86,13 +86,16 @@ AM_CONDITIONAL(HAVE_MAKEINFO, test "$have_makeinfo" = yes)
|
||||||
|
|
||||||
AM_PATH_LISPDIR
|
AM_PATH_LISPDIR
|
||||||
|
|
||||||
|
AC_DEFINE_UNQUOTED([HOST_TYPE], ["$host"],
|
||||||
|
[Define to the host's GNU triplet.])
|
||||||
|
|
||||||
#--------------------------------------------------------------------
|
#--------------------------------------------------------------------
|
||||||
#
|
#
|
||||||
# User options (after above tests that may set default CFLAGS etc.)
|
# User options (after above tests that may set default CFLAGS etc.)
|
||||||
#
|
#
|
||||||
#--------------------------------------------------------------------
|
#--------------------------------------------------------------------
|
||||||
|
|
||||||
GUILE_ERROR_ON_WARNING="yes"
|
GUILE_ERROR_ON_WARNING="no"
|
||||||
|
|
||||||
AC_ARG_ENABLE(error-on-warning,
|
AC_ARG_ENABLE(error-on-warning,
|
||||||
[ --enable-error-on-warning treat compile warnings as errors],
|
[ --enable-error-on-warning treat compile warnings as errors],
|
||||||
|
@ -113,7 +116,7 @@ AC_ARG_ENABLE(debug-freelist,
|
||||||
AC_ARG_ENABLE(debug-malloc,
|
AC_ARG_ENABLE(debug-malloc,
|
||||||
[ --enable-debug-malloc include malloc debugging code],
|
[ --enable-debug-malloc include malloc debugging code],
|
||||||
if test "$enable_debug_malloc" = y || test "$enable_debug_malloc" = yes; then
|
if test "$enable_debug_malloc" = y || test "$enable_debug_malloc" = yes; then
|
||||||
AC_DEFINE(GUILE_DEBUG_MALLOC, 1,
|
AC_DEFINE([GUILE_DEBUG_MALLOC], 1,
|
||||||
[Define this if you want to debug scm_must_malloc/realloc/free calls.])
|
[Define this if you want to debug scm_must_malloc/realloc/free calls.])
|
||||||
fi)
|
fi)
|
||||||
|
|
||||||
|
@ -162,7 +165,7 @@ else
|
||||||
fi
|
fi
|
||||||
SCM_I_GSC_ENABLE_DEPRECATED=1
|
SCM_I_GSC_ENABLE_DEPRECATED=1
|
||||||
fi
|
fi
|
||||||
AC_DEFINE_UNQUOTED(SCM_WARN_DEPRECATED_DEFAULT, "$warn_default",
|
AC_DEFINE_UNQUOTED([SCM_WARN_DEPRECATED_DEFAULT], "$warn_default",
|
||||||
[Define this to control the default warning level for deprecated features.])
|
[Define this to control the default warning level for deprecated features.])
|
||||||
|
|
||||||
AC_ARG_ENABLE(elisp,
|
AC_ARG_ENABLE(elisp,
|
||||||
|
@ -209,7 +212,7 @@ AC_ARG_WITH([64-calls],
|
||||||
AC_MSG_RESULT($use_64_calls)
|
AC_MSG_RESULT($use_64_calls)
|
||||||
case "$use_64_calls" in
|
case "$use_64_calls" in
|
||||||
y* )
|
y* )
|
||||||
AC_DEFINE(GUILE_USE_64_CALLS, 1,
|
AC_DEFINE([GUILE_USE_64_CALLS], 1,
|
||||||
[Define to 1 in order to try to use "64" versions of system and library calls.])
|
[Define to 1 in order to try to use "64" versions of system and library calls.])
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
@ -244,14 +247,14 @@ fi
|
||||||
if test "$enable_posix" = yes; then
|
if test "$enable_posix" = yes; then
|
||||||
AC_LIBOBJ([filesys])
|
AC_LIBOBJ([filesys])
|
||||||
AC_LIBOBJ([posix])
|
AC_LIBOBJ([posix])
|
||||||
AC_DEFINE(HAVE_POSIX, 1,
|
AC_DEFINE([HAVE_POSIX], 1,
|
||||||
[Define this if you want support for POSIX system calls in Guile.])
|
[Define this if you want support for POSIX system calls in Guile.])
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if test "$enable_networking" = yes; then
|
if test "$enable_networking" = yes; then
|
||||||
AC_LIBOBJ([net_db])
|
AC_LIBOBJ([net_db])
|
||||||
AC_LIBOBJ([socket])
|
AC_LIBOBJ([socket])
|
||||||
AC_DEFINE(HAVE_NETWORKING, 1,
|
AC_DEFINE([HAVE_NETWORKING], 1,
|
||||||
[Define this if you want support for networking in Guile.])
|
[Define this if you want support for networking in Guile.])
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
@ -352,6 +355,8 @@ if test "$ac_cv_header_stdint_h" = yes; then
|
||||||
AC_CHECK_TYPE([uint64_t],[scm_stdint_has_uint64=1],,[#include <stdint.h>])
|
AC_CHECK_TYPE([uint64_t],[scm_stdint_has_uint64=1],,[#include <stdint.h>])
|
||||||
AC_CHECK_TYPE([intmax_t],[scm_stdint_has_intmax=1],,[#include <stdint.h>])
|
AC_CHECK_TYPE([intmax_t],[scm_stdint_has_intmax=1],,[#include <stdint.h>])
|
||||||
AC_CHECK_TYPE([uintmax_t],[scm_stdint_has_uintmax=1],,[#include <stdint.h>])
|
AC_CHECK_TYPE([uintmax_t],[scm_stdint_has_uintmax=1],,[#include <stdint.h>])
|
||||||
|
AC_CHECK_TYPE([intptr_t],[scm_stdint_has_intptr=1],,[#include <stdint.h>])
|
||||||
|
AC_CHECK_TYPE([uintptr_t],[scm_stdint_has_uintptr=1],,[#include <stdint.h>])
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# so we don't get confused by the cache (wish there was a better way
|
# so we don't get confused by the cache (wish there was a better way
|
||||||
|
@ -380,6 +385,8 @@ if test "$ac_cv_header_inttypes_h" = yes; then
|
||||||
AC_CHECK_TYPE([uint64_t],[scm_inttypes_has_uint64=1],,[#include <inttypes.h>])
|
AC_CHECK_TYPE([uint64_t],[scm_inttypes_has_uint64=1],,[#include <inttypes.h>])
|
||||||
AC_CHECK_TYPE([intmax_t],[scm_inttypes_has_intmax=1],,[#include <inttypes.h>])
|
AC_CHECK_TYPE([intmax_t],[scm_inttypes_has_intmax=1],,[#include <inttypes.h>])
|
||||||
AC_CHECK_TYPE([uintmax_t],[scm_inttypes_has_uintmax=1],,[#include <inttypes.h>])
|
AC_CHECK_TYPE([uintmax_t],[scm_inttypes_has_uintmax=1],,[#include <inttypes.h>])
|
||||||
|
AC_CHECK_TYPE([intptr_t],[scm_inttypes_has_intptr=1],,[#include <inttypes.h>])
|
||||||
|
AC_CHECK_TYPE([uintptr_t],[scm_inttypes_has_uintptr=1],,[#include <inttypes.h>])
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Try hard to find definitions for some required scm_t_*int* types.
|
# Try hard to find definitions for some required scm_t_*int* types.
|
||||||
|
@ -572,6 +579,46 @@ else
|
||||||
fi
|
fi
|
||||||
AC_SUBST([SCM_I_GSC_T_UINTMAX])
|
AC_SUBST([SCM_I_GSC_T_UINTMAX])
|
||||||
|
|
||||||
|
### Required type scm_t_intptr
|
||||||
|
###
|
||||||
|
SCM_I_GSC_T_INTPTR=0
|
||||||
|
if test "$scm_stdint_has_intptr"; then
|
||||||
|
SCM_I_GSC_T_INTPTR='"intptr_t"'
|
||||||
|
SCM_I_GSC_NEEDS_STDINT_H=1
|
||||||
|
elif test "$scm_inttypes_has_intptr"; then
|
||||||
|
SCM_I_GSC_T_INTPTR='"intptr_t"'
|
||||||
|
SCM_I_GSC_NEEDS_INTTYPES_H=1
|
||||||
|
elif test "$ac_cv_sizeof_int" = "$ac_cv_sizeof_void_p"; then
|
||||||
|
SCM_I_GSC_T_INTPTR='"int"'
|
||||||
|
elif test "$ac_cv_sizeof_long" = "$ac_cv_sizeof_void_p"; then
|
||||||
|
SCM_I_GSC_T_INTPTR='"long"'
|
||||||
|
elif test "$ac_cv_sizeof_long_long" = "$ac_cv_sizeof_void_p"; then
|
||||||
|
SCM_I_GSC_T_INTPTR='"long long"'
|
||||||
|
else
|
||||||
|
AC_MSG_ERROR([Can't find appropriate type for `scm_t_intptr'.])
|
||||||
|
fi
|
||||||
|
AC_SUBST([SCM_I_GSC_T_INTPTR])
|
||||||
|
|
||||||
|
### Required type scm_t_uintptr
|
||||||
|
###
|
||||||
|
SCM_I_GSC_T_UINTPTR=0
|
||||||
|
if test "$scm_stdint_has_uintptr"; then
|
||||||
|
SCM_I_GSC_T_UINTPTR='"uintptr_t"'
|
||||||
|
SCM_I_GSC_NEEDS_STDINT_H=1
|
||||||
|
elif test "$scm_inttypes_has_uintptr"; then
|
||||||
|
SCM_I_GSC_T_UINTPTR='"uintptr_t"'
|
||||||
|
SCM_I_GSC_NEEDS_INTTYPES_H=1
|
||||||
|
elif test "$ac_cv_sizeof_int" = "$ac_cv_sizeof_void_p"; then
|
||||||
|
SCM_I_GSC_T_UINTPTR='"unsigned int"'
|
||||||
|
elif test "$ac_cv_sizeof_long" = "$ac_cv_sizeof_void_p"; then
|
||||||
|
SCM_I_GSC_T_UINTPTR='"unsigned long"'
|
||||||
|
elif test "$ac_cv_sizeof_long_long" = "$ac_cv_sizeof_void_p"; then
|
||||||
|
SCM_I_GSC_T_UINTPTR='"unsigned long long"'
|
||||||
|
else
|
||||||
|
AC_MSG_ERROR([Can't find appropriate type for `scm_t_uintptr'.])
|
||||||
|
fi
|
||||||
|
AC_SUBST([SCM_I_GSC_T_UINTPTR])
|
||||||
|
|
||||||
|
|
||||||
AC_SUBST([SCM_I_GSC_NEEDS_STDINT_H])
|
AC_SUBST([SCM_I_GSC_NEEDS_STDINT_H])
|
||||||
AC_SUBST([SCM_I_GSC_NEEDS_INTTYPES_H])
|
AC_SUBST([SCM_I_GSC_NEEDS_INTTYPES_H])
|
||||||
|
@ -634,7 +681,7 @@ AC_CHECK_TYPES(complex double,,,
|
||||||
# On MacOS X <sys/socklen.h> contains socklen_t, so must include that
|
# On MacOS X <sys/socklen.h> contains socklen_t, so must include that
|
||||||
# when testing.
|
# when testing.
|
||||||
AC_CHECK_TYPE(socklen_t, ,
|
AC_CHECK_TYPE(socklen_t, ,
|
||||||
[AC_DEFINE_UNQUOTED(socklen_t, int,
|
[AC_DEFINE_UNQUOTED([socklen_t], int,
|
||||||
[Define to `int' if <sys/socket.h> does not define.])],
|
[Define to `int' if <sys/socket.h> does not define.])],
|
||||||
[#if HAVE_SYS_TYPES_H
|
[#if HAVE_SYS_TYPES_H
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
@ -680,7 +727,7 @@ case $host in
|
||||||
fi
|
fi
|
||||||
if test "$enable_shared" = yes ; then
|
if test "$enable_shared" = yes ; then
|
||||||
EXTRA_DEFS="-DSCM_IMPORT"
|
EXTRA_DEFS="-DSCM_IMPORT"
|
||||||
AC_DEFINE(USE_DLL_IMPORT, 1,
|
AC_DEFINE([USE_DLL_IMPORT], 1,
|
||||||
[Define if you need additional CPP macros on Win32 platforms.])
|
[Define if you need additional CPP macros on Win32 platforms.])
|
||||||
fi
|
fi
|
||||||
;;
|
;;
|
||||||
|
@ -727,13 +774,12 @@ AC_CHECK_FUNCS([DINFINITY DQNAN cexp chsize clog clog10 ctermid fesetround ftime
|
||||||
# check this specifically, we need it for the timespec test below.
|
# check this specifically, we need it for the timespec test below.
|
||||||
# sethostname - the function itself check because it's not in mingw,
|
# sethostname - the function itself check because it's not in mingw,
|
||||||
# the DECL is checked because Solaris 10 doens't have in any header
|
# the DECL is checked because Solaris 10 doens't have in any header
|
||||||
# xlocale.h - needed on Darwin for the `locale_t' API
|
|
||||||
# hstrerror - on Tru64 5.1b the symbol is available in libc but the
|
# hstrerror - on Tru64 5.1b the symbol is available in libc but the
|
||||||
# declaration isn't anywhere.
|
# declaration isn't anywhere.
|
||||||
# cuserid - on Tru64 5.1b the declaration is documented to be available
|
# cuserid - on Tru64 5.1b the declaration is documented to be available
|
||||||
# only with `_XOPEN_SOURCE' or some such.
|
# only with `_XOPEN_SOURCE' or some such.
|
||||||
#
|
#
|
||||||
AC_CHECK_HEADERS(crypt.h netdb.h pthread.h sys/param.h sys/resource.h sys/file.h xlocale.h)
|
AC_CHECK_HEADERS([crypt.h netdb.h pthread.h sys/param.h sys/resource.h sys/file.h])
|
||||||
AC_CHECK_FUNCS(chroot flock getlogin cuserid getpriority setpriority getpass sethostname gethostname)
|
AC_CHECK_FUNCS(chroot flock getlogin cuserid getpriority setpriority getpass sethostname gethostname)
|
||||||
AC_CHECK_DECLS([sethostname, hstrerror, cuserid])
|
AC_CHECK_DECLS([sethostname, hstrerror, cuserid])
|
||||||
|
|
||||||
|
@ -751,7 +797,7 @@ AC_CHECK_DECLS([sethostname, hstrerror, cuserid])
|
||||||
# libraries already in that list.
|
# libraries already in that list.
|
||||||
#
|
#
|
||||||
AC_SEARCH_LIBS(crypt, crypt,
|
AC_SEARCH_LIBS(crypt, crypt,
|
||||||
[AC_DEFINE(HAVE_CRYPT,1,
|
[AC_DEFINE([HAVE_CRYPT],1,
|
||||||
[Define to 1 if you have the `crypt' function.])])
|
[Define to 1 if you have the `crypt' function.])])
|
||||||
|
|
||||||
# When compiling with GCC on some OSs (Solaris, AIX), _Complex_I doesn't
|
# When compiling with GCC on some OSs (Solaris, AIX), _Complex_I doesn't
|
||||||
|
@ -769,7 +815,7 @@ complex double z;
|
||||||
]], [[
|
]], [[
|
||||||
z = _Complex_I;
|
z = _Complex_I;
|
||||||
]])],
|
]])],
|
||||||
[AC_DEFINE(GUILE_I,_Complex_I,[The imaginary unit (positive square root of -1).])
|
[AC_DEFINE([GUILE_I],_Complex_I,[The imaginary unit (positive square root of -1).])
|
||||||
AC_MSG_RESULT([_Complex_I])],
|
AC_MSG_RESULT([_Complex_I])],
|
||||||
[AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
|
[AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
|
||||||
#if HAVE_COMPLEX_H
|
#if HAVE_COMPLEX_H
|
||||||
|
@ -779,7 +825,7 @@ complex double z;
|
||||||
]],[[
|
]],[[
|
||||||
z = 1.0fi;
|
z = 1.0fi;
|
||||||
]])],
|
]])],
|
||||||
[AC_DEFINE(GUILE_I,1.0fi)
|
[AC_DEFINE([GUILE_I],1.0fi)
|
||||||
AC_MSG_RESULT([1.0fi])],
|
AC_MSG_RESULT([1.0fi])],
|
||||||
[ac_cv_type_complex_double=no
|
[ac_cv_type_complex_double=no
|
||||||
AC_MSG_RESULT([not available])])])
|
AC_MSG_RESULT([not available])])])
|
||||||
|
@ -812,7 +858,7 @@ main (void)
|
||||||
[guile_cv_use_csqrt="yes, hopefully (cross-compiling)"])])
|
[guile_cv_use_csqrt="yes, hopefully (cross-compiling)"])])
|
||||||
case $guile_cv_use_csqrt in
|
case $guile_cv_use_csqrt in
|
||||||
yes*)
|
yes*)
|
||||||
AC_DEFINE(HAVE_USABLE_CSQRT, 1, [Define to 1 if csqrt is bug-free])
|
AC_DEFINE([HAVE_USABLE_CSQRT], 1, [Define to 1 if csqrt is bug-free])
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
fi
|
fi
|
||||||
|
@ -826,6 +872,11 @@ AC_LIB_HAVE_LINKFLAGS(gmp,
|
||||||
AC_MSG_ERROR([GNU MP 4.1 or greater not found, see README]))
|
AC_MSG_ERROR([GNU MP 4.1 or greater not found, see README]))
|
||||||
|
|
||||||
dnl GNU libunistring is checked for by Gnulib's `libunistring' module.
|
dnl GNU libunistring is checked for by Gnulib's `libunistring' module.
|
||||||
|
if test "x$LTLIBUNISTRING" != "x"; then
|
||||||
|
LIBS="$LTLIBUNISTRING $LIBS"
|
||||||
|
else
|
||||||
|
AC_MSG_ERROR([GNU libunistring is required, please install it.])
|
||||||
|
fi
|
||||||
|
|
||||||
dnl i18n tests
|
dnl i18n tests
|
||||||
#AC_CHECK_HEADERS([libintl.h])
|
#AC_CHECK_HEADERS([libintl.h])
|
||||||
|
@ -870,14 +921,14 @@ AC_CACHE_CHECK([return type of usleep], guile_cv_func_usleep_return_type,
|
||||||
[guile_cv_func_usleep_return_type=int])])
|
[guile_cv_func_usleep_return_type=int])])
|
||||||
case "$guile_cv_func_usleep_return_type" in
|
case "$guile_cv_func_usleep_return_type" in
|
||||||
"void" )
|
"void" )
|
||||||
AC_DEFINE(USLEEP_RETURNS_VOID, 1,
|
AC_DEFINE([USLEEP_RETURNS_VOID], 1,
|
||||||
[Define if the system headers declare usleep to return void.])
|
[Define if the system headers declare usleep to return void.])
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
AC_CHECK_HEADER(sys/un.h, have_sys_un_h=1)
|
AC_CHECK_HEADER(sys/un.h, have_sys_un_h=1)
|
||||||
if test -n "$have_sys_un_h" ; then
|
if test -n "$have_sys_un_h" ; then
|
||||||
AC_DEFINE(HAVE_UNIX_DOMAIN_SOCKETS, 1,
|
AC_DEFINE([HAVE_UNIX_DOMAIN_SOCKETS], 1,
|
||||||
[Define if the system supports Unix-domain (file-domain) sockets.])
|
[Define if the system supports Unix-domain (file-domain) sockets.])
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
@ -890,8 +941,7 @@ AC_CHECK_FUNCS(sethostent gethostent endhostent dnl
|
||||||
setprotoent getprotoent endprotoent dnl
|
setprotoent getprotoent endprotoent dnl
|
||||||
setservent getservent endservent dnl
|
setservent getservent endservent dnl
|
||||||
getnetbyaddr getnetbyname dnl
|
getnetbyaddr getnetbyname dnl
|
||||||
inet_lnaof inet_makeaddr inet_netof hstrerror dnl
|
inet_lnaof inet_makeaddr inet_netof hstrerror)
|
||||||
inet_pton inet_ntop)
|
|
||||||
|
|
||||||
# struct sockaddr field sin_len is only present on BSD systems.
|
# struct sockaddr field sin_len is only present on BSD systems.
|
||||||
# On 4.4BSD apparently a #define SIN_LEN exists, but on other BSD systems
|
# On 4.4BSD apparently a #define SIN_LEN exists, but on other BSD systems
|
||||||
|
@ -912,7 +962,7 @@ extern char *__libc_stack_end;]],
|
||||||
AC_MSG_RESULT($guile_cv_have_libc_stack_end)
|
AC_MSG_RESULT($guile_cv_have_libc_stack_end)
|
||||||
|
|
||||||
if test $guile_cv_have_libc_stack_end = yes; then
|
if test $guile_cv_have_libc_stack_end = yes; then
|
||||||
AC_DEFINE(HAVE_LIBC_STACK_END, 1,
|
AC_DEFINE([HAVE_LIBC_STACK_END], 1,
|
||||||
[Define if you have the __libc_stack_end variable.])
|
[Define if you have the __libc_stack_end variable.])
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
@ -927,7 +977,7 @@ AC_CACHE_VAL(guile_cv_have_h_errno,
|
||||||
[guile_cv_have_h_errno=no])])
|
[guile_cv_have_h_errno=no])])
|
||||||
AC_MSG_RESULT($guile_cv_have_h_errno)
|
AC_MSG_RESULT($guile_cv_have_h_errno)
|
||||||
if test $guile_cv_have_h_errno = yes; then
|
if test $guile_cv_have_h_errno = yes; then
|
||||||
AC_DEFINE(HAVE_H_ERRNO, 1, [Define if h_errno is declared in netdb.h.])
|
AC_DEFINE([HAVE_H_ERRNO], 1, [Define if h_errno is declared in netdb.h.])
|
||||||
fi
|
fi
|
||||||
|
|
||||||
AC_MSG_CHECKING(whether uint32_t is defined)
|
AC_MSG_CHECKING(whether uint32_t is defined)
|
||||||
|
@ -944,7 +994,7 @@ AC_CACHE_VAL(guile_cv_have_uint32_t,
|
||||||
[guile_cv_have_uint32_t=no])])
|
[guile_cv_have_uint32_t=no])])
|
||||||
AC_MSG_RESULT($guile_cv_have_uint32_t)
|
AC_MSG_RESULT($guile_cv_have_uint32_t)
|
||||||
if test $guile_cv_have_uint32_t = yes; then
|
if test $guile_cv_have_uint32_t = yes; then
|
||||||
AC_DEFINE(HAVE_UINT32_T, 1,
|
AC_DEFINE([HAVE_UINT32_T], 1,
|
||||||
[Define if uint32_t typedef is defined when netdb.h is include.])
|
[Define if uint32_t typedef is defined when netdb.h is include.])
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
@ -961,7 +1011,7 @@ AC_CACHE_VAL(guile_cv_have_ipv6,
|
||||||
[guile_cv_have_ipv6=no])])
|
[guile_cv_have_ipv6=no])])
|
||||||
AC_MSG_RESULT($guile_cv_have_ipv6)
|
AC_MSG_RESULT($guile_cv_have_ipv6)
|
||||||
if test $guile_cv_have_ipv6 = yes; then
|
if test $guile_cv_have_ipv6 = yes; then
|
||||||
AC_DEFINE(HAVE_IPV6, 1, [Define if you want support for IPv6.])
|
AC_DEFINE([HAVE_IPV6], 1, [Define if you want support for IPv6.])
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# included in rfc2553 but not in older implementations, e.g., glibc 2.1.3.
|
# included in rfc2553 but not in older implementations, e.g., glibc 2.1.3.
|
||||||
|
@ -977,7 +1027,7 @@ AC_CACHE_VAL(guile_cv_have_sin6_scope_id,
|
||||||
[guile_cv_have_sin6_scope_id=no])])
|
[guile_cv_have_sin6_scope_id=no])])
|
||||||
AC_MSG_RESULT($guile_cv_have_sin6_scope_id)
|
AC_MSG_RESULT($guile_cv_have_sin6_scope_id)
|
||||||
if test $guile_cv_have_sin6_scope_id = yes; then
|
if test $guile_cv_have_sin6_scope_id = yes; then
|
||||||
AC_DEFINE(HAVE_SIN6_SCOPE_ID, 1,
|
AC_DEFINE([HAVE_SIN6_SCOPE_ID], 1,
|
||||||
[Define this if your IPv6 has sin6_scope_id in sockaddr_in6 struct.])
|
[Define this if your IPv6 has sin6_scope_id in sockaddr_in6 struct.])
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
@ -1034,7 +1084,7 @@ else
|
||||||
fi])dnl
|
fi])dnl
|
||||||
AC_MSG_RESULT($guile_cv_localtime_cache)
|
AC_MSG_RESULT($guile_cv_localtime_cache)
|
||||||
if test $guile_cv_localtime_cache = yes; then
|
if test $guile_cv_localtime_cache = yes; then
|
||||||
AC_DEFINE(LOCALTIME_CACHE, 1, [Define if localtime caches the TZ setting.])
|
AC_DEFINE([LOCALTIME_CACHE], 1, [Define if localtime caches the TZ setting.])
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if test "$enable_regex" = yes; then
|
if test "$enable_regex" = yes; then
|
||||||
|
@ -1052,7 +1102,7 @@ if test "$enable_regex" = yes; then
|
||||||
if test "$ac_cv_func_regcomp_norx" = yes ||
|
if test "$ac_cv_func_regcomp_norx" = yes ||
|
||||||
test "$ac_cv_func_regcomp_regex" = yes ||
|
test "$ac_cv_func_regcomp_regex" = yes ||
|
||||||
test "$ac_cv_func_regcomp_rx" = yes; then
|
test "$ac_cv_func_regcomp_rx" = yes; then
|
||||||
AC_DEFINE(HAVE_REGCOMP, 1,
|
AC_DEFINE([HAVE_REGCOMP], 1,
|
||||||
[This is included as part of a workaround for a autoheader bug.])
|
[This is included as part of a workaround for a autoheader bug.])
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
@ -1084,7 +1134,7 @@ AC_LINK_IFELSE(AC_LANG_SOURCE(
|
||||||
volatile double x = 0.0;
|
volatile double x = 0.0;
|
||||||
int main () { return (isinf(x) != 0); }]]),
|
int main () { return (isinf(x) != 0); }]]),
|
||||||
[AC_MSG_RESULT([yes])
|
[AC_MSG_RESULT([yes])
|
||||||
AC_DEFINE(HAVE_ISINF, 1,
|
AC_DEFINE([HAVE_ISINF], 1,
|
||||||
[Define to 1 if you have the `isinf' macro or function.])],
|
[Define to 1 if you have the `isinf' macro or function.])],
|
||||||
[AC_MSG_RESULT([no])])
|
[AC_MSG_RESULT([no])])
|
||||||
AC_MSG_CHECKING([for isnan])
|
AC_MSG_CHECKING([for isnan])
|
||||||
|
@ -1093,7 +1143,7 @@ AC_LINK_IFELSE(AC_LANG_SOURCE(
|
||||||
volatile double x = 0.0;
|
volatile double x = 0.0;
|
||||||
int main () { return (isnan(x) != 0); }]]),
|
int main () { return (isnan(x) != 0); }]]),
|
||||||
[AC_MSG_RESULT([yes])
|
[AC_MSG_RESULT([yes])
|
||||||
AC_DEFINE(HAVE_ISNAN, 1,
|
AC_DEFINE([HAVE_ISNAN], 1,
|
||||||
[Define to 1 if you have the `isnan' macro or function.])],
|
[Define to 1 if you have the `isnan' macro or function.])],
|
||||||
[AC_MSG_RESULT([no])])
|
[AC_MSG_RESULT([no])])
|
||||||
|
|
||||||
|
@ -1167,9 +1217,35 @@ main ()
|
||||||
[],
|
[],
|
||||||
[AC_MSG_WARN(Guessing that stack grows down -- see scmconfig.h)])
|
[AC_MSG_WARN(Guessing that stack grows down -- see scmconfig.h)])
|
||||||
|
|
||||||
|
#--------------------------------------------------------------------
|
||||||
|
#
|
||||||
|
# Boehm's GC library
|
||||||
|
#
|
||||||
|
#--------------------------------------------------------------------
|
||||||
|
PKG_CHECK_MODULES([BDW_GC], [bdw-gc])
|
||||||
|
|
||||||
|
CFLAGS="$BDW_GC_CFLAGS $CFLAGS"
|
||||||
|
LIBS="$BDW_GC_LIBS $LIBS"
|
||||||
|
|
||||||
|
# `GC_do_blocking ()' is available in GC 7.1 but not declared.
|
||||||
|
AC_CHECK_FUNCS([GC_do_blocking])
|
||||||
|
AC_CHECK_DECL([GC_do_blocking],
|
||||||
|
[AC_DEFINE([HAVE_DECL_GC_DO_BLOCKING], [1],
|
||||||
|
[Define this if the `GC_do_blocking ()' function is declared])],
|
||||||
|
[],
|
||||||
|
[#include <gc/gc.h>])
|
||||||
|
|
||||||
|
# `GC_fn_type' is not available in GC 7.1 and earlier.
|
||||||
|
AC_CHECK_TYPE([GC_fn_type],
|
||||||
|
[AC_DEFINE([HAVE_GC_FN_TYPE], [1],
|
||||||
|
[Define this if the `GC_fn_type' type is available.])],
|
||||||
|
[],
|
||||||
|
[#include <gc/gc.h>])
|
||||||
|
|
||||||
|
|
||||||
AC_CHECK_SIZEOF(float)
|
AC_CHECK_SIZEOF(float)
|
||||||
if test "$ac_cv_sizeof_float" -le "$ac_cv_sizeof_long"; then
|
if test "$ac_cv_sizeof_float" -le "$ac_cv_sizeof_long"; then
|
||||||
AC_DEFINE(SCM_SINGLES, 1,
|
AC_DEFINE([SCM_SINGLES], 1,
|
||||||
[Define this if floats are the same size as longs.])
|
[Define this if floats are the same size as longs.])
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
@ -1183,7 +1259,7 @@ AC_CACHE_VAL(scm_cv_struct_linger,
|
||||||
[scm_cv_struct_linger="no"]))
|
[scm_cv_struct_linger="no"]))
|
||||||
AC_MSG_RESULT($scm_cv_struct_linger)
|
AC_MSG_RESULT($scm_cv_struct_linger)
|
||||||
if test $scm_cv_struct_linger = yes; then
|
if test $scm_cv_struct_linger = yes; then
|
||||||
AC_DEFINE(HAVE_STRUCT_LINGER, 1,
|
AC_DEFINE([HAVE_STRUCT_LINGER], 1,
|
||||||
[Define this if your system defines struct linger, for use with the
|
[Define this if your system defines struct linger, for use with the
|
||||||
getsockopt and setsockopt system calls.])
|
getsockopt and setsockopt system calls.])
|
||||||
fi
|
fi
|
||||||
|
@ -1202,7 +1278,7 @@ AC_CACHE_VAL(scm_cv_struct_timespec,
|
||||||
[scm_cv_struct_timespec="no"]))
|
[scm_cv_struct_timespec="no"]))
|
||||||
AC_MSG_RESULT($scm_cv_struct_timespec)
|
AC_MSG_RESULT($scm_cv_struct_timespec)
|
||||||
if test $scm_cv_struct_timespec = yes; then
|
if test $scm_cv_struct_timespec = yes; then
|
||||||
AC_DEFINE(HAVE_STRUCT_TIMESPEC, 1,
|
AC_DEFINE([HAVE_STRUCT_TIMESPEC], 1,
|
||||||
[Define this if your system defines struct timespec via either <time.h> or <pthread.h>.])
|
[Define this if your system defines struct timespec via either <time.h> or <pthread.h>.])
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
@ -1299,6 +1375,7 @@ case "$with_threads" in
|
||||||
;;
|
;;
|
||||||
"no" | "null")
|
"no" | "null")
|
||||||
SCM_I_GSC_USE_NULL_THREADS=1
|
SCM_I_GSC_USE_NULL_THREADS=1
|
||||||
|
SCM_I_GSC_HAVE_THREAD_STORAGE_CLASS=0
|
||||||
with_threads="null-threads"
|
with_threads="null-threads"
|
||||||
;;
|
;;
|
||||||
* )
|
* )
|
||||||
|
@ -1347,12 +1424,14 @@ int main ()
|
||||||
#endif
|
#endif
|
||||||
]])],
|
]])],
|
||||||
[works=yes
|
[works=yes
|
||||||
AC_DEFINE(PTHREAD_ATTR_GETSTACK_WORKS, [1], [Define when pthread_att_get_stack works for the main thread])],
|
AC_DEFINE([PTHREAD_ATTR_GETSTACK_WORKS], [1], [Define when pthread_att_get_stack works for the main thread])],
|
||||||
[works=no],
|
[works=no],
|
||||||
[])
|
[])
|
||||||
CFLAGS="$old_CFLAGS"
|
CFLAGS="$old_CFLAGS"
|
||||||
AC_MSG_RESULT($works)
|
AC_MSG_RESULT($works)
|
||||||
|
|
||||||
|
GUILE_THREAD_LOCAL_STORAGE
|
||||||
|
|
||||||
fi # with_threads=pthreads
|
fi # with_threads=pthreads
|
||||||
|
|
||||||
|
|
||||||
|
@ -1400,6 +1479,7 @@ AC_ARG_VAR(GUILE_FOR_BUILD,[guile for build system])
|
||||||
AC_SUBST(GUILE_FOR_BUILD)
|
AC_SUBST(GUILE_FOR_BUILD)
|
||||||
|
|
||||||
## If we're using GCC, ask for aggressive warnings.
|
## If we're using GCC, ask for aggressive warnings.
|
||||||
|
GCC_CFLAGS=""
|
||||||
case "$GCC" in
|
case "$GCC" in
|
||||||
yes )
|
yes )
|
||||||
## We had -Wstrict-prototypes in here for a bit, but Guile does too
|
## We had -Wstrict-prototypes in here for a bit, but Guile does too
|
||||||
|
@ -1407,19 +1487,30 @@ case "$GCC" in
|
||||||
## less than exasperating.
|
## less than exasperating.
|
||||||
## -Wpointer-arith was here too, but something changed in gcc/glibc
|
## -Wpointer-arith was here too, but something changed in gcc/glibc
|
||||||
## and it became equally exasperating (gcc 2.95 and/or glibc 2.1.2).
|
## and it became equally exasperating (gcc 2.95 and/or glibc 2.1.2).
|
||||||
GCC_CFLAGS="-Wall -Wmissing-prototypes"
|
POTENTIAL_GCC_CFLAGS="-Wall -Wmissing-prototypes \
|
||||||
|
-Wdeclaration-after-statement -Wundef \
|
||||||
|
-Wswitch-enum"
|
||||||
# Do this here so we don't screw up any of the tests above that might
|
# Do this here so we don't screw up any of the tests above that might
|
||||||
# not be "warning free"
|
# not be "warning free"
|
||||||
if test "${GUILE_ERROR_ON_WARNING}" = yes
|
if test "${GUILE_ERROR_ON_WARNING}" = yes
|
||||||
then
|
then
|
||||||
GCC_CFLAGS="${GCC_CFLAGS} -Werror"
|
POTENTIAL_GCC_CFLAGS="${POTENTIAL_GCC_CFLAGS} -Werror"
|
||||||
enable_compile_warnings=no
|
enable_compile_warnings=no
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
for flag in $POTENTIAL_GCC_CFLAGS
|
||||||
|
do
|
||||||
|
gl_WARN_ADD([$flag], [GCC_CFLAGS])
|
||||||
|
done
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
AC_SUBST(GCC_CFLAGS)
|
AC_SUBST(GCC_CFLAGS)
|
||||||
|
|
||||||
|
# Check for GNU ld's "-z relro".
|
||||||
|
GUILE_GNU_LD_RELRO
|
||||||
|
|
||||||
|
|
||||||
## If we're creating a shared library (using libtool!), then we'll
|
## If we're creating a shared library (using libtool!), then we'll
|
||||||
## need to generate a list of .lo files corresponding to the .o files
|
## need to generate a list of .lo files corresponding to the .o files
|
||||||
## given in LIBOBJS. We'll call it LIBLOBJS.
|
## given in LIBOBJS. We'll call it LIBLOBJS.
|
||||||
|
@ -1498,7 +1589,7 @@ AC_SUBST(top_srcdir_absolute)
|
||||||
|
|
||||||
dnl We need `sitedir' in `guile-1.8.pc'.
|
dnl We need `sitedir' in `guile-1.8.pc'.
|
||||||
dnl Note: `sitedir' must be kept in sync with `GUILE_SITE_DIR' in `guile.m4'.
|
dnl Note: `sitedir' must be kept in sync with `GUILE_SITE_DIR' in `guile.m4'.
|
||||||
pkgdatadir="$datadir/guile"
|
pkgdatadir="$datadir/$PACKAGE_TARNAME"
|
||||||
sitedir="$pkgdatadir/site"
|
sitedir="$pkgdatadir/site"
|
||||||
AC_SUBST([sitedir])
|
AC_SUBST([sitedir])
|
||||||
|
|
||||||
|
@ -1523,7 +1614,6 @@ AC_CONFIG_FILES([
|
||||||
doc/tutorial/Makefile
|
doc/tutorial/Makefile
|
||||||
emacs/Makefile
|
emacs/Makefile
|
||||||
examples/Makefile
|
examples/Makefile
|
||||||
lang/Makefile
|
|
||||||
libguile/Makefile
|
libguile/Makefile
|
||||||
srfi/Makefile
|
srfi/Makefile
|
||||||
guile-readline/Makefile
|
guile-readline/Makefile
|
||||||
|
|
96
doc/gendocs_template
Normal file
96
doc/gendocs_template
Normal file
|
@ -0,0 +1,96 @@
|
||||||
|
<!--#include virtual="/server/header.html" -->
|
||||||
|
<title>%%TITLE%% - GNU Project - Free Software Foundation (FSF)</title>
|
||||||
|
<!--#include virtual="/server/banner.html" -->
|
||||||
|
<h2>%%TITLE%%</h2>
|
||||||
|
|
||||||
|
<!-- This document is in XML, and xhtml 1.0 -->
|
||||||
|
<!-- Please make sure to properly nest your tags -->
|
||||||
|
<!-- and ensure that your final document validates -->
|
||||||
|
<!-- consistent with W3C xhtml 1.0 and CSS standards -->
|
||||||
|
<!-- See validator.w3.org -->
|
||||||
|
|
||||||
|
<address>Free Software Foundation</address>
|
||||||
|
<address>last updated %%DATE%%</address>
|
||||||
|
|
||||||
|
<p>This manual (%%PACKAGE%%) is available in the following formats:</p>
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
<li><a href="%%PACKAGE%%.html">HTML
|
||||||
|
(%%HTML_MONO_SIZE%%K bytes)</a> - entirely on one web page.</li>
|
||||||
|
<li><a href="html_node/index.html">HTML</a> - with one web page per
|
||||||
|
node.</li>
|
||||||
|
%%IF HTML_SECTION%%
|
||||||
|
<li><a href="html_section/index.html">HTML</a> - with one web page per
|
||||||
|
section.</li>
|
||||||
|
%%ENDIF HTML_SECTION%%
|
||||||
|
%%IF HTML_CHAPTER%%
|
||||||
|
<li><a href="html_chapter/index.html">HTML</a> - with one web page per
|
||||||
|
chapter.</li>
|
||||||
|
%%ENDIF HTML_CHAPTER%%
|
||||||
|
<li><a href="%%PACKAGE%%.html.gz">HTML compressed
|
||||||
|
(%%HTML_MONO_GZ_SIZE%%K gzipped characters)</a> - entirely on
|
||||||
|
one web page.</li>
|
||||||
|
<li><a href="%%PACKAGE%%.html_node.tar.gz">HTML compressed
|
||||||
|
(%%HTML_NODE_TGZ_SIZE%%K gzipped tar file)</a> -
|
||||||
|
with one web page per node.</li>
|
||||||
|
%%IF HTML_SECTION%%
|
||||||
|
<li><a href="%%PACKAGE%%.html_section.tar.gz">HTML compressed
|
||||||
|
(%%HTML_SECTION_TGZ_SIZE%%K gzipped tar file)</a> -
|
||||||
|
with one web page per section.</li>
|
||||||
|
%%ENDIF HTML_SECTION%%
|
||||||
|
%%IF HTML_CHAPTER%%
|
||||||
|
<li><a href="%%PACKAGE%%.html_chapter.tar.gz">HTML compressed
|
||||||
|
(%%HTML_CHAPTER_TGZ_SIZE%%K gzipped tar file)</a> -
|
||||||
|
with one web page per chapter.</li>
|
||||||
|
%%ENDIF HTML_CHAPTER%%
|
||||||
|
<li><a href="%%PACKAGE%%.info.tar.gz">Info document
|
||||||
|
(%%INFO_TGZ_SIZE%%K bytes gzipped tar file)</a>.</li>
|
||||||
|
<li><a href="%%PACKAGE%%.txt">ASCII text
|
||||||
|
(%%ASCII_SIZE%%K bytes)</a>.</li>
|
||||||
|
<li><a href="%%PACKAGE%%.txt.gz">ASCII text compressed
|
||||||
|
(%%ASCII_GZ_SIZE%%K bytes gzipped)</a>.</li>
|
||||||
|
<li><a href="%%PACKAGE%%.dvi.gz">TeX dvi file
|
||||||
|
(%%DVI_GZ_SIZE%%K bytes gzipped)</a>.</li>
|
||||||
|
<li><a href="%%PACKAGE%%.ps.gz">PostScript file
|
||||||
|
(%%PS_GZ_SIZE%%K bytes gzipped)</a>.</li>
|
||||||
|
<li><a href="%%PACKAGE%%.pdf">PDF file
|
||||||
|
(%%PDF_SIZE%%K bytes)</a>.</li>
|
||||||
|
<li><a href="%%PACKAGE%%.texi.tar.gz">Texinfo source
|
||||||
|
(%%TEXI_TGZ_SIZE%%K bytes gzipped tar file).</a></li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<p>You can <a href="http://shop.fsf.org/">buy printed copies of
|
||||||
|
some manuals</a> (among other items) from the Free Software Foundation;
|
||||||
|
this helps support FSF activities.</p>
|
||||||
|
|
||||||
|
<p>(This page generated by the <a href="%%SCRIPTURL%%">%%SCRIPTNAME%%
|
||||||
|
script</a>.)</p>
|
||||||
|
|
||||||
|
<!-- If needed, change the copyright block at the bottom. In general, -->
|
||||||
|
<!-- all pages on the GNU web server should have the section about -->
|
||||||
|
<!-- verbatim copying. Please do NOT remove this without talking -->
|
||||||
|
<!-- with the webmasters first. -->
|
||||||
|
<!-- Please make sure the copyright date is consistent with the document -->
|
||||||
|
<!-- and that it is like this "2001, 2002" not this "2001-2002." -->
|
||||||
|
</div><!-- for id="content", starts in the include above -->
|
||||||
|
<!--#include virtual="/server/footer.html" -->
|
||||||
|
<div id="footer">
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Please send FSF & GNU inquiries to
|
||||||
|
<a href="mailto:gnu@gnu.org"><gnu@gnu.org></a>.
|
||||||
|
There are also <a href="/contact/">other ways to contact</a>
|
||||||
|
the FSF.<br />
|
||||||
|
Please send broken links and other corrections or suggestions to
|
||||||
|
<a href="mailto:%%EMAIL%%"><%%EMAIL%%></a>.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>Copyright © 2009 Free Software Foundation, Inc.</p>
|
||||||
|
|
||||||
|
<p>Verbatim copying and distribution of this entire article is
|
||||||
|
permitted in any medium, provided this notice is preserved.</p>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -1750,22 +1750,6 @@ current interfaces. If a file cannot be opened with the access
|
||||||
requested, @code{open-file} throws an exception.
|
requested, @code{open-file} throws an exception.
|
||||||
@end deffn
|
@end deffn
|
||||||
|
|
||||||
make-future
|
|
||||||
@c snarfed from futures.c:89
|
|
||||||
@deffn {Scheme Procedure} make-future thunk
|
|
||||||
@deffnx {C Function} scm_make_future (thunk)
|
|
||||||
Make a future evaluating THUNK.
|
|
||||||
@end deffn
|
|
||||||
|
|
||||||
future-ref
|
|
||||||
@c snarfed from futures.c:221
|
|
||||||
@deffn {Scheme Procedure} future-ref future
|
|
||||||
@deffnx {C Function} scm_future_ref (future)
|
|
||||||
If the future @var{x} has not been computed yet, compute and
|
|
||||||
return @var{x}, otherwise just return the previously computed
|
|
||||||
value.
|
|
||||||
@end deffn
|
|
||||||
|
|
||||||
gc-live-object-stats
|
gc-live-object-stats
|
||||||
@c snarfed from gc.c:276
|
@c snarfed from gc.c:276
|
||||||
@deffn {Scheme Procedure} gc-live-object-stats
|
@deffn {Scheme Procedure} gc-live-object-stats
|
||||||
|
@ -10708,8 +10692,8 @@ the input is an integer with normal host byte ordering.
|
||||||
|
|
||||||
@lisp
|
@lisp
|
||||||
(inet-ntop AF_INET 2130706433) @result{} "127.0.0.1"
|
(inet-ntop AF_INET 2130706433) @result{} "127.0.0.1"
|
||||||
(inet-ntop AF_INET6 (- (expt 2 128) 1)) @result{}
|
(inet-ntop AF_INET6 (- (expt 2 128) 1))
|
||||||
ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff
|
@result{} "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"
|
||||||
@end lisp
|
@end lisp
|
||||||
@end deffn
|
@end deffn
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
@c -*-texinfo-*-
|
@c -*-texinfo-*-
|
||||||
@c This is part of the GNU Guile Reference Manual.
|
@c This is part of the GNU Guile Reference Manual.
|
||||||
@c Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004
|
@c Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004, 2009
|
||||||
@c Free Software Foundation, Inc.
|
@c Free Software Foundation, Inc.
|
||||||
@c See the file guile.texi for copying conditions.
|
@c See the file guile.texi for copying conditions.
|
||||||
|
|
||||||
|
@ -1506,8 +1506,8 @@ which is the name of the procedure incorrectly invoked.
|
||||||
@subsection Continuation Barriers
|
@subsection Continuation Barriers
|
||||||
|
|
||||||
The non-local flow of control caused by continuations might sometimes
|
The non-local flow of control caused by continuations might sometimes
|
||||||
not be wanted. You can use @code{with-continuation-barrier} etc to
|
not be wanted. You can use @code{with-continuation-barrier} to erect
|
||||||
errect fences that continuations can not pass.
|
fences that continuations can not pass.
|
||||||
|
|
||||||
@deffn {Scheme Procedure} with-continuation-barrier proc
|
@deffn {Scheme Procedure} with-continuation-barrier proc
|
||||||
@deffnx {C Function} scm_with_continuation_barrier (proc)
|
@deffnx {C Function} scm_with_continuation_barrier (proc)
|
||||||
|
|
|
@ -184,7 +184,6 @@ in Scheme, which is particularly clear and accessible: see
|
||||||
* Complex:: Complex number operations.
|
* Complex:: Complex number operations.
|
||||||
* Arithmetic:: Arithmetic functions.
|
* Arithmetic:: Arithmetic functions.
|
||||||
* Scientific:: Scientific functions.
|
* Scientific:: Scientific functions.
|
||||||
* Primitive Numerics:: Primitive numeric functions.
|
|
||||||
* Bitwise Operations:: Logical AND, OR, NOT, and so on.
|
* Bitwise Operations:: Logical AND, OR, NOT, and so on.
|
||||||
* Random:: Random number generation.
|
* Random:: Random number generation.
|
||||||
@end menu
|
@end menu
|
||||||
|
@ -539,7 +538,7 @@ error. Instead, the result of the division is either plus or minus
|
||||||
infinity, depending on the sign of the divided number.
|
infinity, depending on the sign of the divided number.
|
||||||
|
|
||||||
The infinities are written @samp{+inf.0} and @samp{-inf.0},
|
The infinities are written @samp{+inf.0} and @samp{-inf.0},
|
||||||
respectivly. This syntax is also recognized by @code{read} as an
|
respectively. This syntax is also recognized by @code{read} as an
|
||||||
extension to the usual Scheme syntax.
|
extension to the usual Scheme syntax.
|
||||||
|
|
||||||
Dividing zero by zero yields something that is not a number at all:
|
Dividing zero by zero yields something that is not a number at all:
|
||||||
|
@ -637,7 +636,7 @@ magnitude. The argument @var{val} must be a real number.
|
||||||
@end deftypefn
|
@end deftypefn
|
||||||
|
|
||||||
@deftypefn {C Function} SCM scm_from_double (double val)
|
@deftypefn {C Function} SCM scm_from_double (double val)
|
||||||
Return the @code{SCM} value that representats @var{val}. The returned
|
Return the @code{SCM} value that represents @var{val}. The returned
|
||||||
value is inexact according to the predicate @code{inexact?}, but it
|
value is inexact according to the predicate @code{inexact?}, but it
|
||||||
will be exactly equal to @var{val}.
|
will be exactly equal to @var{val}.
|
||||||
@end deftypefn
|
@end deftypefn
|
||||||
|
@ -1337,150 +1336,6 @@ Return the hyperbolic arctangent of @var{z}.
|
||||||
@end deffn
|
@end deffn
|
||||||
|
|
||||||
|
|
||||||
@node Primitive Numerics
|
|
||||||
@subsubsection Primitive Numeric Functions
|
|
||||||
|
|
||||||
Many of Guile's numeric procedures which accept any kind of numbers as
|
|
||||||
arguments, including complex numbers, are implemented as Scheme
|
|
||||||
procedures that use the following real number-based primitives. These
|
|
||||||
primitives signal an error if they are called with complex arguments.
|
|
||||||
|
|
||||||
@c begin (texi-doc-string "guile" "$abs")
|
|
||||||
@deffn {Scheme Procedure} $abs x
|
|
||||||
Return the absolute value of @var{x}.
|
|
||||||
@end deffn
|
|
||||||
|
|
||||||
@c begin (texi-doc-string "guile" "$sqrt")
|
|
||||||
@deffn {Scheme Procedure} $sqrt x
|
|
||||||
Return the square root of @var{x}.
|
|
||||||
@end deffn
|
|
||||||
|
|
||||||
@deffn {Scheme Procedure} $expt x y
|
|
||||||
@deffnx {C Function} scm_sys_expt (x, y)
|
|
||||||
Return @var{x} raised to the power of @var{y}. This
|
|
||||||
procedure does not accept complex arguments.
|
|
||||||
@end deffn
|
|
||||||
|
|
||||||
@c begin (texi-doc-string "guile" "$sin")
|
|
||||||
@deffn {Scheme Procedure} $sin x
|
|
||||||
Return the sine of @var{x}.
|
|
||||||
@end deffn
|
|
||||||
|
|
||||||
@c begin (texi-doc-string "guile" "$cos")
|
|
||||||
@deffn {Scheme Procedure} $cos x
|
|
||||||
Return the cosine of @var{x}.
|
|
||||||
@end deffn
|
|
||||||
|
|
||||||
@c begin (texi-doc-string "guile" "$tan")
|
|
||||||
@deffn {Scheme Procedure} $tan x
|
|
||||||
Return the tangent of @var{x}.
|
|
||||||
@end deffn
|
|
||||||
|
|
||||||
@c begin (texi-doc-string "guile" "$asin")
|
|
||||||
@deffn {Scheme Procedure} $asin x
|
|
||||||
Return the arcsine of @var{x}.
|
|
||||||
@end deffn
|
|
||||||
|
|
||||||
@c begin (texi-doc-string "guile" "$acos")
|
|
||||||
@deffn {Scheme Procedure} $acos x
|
|
||||||
Return the arccosine of @var{x}.
|
|
||||||
@end deffn
|
|
||||||
|
|
||||||
@c begin (texi-doc-string "guile" "$atan")
|
|
||||||
@deffn {Scheme Procedure} $atan x
|
|
||||||
Return the arctangent of @var{x} in the range @minus{}@math{PI/2} to
|
|
||||||
@math{PI/2}.
|
|
||||||
@end deffn
|
|
||||||
|
|
||||||
@deffn {Scheme Procedure} $atan2 x y
|
|
||||||
@deffnx {C Function} scm_sys_atan2 (x, y)
|
|
||||||
Return the arc tangent of the two arguments @var{x} and
|
|
||||||
@var{y}. This is similar to calculating the arc tangent of
|
|
||||||
@var{x} / @var{y}, except that the signs of both arguments
|
|
||||||
are used to determine the quadrant of the result. This
|
|
||||||
procedure does not accept complex arguments.
|
|
||||||
@end deffn
|
|
||||||
|
|
||||||
@c begin (texi-doc-string "guile" "$exp")
|
|
||||||
@deffn {Scheme Procedure} $exp x
|
|
||||||
Return e to the power of @var{x}, where e is the base of natural
|
|
||||||
logarithms (2.71828@dots{}).
|
|
||||||
@end deffn
|
|
||||||
|
|
||||||
@c begin (texi-doc-string "guile" "$log")
|
|
||||||
@deffn {Scheme Procedure} $log x
|
|
||||||
Return the natural logarithm of @var{x}.
|
|
||||||
@end deffn
|
|
||||||
|
|
||||||
@c begin (texi-doc-string "guile" "$sinh")
|
|
||||||
@deffn {Scheme Procedure} $sinh x
|
|
||||||
Return the hyperbolic sine of @var{x}.
|
|
||||||
@end deffn
|
|
||||||
|
|
||||||
@c begin (texi-doc-string "guile" "$cosh")
|
|
||||||
@deffn {Scheme Procedure} $cosh x
|
|
||||||
Return the hyperbolic cosine of @var{x}.
|
|
||||||
@end deffn
|
|
||||||
|
|
||||||
@c begin (texi-doc-string "guile" "$tanh")
|
|
||||||
@deffn {Scheme Procedure} $tanh x
|
|
||||||
Return the hyperbolic tangent of @var{x}.
|
|
||||||
@end deffn
|
|
||||||
|
|
||||||
@c begin (texi-doc-string "guile" "$asinh")
|
|
||||||
@deffn {Scheme Procedure} $asinh x
|
|
||||||
Return the hyperbolic arcsine of @var{x}.
|
|
||||||
@end deffn
|
|
||||||
|
|
||||||
@c begin (texi-doc-string "guile" "$acosh")
|
|
||||||
@deffn {Scheme Procedure} $acosh x
|
|
||||||
Return the hyperbolic arccosine of @var{x}.
|
|
||||||
@end deffn
|
|
||||||
|
|
||||||
@c begin (texi-doc-string "guile" "$atanh")
|
|
||||||
@deffn {Scheme Procedure} $atanh x
|
|
||||||
Return the hyperbolic arctangent of @var{x}.
|
|
||||||
@end deffn
|
|
||||||
|
|
||||||
C functions for the above are provided by the standard mathematics
|
|
||||||
library. Naturally these expect and return @code{double} arguments
|
|
||||||
(@pxref{Mathematics,,, libc, GNU C Library Reference Manual}).
|
|
||||||
|
|
||||||
@multitable {xx} {Scheme Procedure} {C Function}
|
|
||||||
@item @tab Scheme Procedure @tab C Function
|
|
||||||
|
|
||||||
@item @tab @code{$abs} @tab @code{fabs}
|
|
||||||
@item @tab @code{$sqrt} @tab @code{sqrt}
|
|
||||||
@item @tab @code{$sin} @tab @code{sin}
|
|
||||||
@item @tab @code{$cos} @tab @code{cos}
|
|
||||||
@item @tab @code{$tan} @tab @code{tan}
|
|
||||||
@item @tab @code{$asin} @tab @code{asin}
|
|
||||||
@item @tab @code{$acos} @tab @code{acos}
|
|
||||||
@item @tab @code{$atan} @tab @code{atan}
|
|
||||||
@item @tab @code{$atan2} @tab @code{atan2}
|
|
||||||
@item @tab @code{$exp} @tab @code{exp}
|
|
||||||
@item @tab @code{$expt} @tab @code{pow}
|
|
||||||
@item @tab @code{$log} @tab @code{log}
|
|
||||||
@item @tab @code{$sinh} @tab @code{sinh}
|
|
||||||
@item @tab @code{$cosh} @tab @code{cosh}
|
|
||||||
@item @tab @code{$tanh} @tab @code{tanh}
|
|
||||||
@item @tab @code{$asinh} @tab @code{asinh}
|
|
||||||
@item @tab @code{$acosh} @tab @code{acosh}
|
|
||||||
@item @tab @code{$atanh} @tab @code{atanh}
|
|
||||||
@end multitable
|
|
||||||
|
|
||||||
@code{asinh}, @code{acosh} and @code{atanh} are C99 standard but might
|
|
||||||
not be available on older systems. Guile provides the following
|
|
||||||
equivalents (on all systems).
|
|
||||||
|
|
||||||
@deftypefn {C Function} double scm_asinh (double x)
|
|
||||||
@deftypefnx {C Function} double scm_acosh (double x)
|
|
||||||
@deftypefnx {C Function} double scm_atanh (double x)
|
|
||||||
Return the hyperbolic arcsine, arccosine or arctangent of @var{x}
|
|
||||||
respectively.
|
|
||||||
@end deftypefn
|
|
||||||
|
|
||||||
|
|
||||||
@node Bitwise Operations
|
@node Bitwise Operations
|
||||||
@subsubsection Bitwise Operations
|
@subsubsection Bitwise Operations
|
||||||
|
|
||||||
|
@ -1779,16 +1634,66 @@ another manual.
|
||||||
@subsection Characters
|
@subsection Characters
|
||||||
@tpindex Characters
|
@tpindex Characters
|
||||||
|
|
||||||
|
In Scheme, there is a data type to describe a single character.
|
||||||
|
|
||||||
|
Defining what exactly a character @emph{is} can be more complicated
|
||||||
|
than it seems. Guile follows the advice of R6RS and uses The Unicode
|
||||||
|
Standard to help define what a character is. So, for Guile, a
|
||||||
|
character is anything in the Unicode Character Database.
|
||||||
|
|
||||||
|
@cindex code point
|
||||||
|
@cindex Unicode code point
|
||||||
|
|
||||||
|
The Unicode Character Database is basically a table of characters
|
||||||
|
indexed using integers called 'code points'. Valid code points are in
|
||||||
|
the ranges 0 to @code{#xD7FF} inclusive or @code{#xE000} to
|
||||||
|
@code{#x10FFFF} inclusive, which is about 1.1 million code points.
|
||||||
|
|
||||||
|
@cindex designated code point
|
||||||
|
@cindex code point, designated
|
||||||
|
|
||||||
|
Any code point that has been assigned to a character or that has
|
||||||
|
otherwise been given a meaning by Unicode is called a 'designated code
|
||||||
|
point'. Most of the designated code points, about 200,000 of them,
|
||||||
|
indicate characters, accents or other combining marks that modify
|
||||||
|
other characters, symbols, whitespace, and control characters. Some
|
||||||
|
are not characters but indicators that suggest how to format or
|
||||||
|
display neighboring characters.
|
||||||
|
|
||||||
|
@cindex reserved code point
|
||||||
|
@cindex code point, reserved
|
||||||
|
|
||||||
|
If a code point is not a designated code point -- if it has not been
|
||||||
|
assigned to a character by The Unicode Standard -- it is a 'reserved
|
||||||
|
code point', meaning that they are reserved for future use. Most of
|
||||||
|
the code points, about 800,000, are 'reserved code points'.
|
||||||
|
|
||||||
|
By convention, a Unicode code point is written as
|
||||||
|
``U+XXXX'' where ``XXXX'' is a hexadecimal number. Please note that
|
||||||
|
this convenient notation is not valid code. Guile does not interpret
|
||||||
|
``U+XXXX'' as a character.
|
||||||
|
|
||||||
In Scheme, a character literal is written as @code{#\@var{name}} where
|
In Scheme, a character literal is written as @code{#\@var{name}} where
|
||||||
@var{name} is the name of the character that you want. Printable
|
@var{name} is the name of the character that you want. Printable
|
||||||
characters have their usual single character name; for example,
|
characters have their usual single character name; for example,
|
||||||
@code{#\a} is a lower case @code{a}.
|
@code{#\a} is a lower case @code{a}.
|
||||||
|
|
||||||
Most of the ``control characters'' (those below codepoint 32) in the
|
Some of the code points are 'combining characters' that are not meant
|
||||||
@acronym{ASCII} character set, as well as the space, may be referred
|
to be printed by themselves but are instead meant to modify the
|
||||||
to by longer names: for example, @code{#\tab}, @code{#\esc},
|
appearance of the previous character. For combining characters, an
|
||||||
@code{#\stx}, and so on. The following table describes the
|
alternate form of the character literal is @code{#\} followed by
|
||||||
@acronym{ASCII} names for each character.
|
U+25CC (a small, dotted circle), followed by the combining character.
|
||||||
|
This allows the combining character to be drawn on the circle, not on
|
||||||
|
the backslash of @code{#\}.
|
||||||
|
|
||||||
|
Many of the non-printing characters, such as whitespace characters and
|
||||||
|
control characters, also have names.
|
||||||
|
|
||||||
|
The most commonly used non-printing characters are space and
|
||||||
|
newline. Their character names are @code{#\space} and
|
||||||
|
@code{#\newline}. There are also names for all of the ``C0 control
|
||||||
|
characters'' (those with code points below 32). The following table
|
||||||
|
describes the names for each character.
|
||||||
|
|
||||||
@multitable @columnfractions .25 .25 .25 .25
|
@multitable @columnfractions .25 .25 .25 .25
|
||||||
@item 0 = @code{#\nul}
|
@item 0 = @code{#\nul}
|
||||||
|
@ -1801,9 +1706,9 @@ to by longer names: for example, @code{#\tab}, @code{#\esc},
|
||||||
@tab 7 = @code{#\bel}
|
@tab 7 = @code{#\bel}
|
||||||
@item 8 = @code{#\bs}
|
@item 8 = @code{#\bs}
|
||||||
@tab 9 = @code{#\ht}
|
@tab 9 = @code{#\ht}
|
||||||
@tab 10 = @code{#\nl}
|
@tab 10 = @code{#\lf}
|
||||||
@tab 11 = @code{#\vt}
|
@tab 11 = @code{#\vt}
|
||||||
@item 12 = @code{#\np}
|
@item 12 = @code{#\ff}
|
||||||
@tab 13 = @code{#\cr}
|
@tab 13 = @code{#\cr}
|
||||||
@tab 14 = @code{#\so}
|
@tab 14 = @code{#\so}
|
||||||
@tab 15 = @code{#\si}
|
@tab 15 = @code{#\si}
|
||||||
|
@ -1826,85 +1731,112 @@ to by longer names: for example, @code{#\tab}, @code{#\esc},
|
||||||
@item 32 = @code{#\sp}
|
@item 32 = @code{#\sp}
|
||||||
@end multitable
|
@end multitable
|
||||||
|
|
||||||
The ``delete'' character (octal 177) may be referred to with the name
|
The ``delete'' character (code point U+007F) may be referred to with the
|
||||||
@code{#\del}.
|
name @code{#\del}.
|
||||||
|
|
||||||
Several characters have more than one name:
|
One might note that the space character has two names --
|
||||||
|
@code{#\space} and @code{#\sp} -- as does the newline character.
|
||||||
|
Several other non-printing characters have more than one name, for the
|
||||||
|
sake of compatibility with previous versions.
|
||||||
|
|
||||||
@multitable {@code{#\backspace}} {Original}
|
@multitable {@code{#\backspace}} {Preferred}
|
||||||
@item Alias @tab Original
|
@item Alternate @tab Standard
|
||||||
@item @code{#\space} @tab @code{#\sp}
|
@item @code{#\sp} @tab @code{#\space}
|
||||||
@item @code{#\newline} @tab @code{#\nl}
|
@item @code{#\nl} @tab @code{#\newline}
|
||||||
|
@item @code{#\lf} @tab @code{#\newline}
|
||||||
@item @code{#\tab} @tab @code{#\ht}
|
@item @code{#\tab} @tab @code{#\ht}
|
||||||
@item @code{#\backspace} @tab @code{#\bs}
|
@item @code{#\backspace} @tab @code{#\bs}
|
||||||
@item @code{#\return} @tab @code{#\cr}
|
@item @code{#\return} @tab @code{#\cr}
|
||||||
@item @code{#\page} @tab @code{#\np}
|
@item @code{#\page} @tab @code{#\ff}
|
||||||
|
@item @code{#\np} @tab @code{#\ff}
|
||||||
@item @code{#\null} @tab @code{#\nul}
|
@item @code{#\null} @tab @code{#\nul}
|
||||||
@end multitable
|
@end multitable
|
||||||
|
|
||||||
|
Characters may also be written using their code point values. They can
|
||||||
|
be written with as an octal number, such as @code{#\10} for
|
||||||
|
@code{#\bs} or @code{#\177} for @code{#\del}.
|
||||||
|
|
||||||
@rnindex char?
|
@rnindex char?
|
||||||
@deffn {Scheme Procedure} char? x
|
@deffn {Scheme Procedure} char? x
|
||||||
@deffnx {C Function} scm_char_p (x)
|
@deffnx {C Function} scm_char_p (x)
|
||||||
Return @code{#t} iff @var{x} is a character, else @code{#f}.
|
Return @code{#t} iff @var{x} is a character, else @code{#f}.
|
||||||
@end deffn
|
@end deffn
|
||||||
|
|
||||||
|
Fundamentally, the character comparison operations below are
|
||||||
|
numeric comparisons of the character's code points.
|
||||||
|
|
||||||
@rnindex char=?
|
@rnindex char=?
|
||||||
@deffn {Scheme Procedure} char=? x y
|
@deffn {Scheme Procedure} char=? x y
|
||||||
Return @code{#t} iff @var{x} is the same character as @var{y}, else @code{#f}.
|
Return @code{#t} iff code point of @var{x} is equal to the code point
|
||||||
|
of @var{y}, else @code{#f}.
|
||||||
@end deffn
|
@end deffn
|
||||||
|
|
||||||
@rnindex char<?
|
@rnindex char<?
|
||||||
@deffn {Scheme Procedure} char<? x y
|
@deffn {Scheme Procedure} char<? x y
|
||||||
Return @code{#t} iff @var{x} is less than @var{y} in the @acronym{ASCII} sequence,
|
Return @code{#t} iff the code point of @var{x} is less than the code
|
||||||
else @code{#f}.
|
point of @var{y}, else @code{#f}.
|
||||||
@end deffn
|
@end deffn
|
||||||
|
|
||||||
@rnindex char<=?
|
@rnindex char<=?
|
||||||
@deffn {Scheme Procedure} char<=? x y
|
@deffn {Scheme Procedure} char<=? x y
|
||||||
Return @code{#t} iff @var{x} is less than or equal to @var{y} in the
|
Return @code{#t} iff the code point of @var{x} is less than or equal
|
||||||
@acronym{ASCII} sequence, else @code{#f}.
|
to the code point of @var{y}, else @code{#f}.
|
||||||
@end deffn
|
@end deffn
|
||||||
|
|
||||||
@rnindex char>?
|
@rnindex char>?
|
||||||
@deffn {Scheme Procedure} char>? x y
|
@deffn {Scheme Procedure} char>? x y
|
||||||
Return @code{#t} iff @var{x} is greater than @var{y} in the @acronym{ASCII}
|
Return @code{#t} iff the code point of @var{x} is greater than the
|
||||||
sequence, else @code{#f}.
|
code point of @var{y}, else @code{#f}.
|
||||||
@end deffn
|
@end deffn
|
||||||
|
|
||||||
@rnindex char>=?
|
@rnindex char>=?
|
||||||
@deffn {Scheme Procedure} char>=? x y
|
@deffn {Scheme Procedure} char>=? x y
|
||||||
Return @code{#t} iff @var{x} is greater than or equal to @var{y} in the
|
Return @code{#t} iff the code point of @var{x} is greater than or
|
||||||
@acronym{ASCII} sequence, else @code{#f}.
|
equal to the code point of @var{y}, else @code{#f}.
|
||||||
@end deffn
|
@end deffn
|
||||||
|
|
||||||
|
@cindex case folding
|
||||||
|
|
||||||
|
Case-insensitive character comparisons use @emph{Unicode case
|
||||||
|
folding}. In case folding comparisons, if a character is lowercase
|
||||||
|
and has an uppercase form that can be expressed as a single character,
|
||||||
|
it is converted to uppercase before comparison. All other characters
|
||||||
|
undergo no conversion before the comparison occurs. This includes the
|
||||||
|
German sharp S (Eszett) which is not uppercased before conversion
|
||||||
|
because its uppercase form has two characters. Unicode case folding
|
||||||
|
is language independent: it uses rules that are generally true, but,
|
||||||
|
it cannot cover all cases for all languages.
|
||||||
|
|
||||||
@rnindex char-ci=?
|
@rnindex char-ci=?
|
||||||
@deffn {Scheme Procedure} char-ci=? x y
|
@deffn {Scheme Procedure} char-ci=? x y
|
||||||
Return @code{#t} iff @var{x} is the same character as @var{y} ignoring
|
Return @code{#t} iff the case-folded code point of @var{x} is the same
|
||||||
case, else @code{#f}.
|
as the case-folded code point of @var{y}, else @code{#f}.
|
||||||
@end deffn
|
@end deffn
|
||||||
|
|
||||||
@rnindex char-ci<?
|
@rnindex char-ci<?
|
||||||
@deffn {Scheme Procedure} char-ci<? x y
|
@deffn {Scheme Procedure} char-ci<? x y
|
||||||
Return @code{#t} iff @var{x} is less than @var{y} in the @acronym{ASCII} sequence
|
Return @code{#t} iff the case-folded code point of @var{x} is less
|
||||||
ignoring case, else @code{#f}.
|
than the case-folded code point of @var{y}, else @code{#f}.
|
||||||
@end deffn
|
@end deffn
|
||||||
|
|
||||||
@rnindex char-ci<=?
|
@rnindex char-ci<=?
|
||||||
@deffn {Scheme Procedure} char-ci<=? x y
|
@deffn {Scheme Procedure} char-ci<=? x y
|
||||||
Return @code{#t} iff @var{x} is less than or equal to @var{y} in the
|
Return @code{#t} iff the case-folded code point of @var{x} is less
|
||||||
@acronym{ASCII} sequence ignoring case, else @code{#f}.
|
than or equal to the case-folded code point of @var{y}, else
|
||||||
|
@code{#f}.
|
||||||
@end deffn
|
@end deffn
|
||||||
|
|
||||||
@rnindex char-ci>?
|
@rnindex char-ci>?
|
||||||
@deffn {Scheme Procedure} char-ci>? x y
|
@deffn {Scheme Procedure} char-ci>? x y
|
||||||
Return @code{#t} iff @var{x} is greater than @var{y} in the @acronym{ASCII}
|
Return @code{#t} iff the case-folded code point of @var{x} is greater
|
||||||
sequence ignoring case, else @code{#f}.
|
than the case-folded code point of @var{y}, else @code{#f}.
|
||||||
@end deffn
|
@end deffn
|
||||||
|
|
||||||
@rnindex char-ci>=?
|
@rnindex char-ci>=?
|
||||||
@deffn {Scheme Procedure} char-ci>=? x y
|
@deffn {Scheme Procedure} char-ci>=? x y
|
||||||
Return @code{#t} iff @var{x} is greater than or equal to @var{y} in the
|
Return @code{#t} iff the case-folded code point of @var{x} is greater
|
||||||
@acronym{ASCII} sequence ignoring case, else @code{#f}.
|
than or equal to the case-folded code point of @var{y}, else
|
||||||
|
@code{#f}.
|
||||||
@end deffn
|
@end deffn
|
||||||
|
|
||||||
@rnindex char-alphabetic?
|
@rnindex char-alphabetic?
|
||||||
|
@ -1946,14 +1878,15 @@ Return @code{#t} iff @var{chr} is either uppercase or lowercase, else
|
||||||
@rnindex char->integer
|
@rnindex char->integer
|
||||||
@deffn {Scheme Procedure} char->integer chr
|
@deffn {Scheme Procedure} char->integer chr
|
||||||
@deffnx {C Function} scm_char_to_integer (chr)
|
@deffnx {C Function} scm_char_to_integer (chr)
|
||||||
Return the number corresponding to ordinal position of @var{chr} in the
|
Return the code point of @var{chr}.
|
||||||
@acronym{ASCII} sequence.
|
|
||||||
@end deffn
|
@end deffn
|
||||||
|
|
||||||
@rnindex integer->char
|
@rnindex integer->char
|
||||||
@deffn {Scheme Procedure} integer->char n
|
@deffn {Scheme Procedure} integer->char n
|
||||||
@deffnx {C Function} scm_integer_to_char (n)
|
@deffnx {C Function} scm_integer_to_char (n)
|
||||||
Return the character at position @var{n} in the @acronym{ASCII} sequence.
|
Return the character that has code point @var{n}. The integer @var{n}
|
||||||
|
must be a valid code point. Valid code points are in the ranges 0 to
|
||||||
|
@code{#xD7FF} inclusive or @code{#xE000} to @code{#x10FFFF} inclusive.
|
||||||
@end deffn
|
@end deffn
|
||||||
|
|
||||||
@rnindex char-upcase
|
@rnindex char-upcase
|
||||||
|
@ -1981,12 +1914,6 @@ handling them are provided.
|
||||||
Character sets can be created, extended, tested for the membership of a
|
Character sets can be created, extended, tested for the membership of a
|
||||||
characters and be compared to other character sets.
|
characters and be compared to other character sets.
|
||||||
|
|
||||||
The Guile implementation of character sets currently deals only with
|
|
||||||
8-bit characters. In the future, when Guile gets support for
|
|
||||||
international character sets, this will change, but the functions
|
|
||||||
provided here will always then be able to efficiently cope with very
|
|
||||||
large character sets.
|
|
||||||
|
|
||||||
@menu
|
@menu
|
||||||
* Character Set Predicates/Comparison::
|
* Character Set Predicates/Comparison::
|
||||||
* Iterating Over Character Sets:: Enumerate charset elements.
|
* Iterating Over Character Sets:: Enumerate charset elements.
|
||||||
|
@ -2185,7 +2112,7 @@ character codes lie in the half-open range
|
||||||
If @var{error} is a true value, an error is signalled if the
|
If @var{error} is a true value, an error is signalled if the
|
||||||
specified range contains characters which are not contained in
|
specified range contains characters which are not contained in
|
||||||
the implemented character range. If @var{error} is @code{#f},
|
the implemented character range. If @var{error} is @code{#f},
|
||||||
these characters are silently left out of the resultung
|
these characters are silently left out of the resulting
|
||||||
character set.
|
character set.
|
||||||
|
|
||||||
The characters in @var{base_cs} are added to the result, if
|
The characters in @var{base_cs} are added to the result, if
|
||||||
|
@ -2201,7 +2128,7 @@ character codes lie in the half-open range
|
||||||
If @var{error} is a true value, an error is signalled if the
|
If @var{error} is a true value, an error is signalled if the
|
||||||
specified range contains characters which are not contained in
|
specified range contains characters which are not contained in
|
||||||
the implemented character range. If @var{error} is @code{#f},
|
the implemented character range. If @var{error} is @code{#f},
|
||||||
these characters are silently left out of the resultung
|
these characters are silently left out of the resulting
|
||||||
character set.
|
character set.
|
||||||
|
|
||||||
The characters are added to @var{base_cs} and @var{base_cs} is
|
The characters are added to @var{base_cs} and @var{base_cs} is
|
||||||
|
@ -2210,7 +2137,10 @@ returned.
|
||||||
|
|
||||||
@deffn {Scheme Procedure} ->char-set x
|
@deffn {Scheme Procedure} ->char-set x
|
||||||
@deffnx {C Function} scm_to_char_set (x)
|
@deffnx {C Function} scm_to_char_set (x)
|
||||||
Coerces x into a char-set. @var{x} may be a string, character or char-set. A string is converted to the set of its constituent characters; a character is converted to a singleton set; a char-set is returned as-is.
|
Coerces x into a char-set. @var{x} may be a string, character or
|
||||||
|
char-set. A string is converted to the set of its constituent
|
||||||
|
characters; a character is converted to a singleton set; a char-set is
|
||||||
|
returned as-is.
|
||||||
@end deffn
|
@end deffn
|
||||||
|
|
||||||
@c ===================================================================
|
@c ===================================================================
|
||||||
|
@ -2221,6 +2151,23 @@ Coerces x into a char-set. @var{x} may be a string, character or char-set. A str
|
||||||
Access the elements and other information of a character set with these
|
Access the elements and other information of a character set with these
|
||||||
procedures.
|
procedures.
|
||||||
|
|
||||||
|
@deffn {Scheme Procedure} %char-set-dump cs
|
||||||
|
Returns an association list containing debugging information
|
||||||
|
for @var{cs}. The association list has the following entries.
|
||||||
|
@table @code
|
||||||
|
@item char-set
|
||||||
|
The char-set itself
|
||||||
|
@item len
|
||||||
|
The number of groups of contiguous code points the char-set
|
||||||
|
contains
|
||||||
|
@item ranges
|
||||||
|
A list of lists where each sublist is a range of code points
|
||||||
|
and their associated characters
|
||||||
|
@end table
|
||||||
|
The return value of this function cannot be relied upon to be
|
||||||
|
consistent between versions of Guile and should not be used in code.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
@deffn {Scheme Procedure} char-set-size cs
|
@deffn {Scheme Procedure} char-set-size cs
|
||||||
@deffnx {C Function} scm_char_set_size (cs)
|
@deffnx {C Function} scm_char_set_size (cs)
|
||||||
Return the number of elements in character set @var{cs}.
|
Return the number of elements in character set @var{cs}.
|
||||||
|
@ -2302,6 +2249,12 @@ must be a character set.
|
||||||
Return the complement of the character set @var{cs}.
|
Return the complement of the character set @var{cs}.
|
||||||
@end deffn
|
@end deffn
|
||||||
|
|
||||||
|
Note that the complement of a character set is likely to contain many
|
||||||
|
reserved code points (code points that are not associated with
|
||||||
|
characters). It may be helpful to modify the output of
|
||||||
|
@code{char-set-complement} by computing its intersection with the set
|
||||||
|
of designated code points, @code{char-set:designated}.
|
||||||
|
|
||||||
@deffn {Scheme Procedure} char-set-union . rest
|
@deffn {Scheme Procedure} char-set-union . rest
|
||||||
@deffnx {C Function} scm_char_set_union (rest)
|
@deffnx {C Function} scm_char_set_union (rest)
|
||||||
Return the union of all argument character sets.
|
Return the union of all argument character sets.
|
||||||
|
@ -2371,12 +2324,10 @@ useful, several predefined character set variables exist.
|
||||||
@cindex charset
|
@cindex charset
|
||||||
@cindex locale
|
@cindex locale
|
||||||
|
|
||||||
Currently, the contents of these character sets are recomputed upon a
|
These character sets are locale independent and are not recomputed
|
||||||
successful @code{setlocale} call (@pxref{Locales}) in order to reflect
|
upon a @code{setlocale} call. They contain characters from the whole
|
||||||
the characters available in the current locale's codeset. For
|
range of Unicode code points. For instance, @code{char-set:letter}
|
||||||
instance, @code{char-set:letter} contains 52 characters under an ASCII
|
contains about 94,000 characters.
|
||||||
locale (e.g., the default @code{C} locale) and 117 characters under an
|
|
||||||
ISO-8859-1 (``Latin-1'') locale.
|
|
||||||
|
|
||||||
@defvr {Scheme Variable} char-set:lower-case
|
@defvr {Scheme Variable} char-set:lower-case
|
||||||
@defvrx {C Variable} scm_char_set_lower_case
|
@defvrx {C Variable} scm_char_set_lower_case
|
||||||
|
@ -2390,13 +2341,16 @@ All upper-case characters.
|
||||||
|
|
||||||
@defvr {Scheme Variable} char-set:title-case
|
@defvr {Scheme Variable} char-set:title-case
|
||||||
@defvrx {C Variable} scm_char_set_title_case
|
@defvrx {C Variable} scm_char_set_title_case
|
||||||
This is empty, because ASCII has no titlecase characters.
|
All single characters that function as if they were an upper-case
|
||||||
|
letter followed by a lower-case letter.
|
||||||
@end defvr
|
@end defvr
|
||||||
|
|
||||||
@defvr {Scheme Variable} char-set:letter
|
@defvr {Scheme Variable} char-set:letter
|
||||||
@defvrx {C Variable} scm_char_set_letter
|
@defvrx {C Variable} scm_char_set_letter
|
||||||
All letters, e.g. the union of @code{char-set:lower-case} and
|
All letters. This includes @code{char-set:lower-case},
|
||||||
@code{char-set:upper-case}.
|
@code{char-set:upper-case}, @code{char-set:title-case}, and many
|
||||||
|
letters that have no case at all. For example, Chinese and Japanese
|
||||||
|
characters typically have no concept of case.
|
||||||
@end defvr
|
@end defvr
|
||||||
|
|
||||||
@defvr {Scheme Variable} char-set:digit
|
@defvr {Scheme Variable} char-set:digit
|
||||||
|
@ -2426,23 +2380,26 @@ All whitespace characters.
|
||||||
|
|
||||||
@defvr {Scheme Variable} char-set:blank
|
@defvr {Scheme Variable} char-set:blank
|
||||||
@defvrx {C Variable} scm_char_set_blank
|
@defvrx {C Variable} scm_char_set_blank
|
||||||
All horizontal whitespace characters, that is @code{#\space} and
|
All horizontal whitespace characters, which notably includes
|
||||||
@code{#\tab}.
|
@code{#\space} and @code{#\tab}.
|
||||||
@end defvr
|
@end defvr
|
||||||
|
|
||||||
@defvr {Scheme Variable} char-set:iso-control
|
@defvr {Scheme Variable} char-set:iso-control
|
||||||
@defvrx {C Variable} scm_char_set_iso_control
|
@defvrx {C Variable} scm_char_set_iso_control
|
||||||
The ISO control characters with the codes 0--31 and 127.
|
The ISO control characters are the C0 control characters (U+0000 to
|
||||||
|
U+001F), delete (U+007F), and the C1 control characters (U+0080 to
|
||||||
|
U+009F).
|
||||||
@end defvr
|
@end defvr
|
||||||
|
|
||||||
@defvr {Scheme Variable} char-set:punctuation
|
@defvr {Scheme Variable} char-set:punctuation
|
||||||
@defvrx {C Variable} scm_char_set_punctuation
|
@defvrx {C Variable} scm_char_set_punctuation
|
||||||
The characters @code{!"#%&'()*,-./:;?@@[\\]_@{@}}
|
All punctuation characters, such as the characters
|
||||||
|
@code{!"#%&'()*,-./:;?@@[\\]_@{@}}
|
||||||
@end defvr
|
@end defvr
|
||||||
|
|
||||||
@defvr {Scheme Variable} char-set:symbol
|
@defvr {Scheme Variable} char-set:symbol
|
||||||
@defvrx {C Variable} scm_char_set_symbol
|
@defvrx {C Variable} scm_char_set_symbol
|
||||||
The characters @code{$+<=>^`|~}.
|
All symbol characters, such as the characters @code{$+<=>^`|~}.
|
||||||
@end defvr
|
@end defvr
|
||||||
|
|
||||||
@defvr {Scheme Variable} char-set:hex-digit
|
@defvr {Scheme Variable} char-set:hex-digit
|
||||||
|
@ -2460,9 +2417,17 @@ All ASCII characters.
|
||||||
The empty character set.
|
The empty character set.
|
||||||
@end defvr
|
@end defvr
|
||||||
|
|
||||||
|
@defvr {Scheme Variable} char-set:designated
|
||||||
|
@defvrx {C Variable} scm_char_set_designated
|
||||||
|
This character set contains all designated code points. This includes
|
||||||
|
all the code points to which Unicode has assigned a character or other
|
||||||
|
meaning.
|
||||||
|
@end defvr
|
||||||
|
|
||||||
@defvr {Scheme Variable} char-set:full
|
@defvr {Scheme Variable} char-set:full
|
||||||
@defvrx {C Variable} scm_char_set_full
|
@defvrx {C Variable} scm_char_set_full
|
||||||
This character set contains all possible characters.
|
This character set contains all possible code points. This includes
|
||||||
|
both designated and reserved code points.
|
||||||
@end defvr
|
@end defvr
|
||||||
|
|
||||||
@node Strings
|
@node Strings
|
||||||
|
@ -2490,7 +2455,7 @@ memory.
|
||||||
|
|
||||||
When one of these two strings is modified, as with @code{string-set!},
|
When one of these two strings is modified, as with @code{string-set!},
|
||||||
their common memory does get copied so that each string has its own
|
their common memory does get copied so that each string has its own
|
||||||
memory and modifying one does not accidently modify the other as well.
|
memory and modifying one does not accidentally modify the other as well.
|
||||||
Thus, Guile's strings are `copy on write'; the actual copying of their
|
Thus, Guile's strings are `copy on write'; the actual copying of their
|
||||||
memory is delayed until one string is written to.
|
memory is delayed until one string is written to.
|
||||||
|
|
||||||
|
@ -2580,6 +2545,14 @@ Vertical tab character (ASCII 11).
|
||||||
@item @nicode{\xHH}
|
@item @nicode{\xHH}
|
||||||
Character code given by two hexadecimal digits. For example
|
Character code given by two hexadecimal digits. For example
|
||||||
@nicode{\x7f} for an ASCII DEL (127).
|
@nicode{\x7f} for an ASCII DEL (127).
|
||||||
|
|
||||||
|
@item @nicode{\uHHHH}
|
||||||
|
Character code given by four hexadecimal digits. For example
|
||||||
|
@nicode{\u0100} for a capital A with macron (U+0100).
|
||||||
|
|
||||||
|
@item @nicode{\UHHHHHH}
|
||||||
|
Character code given by six hexadecimal digits. For example
|
||||||
|
@nicode{\U010402}.
|
||||||
@end table
|
@end table
|
||||||
|
|
||||||
@noindent
|
@noindent
|
||||||
|
@ -2910,7 +2883,7 @@ characters.
|
||||||
@deffnx {C Function} scm_string_trim (s, char_pred, start, end)
|
@deffnx {C Function} scm_string_trim (s, char_pred, start, end)
|
||||||
@deffnx {C Function} scm_string_trim_right (s, char_pred, start, end)
|
@deffnx {C Function} scm_string_trim_right (s, char_pred, start, end)
|
||||||
@deffnx {C Function} scm_string_trim_both (s, char_pred, start, end)
|
@deffnx {C Function} scm_string_trim_both (s, char_pred, start, end)
|
||||||
Trim occurrances of @var{char_pred} from the ends of @var{s}.
|
Trim occurrences of @var{char_pred} from the ends of @var{s}.
|
||||||
|
|
||||||
@code{string-trim} trims @var{char_pred} characters from the left
|
@code{string-trim} trims @var{char_pred} characters from the left
|
||||||
(start) of the string, @code{string-trim-right} trims them from the
|
(start) of the string, @code{string-trim-right} trims them from the
|
||||||
|
@ -3000,9 +2973,14 @@ The procedures in this section are similar to the character ordering
|
||||||
predicates (@pxref{Characters}), but are defined on character sequences.
|
predicates (@pxref{Characters}), but are defined on character sequences.
|
||||||
|
|
||||||
The first set is specified in R5RS and has names that end in @code{?}.
|
The first set is specified in R5RS and has names that end in @code{?}.
|
||||||
The second set is specified in SRFI-13 and the names have no ending
|
The second set is specified in SRFI-13 and the names have not ending
|
||||||
@code{?}. The predicates ending in @code{-ci} ignore the character case
|
@code{?}.
|
||||||
when comparing strings. @xref{Text Collation, the @code{(ice-9
|
|
||||||
|
The predicates ending in @code{-ci} ignore the character case
|
||||||
|
when comparing strings. For now, case-insensitive comparison is done
|
||||||
|
using the R5RS rules, where every lower-case character that has a
|
||||||
|
single character upper-case form is converted to uppercase before
|
||||||
|
comparison. See @xref{Text Collation, the @code{(ice-9
|
||||||
i18n)} module}, for locale-dependent string comparison.
|
i18n)} module}, for locale-dependent string comparison.
|
||||||
|
|
||||||
@rnindex string=?
|
@rnindex string=?
|
||||||
|
@ -3192,14 +3170,14 @@ Compute a hash value for @var{S}. the optional argument @var{bound} is a non-ne
|
||||||
@deffn {Scheme Procedure} string-index s char_pred [start [end]]
|
@deffn {Scheme Procedure} string-index s char_pred [start [end]]
|
||||||
@deffnx {C Function} scm_string_index (s, char_pred, start, end)
|
@deffnx {C Function} scm_string_index (s, char_pred, start, end)
|
||||||
Search through the string @var{s} from left to right, returning
|
Search through the string @var{s} from left to right, returning
|
||||||
the index of the first occurence of a character which
|
the index of the first occurrence of a character which
|
||||||
|
|
||||||
@itemize @bullet
|
@itemize @bullet
|
||||||
@item
|
@item
|
||||||
equals @var{char_pred}, if it is character,
|
equals @var{char_pred}, if it is character,
|
||||||
|
|
||||||
@item
|
@item
|
||||||
satisifies the predicate @var{char_pred}, if it is a procedure,
|
satisfies the predicate @var{char_pred}, if it is a procedure,
|
||||||
|
|
||||||
@item
|
@item
|
||||||
is in the set @var{char_pred}, if it is a character set.
|
is in the set @var{char_pred}, if it is a character set.
|
||||||
|
@ -3209,14 +3187,14 @@ is in the set @var{char_pred}, if it is a character set.
|
||||||
@deffn {Scheme Procedure} string-rindex s char_pred [start [end]]
|
@deffn {Scheme Procedure} string-rindex s char_pred [start [end]]
|
||||||
@deffnx {C Function} scm_string_rindex (s, char_pred, start, end)
|
@deffnx {C Function} scm_string_rindex (s, char_pred, start, end)
|
||||||
Search through the string @var{s} from right to left, returning
|
Search through the string @var{s} from right to left, returning
|
||||||
the index of the last occurence of a character which
|
the index of the last occurrence of a character which
|
||||||
|
|
||||||
@itemize @bullet
|
@itemize @bullet
|
||||||
@item
|
@item
|
||||||
equals @var{char_pred}, if it is character,
|
equals @var{char_pred}, if it is character,
|
||||||
|
|
||||||
@item
|
@item
|
||||||
satisifies the predicate @var{char_pred}, if it is a procedure,
|
satisfies the predicate @var{char_pred}, if it is a procedure,
|
||||||
|
|
||||||
@item
|
@item
|
||||||
is in the set if @var{char_pred} is a character set.
|
is in the set if @var{char_pred} is a character set.
|
||||||
|
@ -3270,14 +3248,14 @@ Is @var{s1} a suffix of @var{s2}, ignoring character case?
|
||||||
@deffn {Scheme Procedure} string-index-right s char_pred [start [end]]
|
@deffn {Scheme Procedure} string-index-right s char_pred [start [end]]
|
||||||
@deffnx {C Function} scm_string_index_right (s, char_pred, start, end)
|
@deffnx {C Function} scm_string_index_right (s, char_pred, start, end)
|
||||||
Search through the string @var{s} from right to left, returning
|
Search through the string @var{s} from right to left, returning
|
||||||
the index of the last occurence of a character which
|
the index of the last occurrence of a character which
|
||||||
|
|
||||||
@itemize @bullet
|
@itemize @bullet
|
||||||
@item
|
@item
|
||||||
equals @var{char_pred}, if it is character,
|
equals @var{char_pred}, if it is character,
|
||||||
|
|
||||||
@item
|
@item
|
||||||
satisifies the predicate @var{char_pred}, if it is a procedure,
|
satisfies the predicate @var{char_pred}, if it is a procedure,
|
||||||
|
|
||||||
@item
|
@item
|
||||||
is in the set if @var{char_pred} is a character set.
|
is in the set if @var{char_pred} is a character set.
|
||||||
|
@ -3287,14 +3265,14 @@ is in the set if @var{char_pred} is a character set.
|
||||||
@deffn {Scheme Procedure} string-skip s char_pred [start [end]]
|
@deffn {Scheme Procedure} string-skip s char_pred [start [end]]
|
||||||
@deffnx {C Function} scm_string_skip (s, char_pred, start, end)
|
@deffnx {C Function} scm_string_skip (s, char_pred, start, end)
|
||||||
Search through the string @var{s} from left to right, returning
|
Search through the string @var{s} from left to right, returning
|
||||||
the index of the first occurence of a character which
|
the index of the first occurrence of a character which
|
||||||
|
|
||||||
@itemize @bullet
|
@itemize @bullet
|
||||||
@item
|
@item
|
||||||
does not equal @var{char_pred}, if it is character,
|
does not equal @var{char_pred}, if it is character,
|
||||||
|
|
||||||
@item
|
@item
|
||||||
does not satisify the predicate @var{char_pred}, if it is a
|
does not satisfy the predicate @var{char_pred}, if it is a
|
||||||
procedure,
|
procedure,
|
||||||
|
|
||||||
@item
|
@item
|
||||||
|
@ -3305,7 +3283,7 @@ is not in the set if @var{char_pred} is a character set.
|
||||||
@deffn {Scheme Procedure} string-skip-right s char_pred [start [end]]
|
@deffn {Scheme Procedure} string-skip-right s char_pred [start [end]]
|
||||||
@deffnx {C Function} scm_string_skip_right (s, char_pred, start, end)
|
@deffnx {C Function} scm_string_skip_right (s, char_pred, start, end)
|
||||||
Search through the string @var{s} from right to left, returning
|
Search through the string @var{s} from right to left, returning
|
||||||
the index of the last occurence of a character which
|
the index of the last occurrence of a character which
|
||||||
|
|
||||||
@itemize @bullet
|
@itemize @bullet
|
||||||
@item
|
@item
|
||||||
|
@ -3330,7 +3308,7 @@ Return the count of the number of characters in the string
|
||||||
equals @var{char_pred}, if it is character,
|
equals @var{char_pred}, if it is character,
|
||||||
|
|
||||||
@item
|
@item
|
||||||
satisifies the predicate @var{char_pred}, if it is a procedure.
|
satisfies the predicate @var{char_pred}, if it is a procedure.
|
||||||
|
|
||||||
@item
|
@item
|
||||||
is in the set @var{char_pred}, if it is a character set.
|
is in the set @var{char_pred}, if it is a character set.
|
||||||
|
|
|
@ -1708,7 +1708,7 @@ facilities just described.
|
||||||
A good way to explore in detail what a Scheme procedure does is to set
|
A good way to explore in detail what a Scheme procedure does is to set
|
||||||
a trap on it and then single step through what it does. To do this,
|
a trap on it and then single step through what it does. To do this,
|
||||||
make and install a @code{<procedure-trap>} with the @code{debug-trap}
|
make and install a @code{<procedure-trap>} with the @code{debug-trap}
|
||||||
behaviour from @code{(ice-9 debugging ice-9-debugger-extensions)}.
|
behaviour from @code{(ice-9 debugger)}.
|
||||||
|
|
||||||
The following sample session illustrates this. It assumes that the
|
The following sample session illustrates this. It assumes that the
|
||||||
file @file{matrix.scm} defines a procedure @code{mkmatrix}, which is
|
file @file{matrix.scm} defines a procedure @code{mkmatrix}, which is
|
||||||
|
@ -1718,7 +1718,6 @@ calls @code{mkmatrix}.
|
||||||
@lisp
|
@lisp
|
||||||
$ /usr/bin/guile -q
|
$ /usr/bin/guile -q
|
||||||
guile> (use-modules (ice-9 debugger)
|
guile> (use-modules (ice-9 debugger)
|
||||||
(ice-9 debugging ice-9-debugger-extensions)
|
|
||||||
(ice-9 debugging traps))
|
(ice-9 debugging traps))
|
||||||
guile> (load "matrix.scm")
|
guile> (load "matrix.scm")
|
||||||
guile> (install-trap (make <procedure-trap>
|
guile> (install-trap (make <procedure-trap>
|
||||||
|
@ -1758,10 +1757,9 @@ guile>
|
||||||
|
|
||||||
Or you can use Guile's Emacs interface (GDS), by using the module
|
Or you can use Guile's Emacs interface (GDS), by using the module
|
||||||
@code{(ice-9 gds-client)} instead of @code{(ice-9 debugger)} and
|
@code{(ice-9 gds-client)} instead of @code{(ice-9 debugger)} and
|
||||||
@code{(ice-9 debugging ice-9-debugger-extensions)}, and changing
|
changing @code{debug-trap} to @code{gds-debug-trap}. Then the stack and
|
||||||
@code{debug-trap} to @code{gds-debug-trap}. Then the stack and
|
corresponding source locations are displayed in Emacs instead of on the
|
||||||
corresponding source locations are displayed in Emacs instead of on
|
Guile command line.
|
||||||
the Guile command line.
|
|
||||||
|
|
||||||
|
|
||||||
@node Profiling or Tracing a Procedure's Code
|
@node Profiling or Tracing a Procedure's Code
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
@c -*-texinfo-*-
|
@c -*-texinfo-*-
|
||||||
@c This is part of the GNU Guile Reference Manual.
|
@c This is part of the GNU Guile Reference Manual.
|
||||||
@c Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004, 2005, 2006
|
@c Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2009
|
||||||
@c Free Software Foundation, Inc.
|
@c Free Software Foundation, Inc.
|
||||||
@c See the file guile.texi for copying conditions.
|
@c See the file guile.texi for copying conditions.
|
||||||
|
|
||||||
|
@ -17,6 +17,7 @@ loading, evaluating, and compiling Scheme code at run time.
|
||||||
* Fly Evaluation:: Procedures for on the fly evaluation.
|
* Fly Evaluation:: Procedures for on the fly evaluation.
|
||||||
* Compilation:: How to compile Scheme files and procedures.
|
* Compilation:: How to compile Scheme files and procedures.
|
||||||
* Loading:: Loading Scheme code from file.
|
* Loading:: Loading Scheme code from file.
|
||||||
|
* Character Encoding of Source Files:: Loading non-ASCII Scheme code from file.
|
||||||
* Delayed Evaluation:: Postponing evaluation until it is needed.
|
* Delayed Evaluation:: Postponing evaluation until it is needed.
|
||||||
* Local Evaluation:: Evaluation in a local environment.
|
* Local Evaluation:: Evaluation in a local environment.
|
||||||
* Evaluator Behaviour:: Modifying Guile's evaluator.
|
* Evaluator Behaviour:: Modifying Guile's evaluator.
|
||||||
|
@ -229,6 +230,27 @@ Thus a Guile script often starts like this.
|
||||||
More details on Guile scripting can be found in the scripting section
|
More details on Guile scripting can be found in the scripting section
|
||||||
(@pxref{Guile Scripting}).
|
(@pxref{Guile Scripting}).
|
||||||
|
|
||||||
|
@cindex R6RS block comments
|
||||||
|
@cindex SRFI-30 block comments
|
||||||
|
Similarly, Guile (starting from version 2.0) supports nested block
|
||||||
|
comments as specified by R6RS and
|
||||||
|
@url{http://srfi.schemers.org/srfi-30/srfi-30.html, SRFI-30}:
|
||||||
|
|
||||||
|
@lisp
|
||||||
|
(+ #| this is a #| nested |# block comment |# 2)
|
||||||
|
@result{} 3
|
||||||
|
@end lisp
|
||||||
|
|
||||||
|
For backward compatibility, this syntax can be overridden with
|
||||||
|
@code{read-hash-extend} (@pxref{Reader Extensions,
|
||||||
|
@code{read-hash-extend}}).
|
||||||
|
|
||||||
|
There is one special case where the contents of a comment can actually
|
||||||
|
affect the interpretation of code. When a character encoding
|
||||||
|
declaration, such as @code{coding: utf-8} appears in one of the first
|
||||||
|
few lines of a source file, it indicates to Guile's default reader
|
||||||
|
that this source code file is not ASCII. For details see @ref{Character
|
||||||
|
Encoding of Source Files}.
|
||||||
|
|
||||||
@node Case Sensitivity
|
@node Case Sensitivity
|
||||||
@subsubsection Case Sensitivity
|
@subsubsection Case Sensitivity
|
||||||
|
@ -531,13 +553,20 @@ documentation for @code{%load-hook} later in this section.
|
||||||
@code{SCM}.
|
@code{SCM}.
|
||||||
@end deftypefn
|
@end deftypefn
|
||||||
|
|
||||||
@deffn {Scheme Procedure} primitive-load-path filename
|
@deffn {Scheme Procedure} primitive-load-path filename [exception-on-not-found]
|
||||||
@deffnx {C Function} scm_primitive_load_path (filename)
|
@deffnx {C Function} scm_primitive_load_path (filename)
|
||||||
Search @code{%load-path} for the file named @var{filename} and
|
Search @code{%load-path} for the file named @var{filename} and
|
||||||
load it into the top-level environment. If @var{filename} is a
|
load it into the top-level environment. If @var{filename} is a
|
||||||
relative pathname and is not found in the list of search paths,
|
relative pathname and is not found in the list of search paths,
|
||||||
an error is signalled. Preferentially loads a compiled version of the
|
an error is signalled. Preferentially loads a compiled version of the
|
||||||
file, if it is available and up-to-date.
|
file, if it is available and up-to-date.
|
||||||
|
|
||||||
|
By default or if @var{exception-on-not-found} is true, an exception is
|
||||||
|
raised if @var{filename} is not found. If @var{exception-on-not-found}
|
||||||
|
is @code{#f} and @var{filename} is not found, no exception is raised and
|
||||||
|
@code{#f} is returned. For compatibility with Guile 1.8 and earlier,
|
||||||
|
the C function takes only one argument, which can be either a string
|
||||||
|
(the file name) or an argument list.
|
||||||
@end deffn
|
@end deffn
|
||||||
|
|
||||||
@deffn {Scheme Procedure} %search-load-path filename
|
@deffn {Scheme Procedure} %search-load-path filename
|
||||||
|
@ -558,6 +587,21 @@ that they are loading). @code{current-reader} is a fluid, so it has an
|
||||||
independent value in each dynamic root and should be read and set using
|
independent value in each dynamic root and should be read and set using
|
||||||
@code{fluid-ref} and @code{fluid-set!} (@pxref{Fluids and Dynamic
|
@code{fluid-ref} and @code{fluid-set!} (@pxref{Fluids and Dynamic
|
||||||
States}).
|
States}).
|
||||||
|
|
||||||
|
Changing @code{current-reader} is typically useful to introduce local
|
||||||
|
syntactic changes, such that code following the @code{fluid-set!} call
|
||||||
|
is read using the newly installed reader. The @code{current-reader}
|
||||||
|
change should take place at evaluation time when the code is evaluated,
|
||||||
|
or at compilation time when the code is compiled:
|
||||||
|
|
||||||
|
@findex eval-when
|
||||||
|
@example
|
||||||
|
(eval-when (compile eval)
|
||||||
|
(fluid-set! current-reader my-own-reader))
|
||||||
|
@end example
|
||||||
|
|
||||||
|
The @code{eval-when} form above ensures that the @code{current-reader}
|
||||||
|
change occurs at the right time.
|
||||||
@end defvar
|
@end defvar
|
||||||
|
|
||||||
@defvar %load-hook
|
@defvar %load-hook
|
||||||
|
@ -590,6 +634,82 @@ a file to load. By default, @code{%load-extensions} is bound to the
|
||||||
list @code{("" ".scm")}.
|
list @code{("" ".scm")}.
|
||||||
@end defvar
|
@end defvar
|
||||||
|
|
||||||
|
@node Character Encoding of Source Files
|
||||||
|
@subsection Character Encoding of Source Files
|
||||||
|
|
||||||
|
@cindex source file encoding
|
||||||
|
@cindex primitive-load
|
||||||
|
@cindex load
|
||||||
|
Scheme source code files are usually encoded in ASCII, but, the
|
||||||
|
built-in reader can interpret other character encodings. The
|
||||||
|
procedure @code{primitive-load}, and by extension the functions that
|
||||||
|
call it, such as @code{load}, first scan the top 500 characters of the
|
||||||
|
file for a coding declaration.
|
||||||
|
|
||||||
|
A coding declaration has the form @code{coding: XXXXXX}, where
|
||||||
|
@code{XXXXXX} is the name of a character encoding in which the source
|
||||||
|
code file has been encoded. The coding declaration must appear in a
|
||||||
|
scheme comment. It can either be a semicolon-initiated comment or a block
|
||||||
|
@code{#!} comment.
|
||||||
|
|
||||||
|
The name of the character encoding in the coding declaration is
|
||||||
|
typically lower case and containing only letters, numbers, and hyphens,
|
||||||
|
as recognized by @code{set-port-encoding!} (@pxref{Ports,
|
||||||
|
@code{set-port-encoding!}}). Common examples of character encoding
|
||||||
|
names are @code{utf-8} and @code{iso-8859-1},
|
||||||
|
@url{http://www.iana.org/assignments/character-sets, as defined by
|
||||||
|
IANA}. Thus, the coding declaration is mostly compatible with Emacs.
|
||||||
|
|
||||||
|
However, there are some differences in encoding names recognized by
|
||||||
|
Emacs and encoding names defined by IANA, the latter being essentially a
|
||||||
|
subset of the former. For instance, @code{latin-1} is a valid encoding
|
||||||
|
name for Emacs, but it's not according to the IANA standard, which Guile
|
||||||
|
follows; instead, you should use @code{iso-8859-1}, which is both
|
||||||
|
understood by Emacs and dubbed by IANA (IANA writes it uppercase but
|
||||||
|
Emacs wants it lowercase and Guile is case insensitive.)
|
||||||
|
|
||||||
|
For source code, only a subset of all possible character encodings can
|
||||||
|
be interpreted by the built-in source code reader. Only those
|
||||||
|
character encodings in which ASCII text appears unmodified can be
|
||||||
|
used. This includes @code{UTF-8} and @code{ISO-8859-1} through
|
||||||
|
@code{ISO-8859-15}. The multi-byte character encodings @code{UTF-16}
|
||||||
|
and @code{UTF-32} may not be used because they are not compatible with
|
||||||
|
ASCII.
|
||||||
|
|
||||||
|
@cindex read
|
||||||
|
@cindex encoding
|
||||||
|
@cindex port encoding
|
||||||
|
@findex set-port-encoding!
|
||||||
|
There might be a scenario in which one would want to read non-ASCII
|
||||||
|
code from a port, such as with the function @code{read}, instead of
|
||||||
|
with @code{load}. If the port's character encoding is the same as the
|
||||||
|
encoding of the code to be read by the port, not other special
|
||||||
|
handling is necessary. The port will automatically do the character
|
||||||
|
encoding conversion. The functions @code{setlocale} or by
|
||||||
|
@code{set-port-encoding!} are used to set port encodings
|
||||||
|
(@pxref{Ports}).
|
||||||
|
|
||||||
|
If a port is used to read code of unknown character encoding, it can
|
||||||
|
accomplish this in three steps. First, the character encoding of the
|
||||||
|
port should be set to ISO-8859-1 using @code{set-port-encoding!}.
|
||||||
|
Then, the procedure @code{file-encoding}, described below, is used to
|
||||||
|
scan for a coding declaration when reading from the port. As a side
|
||||||
|
effect, it rewinds the port after its scan is complete. After that,
|
||||||
|
the port's character encoding should be set to the encoding returned
|
||||||
|
by @code{file-encoding}, if any, again by using
|
||||||
|
@code{set-port-encoding!}. Then the code can be read as normal.
|
||||||
|
|
||||||
|
@deffn {Scheme Procedure} file-encoding port
|
||||||
|
@deffnx {C Function} scm_file_encoding port
|
||||||
|
Scan the port for an Emacs-like character coding declaration near the
|
||||||
|
top of the contents of a port with random-accessible contents
|
||||||
|
(@pxref{Recognize Coding, how Emacs recognizes file encoding,, emacs,
|
||||||
|
The GNU Emacs Reference Manual}). The coding declaration is of the form
|
||||||
|
@code{coding: XXXXX} and must appear in a Scheme comment. Return a
|
||||||
|
string containing the character encoding of the file if a declaration
|
||||||
|
was found, or @code{#f} otherwise. The port is rewound.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
|
||||||
@node Delayed Evaluation
|
@node Delayed Evaluation
|
||||||
@subsection Delayed Evaluation
|
@subsection Delayed Evaluation
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
@c -*-texinfo-*-
|
@c -*-texinfo-*-
|
||||||
@c This is part of the GNU Guile Reference Manual.
|
@c This is part of the GNU Guile Reference Manual.
|
||||||
@c Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004, 2006, 2007
|
@c Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004, 2006, 2007, 2009
|
||||||
@c Free Software Foundation, Inc.
|
@c Free Software Foundation, Inc.
|
||||||
@c See the file guile.texi for copying conditions.
|
@c See the file guile.texi for copying conditions.
|
||||||
|
|
||||||
|
@ -39,12 +39,6 @@ In order to make use of the functions described thereafter, the
|
||||||
(use-modules (ice-9 i18n))
|
(use-modules (ice-9 i18n))
|
||||||
@end example
|
@end example
|
||||||
|
|
||||||
@cindex libguile-i18n-v-@value{LIBGUILE_I18N_MAJOR}
|
|
||||||
|
|
||||||
C programs can use the C functions corresponding to the procedures of
|
|
||||||
this module by including @code{<libguile/i18n.h>} and by linking
|
|
||||||
against @code{libguile-i18n-v-@value{LIBGUILE_I18N_MAJOR}}.
|
|
||||||
|
|
||||||
@cindex cultural conventions
|
@cindex cultural conventions
|
||||||
|
|
||||||
The @code{(ice-9 i18n)} module provides procedures to manipulate text
|
The @code{(ice-9 i18n)} module provides procedures to manipulate text
|
||||||
|
|
|
@ -47,7 +47,7 @@ are two interesting and powerful examples of this technique.
|
||||||
|
|
||||||
Ports are garbage collected in the usual way (@pxref{Memory
|
Ports are garbage collected in the usual way (@pxref{Memory
|
||||||
Management}), and will be closed at that time if not already closed.
|
Management}), and will be closed at that time if not already closed.
|
||||||
In this case any errors occuring in the close will not be reported.
|
In this case any errors occurring in the close will not be reported.
|
||||||
Usually a program will want to explicitly close so as to be sure all
|
Usually a program will want to explicitly close so as to be sure all
|
||||||
its operations have been successful. Of course if a program has
|
its operations have been successful. Of course if a program has
|
||||||
abandoned something due to an error or other condition then closing
|
abandoned something due to an error or other condition then closing
|
||||||
|
@ -70,6 +70,18 @@ All file access uses the ``LFS'' large file support functions when
|
||||||
available, so files bigger than 2 Gbytes (@math{2^31} bytes) can be
|
available, so files bigger than 2 Gbytes (@math{2^31} bytes) can be
|
||||||
read and written on a 32-bit system.
|
read and written on a 32-bit system.
|
||||||
|
|
||||||
|
Each port has an associated character encoding that controls how bytes
|
||||||
|
read from the port are converted to characters and string and controls
|
||||||
|
how characters and strings written to the port are converted to bytes.
|
||||||
|
When ports are created, they inherit their character encoding from the
|
||||||
|
current locale, but, that can be modified after the port is created.
|
||||||
|
|
||||||
|
Each port also has an associated conversion strategy: what to do when
|
||||||
|
a Guile character can't be converted to the port's encoded character
|
||||||
|
representation for output. There are three possible strategies: to
|
||||||
|
raise an error, to replace the character with a hex escape, or to
|
||||||
|
replace the character with a substitute character.
|
||||||
|
|
||||||
@rnindex input-port?
|
@rnindex input-port?
|
||||||
@deffn {Scheme Procedure} input-port? x
|
@deffn {Scheme Procedure} input-port? x
|
||||||
@deffnx {C Function} scm_input_port_p (x)
|
@deffnx {C Function} scm_input_port_p (x)
|
||||||
|
@ -93,6 +105,63 @@ Equivalent to @code{(or (input-port? @var{x}) (output-port?
|
||||||
@var{x}))}.
|
@var{x}))}.
|
||||||
@end deffn
|
@end deffn
|
||||||
|
|
||||||
|
@deffn {Scheme Procedure} set-port-encoding! port enc
|
||||||
|
@deffnx {C Function} scm_set_port_encoding_x (port, enc)
|
||||||
|
Sets the character encoding that will be used to interpret all port I/O.
|
||||||
|
@var{enc} is a string containing the name of an encoding. Valid
|
||||||
|
encoding names are those
|
||||||
|
@url{http://www.iana.org/assignments/character-sets, defined by IANA}.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@defvr {Scheme Variable} %default-port-encoding
|
||||||
|
A fluid containing containing @code{#f} or the name of the encoding to
|
||||||
|
be used by default for newly created ports (@pxref{Fluids and Dynamic
|
||||||
|
States}). The value @code{#f} is equivalent to @code{"ISO-8859-1"}.
|
||||||
|
|
||||||
|
New ports are created with the encoding appropriate for the current
|
||||||
|
locale if @code{setlocale} has been called or the value specified by
|
||||||
|
this fluid otherwise.
|
||||||
|
@end defvr
|
||||||
|
|
||||||
|
@deffn {Scheme Procedure} port-encoding port
|
||||||
|
@deffnx {C Function} scm_port_encoding
|
||||||
|
Returns, as a string, the character encoding that @var{port} uses to
|
||||||
|
interpret its input and output.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@deffn {Scheme Procedure} set-port-conversion-strategy! port sym
|
||||||
|
@deffnx {C Function} scm_set_port_conversion_strategy_x (port, sym)
|
||||||
|
Sets the behavior of the interpreter when outputting a character that
|
||||||
|
is not representable in the port's current encoding. @var{sym} can be
|
||||||
|
either @code{'error}, @code{'substitute}, or @code{'escape}. If it is
|
||||||
|
@code{'error}, an error will be thrown when an nonconvertible character
|
||||||
|
is encountered. If it is @code{'substitute}, then nonconvertible
|
||||||
|
characters will be replaced with approximate characters, or with
|
||||||
|
question marks if no approximately correct character is available. If
|
||||||
|
it is @code{'escape}, it will appear as a hex escape when output.
|
||||||
|
|
||||||
|
If @var{port} is an open port, the conversion error behavior
|
||||||
|
is set for that port. If it is @code{#f}, it is set as the
|
||||||
|
default behavior for any future ports that get created in
|
||||||
|
this thread.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@deffn {Scheme Procedure} port-conversion-strategy port
|
||||||
|
@deffnx {C Function} scm_port_conversion_strategy (port)
|
||||||
|
Returns the behavior of the port when outputting a character that is
|
||||||
|
not representable in the port's current encoding. It returns the
|
||||||
|
symbol @code{error} if unrepresentable characters should cause
|
||||||
|
exceptions, @code{substitute} if the port should try to replace
|
||||||
|
unrepresentable characters with question marks or approximate
|
||||||
|
characters, or @code{escape} if unrepresentable characters should be
|
||||||
|
converted to string escapes.
|
||||||
|
|
||||||
|
If @var{port} is @code{#f}, then the current default behavior will be
|
||||||
|
returned. New ports will have this default behavior when they are
|
||||||
|
created.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@node Reading
|
@node Reading
|
||||||
@subsection Reading
|
@subsection Reading
|
||||||
|
@ -238,7 +307,7 @@ output port if not given.
|
||||||
|
|
||||||
The output is designed to be machine readable, and can be read back
|
The output is designed to be machine readable, and can be read back
|
||||||
with @code{read} (@pxref{Reading}). Strings are printed in
|
with @code{read} (@pxref{Reading}). Strings are printed in
|
||||||
doublequotes, with escapes if necessary, and characters are printed in
|
double quotes, with escapes if necessary, and characters are printed in
|
||||||
@samp{#\} notation.
|
@samp{#\} notation.
|
||||||
@end deffn
|
@end deffn
|
||||||
|
|
||||||
|
@ -248,7 +317,7 @@ Send a representation of @var{obj} to @var{port} or to the current
|
||||||
output port if not given.
|
output port if not given.
|
||||||
|
|
||||||
The output is designed for human readability, it differs from
|
The output is designed for human readability, it differs from
|
||||||
@code{write} in that strings are printed without doublequotes and
|
@code{write} in that strings are printed without double quotes and
|
||||||
escapes, and characters are printed as per @code{write-char}, not in
|
escapes, and characters are printed as per @code{write-char}, not in
|
||||||
@samp{#\} form.
|
@samp{#\} form.
|
||||||
@end deffn
|
@end deffn
|
||||||
|
@ -496,7 +565,7 @@ used. This function is equivalent to:
|
||||||
@end lisp
|
@end lisp
|
||||||
@end deffn
|
@end deffn
|
||||||
|
|
||||||
Some of the abovementioned I/O functions rely on the following C
|
Some of the aforementioned I/O functions rely on the following C
|
||||||
primitives. These will mainly be of interest to people hacking Guile
|
primitives. These will mainly be of interest to people hacking Guile
|
||||||
internals.
|
internals.
|
||||||
|
|
||||||
|
@ -815,11 +884,11 @@ Open @var{filename} for output. Equivalent to
|
||||||
Open @var{filename} for input or output, and call @code{(@var{proc}
|
Open @var{filename} for input or output, and call @code{(@var{proc}
|
||||||
port)} with the resulting port. Return the value returned by
|
port)} with the resulting port. Return the value returned by
|
||||||
@var{proc}. @var{filename} is opened as per @code{open-input-file} or
|
@var{proc}. @var{filename} is opened as per @code{open-input-file} or
|
||||||
@code{open-output-file} respectively, and an error is signalled if it
|
@code{open-output-file} respectively, and an error is signaled if it
|
||||||
cannot be opened.
|
cannot be opened.
|
||||||
|
|
||||||
When @var{proc} returns, the port is closed. If @var{proc} does not
|
When @var{proc} returns, the port is closed. If @var{proc} does not
|
||||||
return (eg.@: if it throws an error), then the port might not be
|
return (e.g.@: if it throws an error), then the port might not be
|
||||||
closed automatically, though it will be garbage collected in the usual
|
closed automatically, though it will be garbage collected in the usual
|
||||||
way if not otherwise referenced.
|
way if not otherwise referenced.
|
||||||
@end deffn
|
@end deffn
|
||||||
|
@ -834,7 +903,7 @@ setup as respectively the @code{current-input-port},
|
||||||
@code{current-output-port}, or @code{current-error-port}. Return the
|
@code{current-output-port}, or @code{current-error-port}. Return the
|
||||||
value returned by @var{thunk}. @var{filename} is opened as per
|
value returned by @var{thunk}. @var{filename} is opened as per
|
||||||
@code{open-input-file} or @code{open-output-file} respectively, and an
|
@code{open-input-file} or @code{open-output-file} respectively, and an
|
||||||
error is signalled if it cannot be opened.
|
error is signaled if it cannot be opened.
|
||||||
|
|
||||||
When @var{thunk} returns, the port is closed and the previous setting
|
When @var{thunk} returns, the port is closed and the previous setting
|
||||||
of the respective current port is restored.
|
of the respective current port is restored.
|
||||||
|
@ -891,6 +960,13 @@ Determine whether @var{obj} is a port that is related to a file.
|
||||||
The following allow string ports to be opened by analogy to R4R*
|
The following allow string ports to be opened by analogy to R4R*
|
||||||
file port facilities:
|
file port facilities:
|
||||||
|
|
||||||
|
With string ports, the port-encoding is treated differently than other
|
||||||
|
types of ports. When string ports are created, they do not inherit a
|
||||||
|
character encoding from the current locale. They are given a
|
||||||
|
default locale that allows them to handle all valid string characters.
|
||||||
|
Typically one should not modify a string port's character encoding
|
||||||
|
away from its default.
|
||||||
|
|
||||||
@deffn {Scheme Procedure} call-with-output-string proc
|
@deffn {Scheme Procedure} call-with-output-string proc
|
||||||
@deffnx {C Function} scm_call_with_output_string (proc)
|
@deffnx {C Function} scm_call_with_output_string (proc)
|
||||||
Calls the one-argument procedure @var{proc} with a newly created output
|
Calls the one-argument procedure @var{proc} with a newly created output
|
||||||
|
@ -1409,7 +1485,7 @@ is set.
|
||||||
|
|
||||||
@node Port Implementation
|
@node Port Implementation
|
||||||
@subsubsection Port Implementation
|
@subsubsection Port Implementation
|
||||||
@cindex Port implemenation
|
@cindex Port implementation
|
||||||
|
|
||||||
This section describes how to implement a new port type in C.
|
This section describes how to implement a new port type in C.
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
@c -*-texinfo-*-
|
@c -*-texinfo-*-
|
||||||
@c This is part of the GNU Guile Reference Manual.
|
@c This is part of the GNU Guile Reference Manual.
|
||||||
@c Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004
|
@c Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004, 2009
|
||||||
@c Free Software Foundation, Inc.
|
@c Free Software Foundation, Inc.
|
||||||
@c See the file guile.texi for copying conditions.
|
@c See the file guile.texi for copying conditions.
|
||||||
|
|
||||||
|
@ -41,6 +41,11 @@ otherwise might be. When you are done with the object, call
|
||||||
the object remains protected until it has been unprotected as many times
|
the object remains protected until it has been unprotected as many times
|
||||||
as it was protected. It is an error to unprotect an object more times
|
as it was protected. It is an error to unprotect an object more times
|
||||||
than it has been protected. Returns the SCM object it was passed.
|
than it has been protected. Returns the SCM object it was passed.
|
||||||
|
|
||||||
|
Note that storing @var{obj} in a C global variable has the same
|
||||||
|
effect@footnote{In Guile up to version 1.8, C global variables were not
|
||||||
|
scanned by the garbage collector; hence, @code{scm_gc_protect_object}
|
||||||
|
was the only way in C to prevent a Scheme object from being freed.}.
|
||||||
@end deftypefn
|
@end deftypefn
|
||||||
|
|
||||||
@deftypefn {C Function} SCM scm_gc_unprotect_object (SCM @var{obj})
|
@deftypefn {C Function} SCM scm_gc_unprotect_object (SCM @var{obj})
|
||||||
|
@ -98,38 +103,52 @@ typically from a smob @emph{mark} function.
|
||||||
@node Memory Blocks
|
@node Memory Blocks
|
||||||
@subsection Memory Blocks
|
@subsection Memory Blocks
|
||||||
|
|
||||||
|
@cindex automatically-managed memory
|
||||||
|
@cindex GC-managed memory
|
||||||
|
@cindex conservative garbage collection
|
||||||
|
|
||||||
In C programs, dynamic management of memory blocks is normally done
|
In C programs, dynamic management of memory blocks is normally done
|
||||||
with the functions malloc, realloc, and free. Guile has additional
|
with the functions malloc, realloc, and free. Guile has additional
|
||||||
functions for dynamic memory allocation that are integrated into the
|
functions for dynamic memory allocation that are integrated into the
|
||||||
garbage collector and the error reporting system.
|
garbage collector and the error reporting system.
|
||||||
|
|
||||||
Memory blocks that are associated with Scheme objects (for example a
|
Memory blocks that are associated with Scheme objects (for example a
|
||||||
smob) should be allocated and freed with @code{scm_gc_malloc} and
|
smob) should be allocated with @code{scm_gc_malloc} or
|
||||||
@code{scm_gc_free}. The function @code{scm_gc_malloc} will either
|
@code{scm_gc_malloc_pointerless}. These two functions will either
|
||||||
return a valid pointer or signal an error. It will also assume that
|
return a valid pointer or signal an error. Memory blocks allocated this
|
||||||
the new memory can be freed by a garbage collection. The garbage
|
way can be freed with @code{scm_gc_free}; however, this is not strictly
|
||||||
collector uses this information to decide when to try to actually
|
needed: memory allocated with @code{scm_gc_malloc} or
|
||||||
collect some garbage. Memory blocks allocated with
|
@code{scm_gc_malloc_pointerless} is automatically reclaimed when the
|
||||||
@code{scm_gc_malloc} must be freed with @code{scm_gc_free}.
|
garbage collector no longer sees any live reference to it@footnote{In
|
||||||
|
Guile up to version 1.8, memory allocated with @code{scm_gc_malloc}
|
||||||
|
@emph{had} to be freed with @code{scm_gc_free}.}.
|
||||||
|
|
||||||
|
Memory allocated with @code{scm_gc_malloc} is scanned for live pointers.
|
||||||
|
This means that if @code{scm_gc_malloc}-allocated memory contains a
|
||||||
|
pointer to some other part of the memory, the garbage collector notices
|
||||||
|
it and prevents it from being reclaimed@footnote{In Guile up to 1.8,
|
||||||
|
memory allocated with @code{scm_gc_malloc} was @emph{not} scanned.
|
||||||
|
Consequently, the GC had to be told explicitly about pointers to live
|
||||||
|
objects contained in the memory block, e.g., @i{via} SMOB mark functions
|
||||||
|
(@pxref{Smobs, @code{scm_set_smob_mark}})}. Conversely, memory
|
||||||
|
allocated with @code{scm_gc_malloc_pointerless} is assumed to be
|
||||||
|
``pointer-less'' and is not scanned.
|
||||||
|
|
||||||
For memory that is not associated with a Scheme object, you can use
|
For memory that is not associated with a Scheme object, you can use
|
||||||
@code{scm_malloc} instead of @code{malloc}. Like
|
@code{scm_malloc} instead of @code{malloc}. Like
|
||||||
@code{scm_gc_malloc}, it will either return a valid pointer or signal
|
@code{scm_gc_malloc}, it will either return a valid pointer or signal
|
||||||
an error. However, it will not assume that the new memory block can
|
an error. However, it will not assume that the new memory block can
|
||||||
be freed by a garbage collection. The memory can be freed with
|
be freed by a garbage collection. The memory must be explicitly freed
|
||||||
@code{free}.
|
with @code{free}.
|
||||||
|
|
||||||
There is also @code{scm_gc_realloc} and @code{scm_realloc}, to be used
|
There is also @code{scm_gc_realloc} and @code{scm_realloc}, to be used
|
||||||
in place of @code{realloc} when appropriate, and @code{scm_gc_calloc}
|
in place of @code{realloc} when appropriate, and @code{scm_gc_calloc}
|
||||||
and @code{scm_calloc}, to be used in place of @code{calloc} when
|
and @code{scm_calloc}, to be used in place of @code{calloc} when
|
||||||
appropriate.
|
appropriate.
|
||||||
|
|
||||||
The function @code{scm_dynwind_free} can be useful when memory should
|
The function @code{scm_dynwind_free} can be useful when memory should be
|
||||||
be freed when a dynwind context, @xref{Dynamic Wind}.
|
freed with libc's @code{free} when leaving a dynwind context,
|
||||||
|
@xref{Dynamic Wind}.
|
||||||
For really specialized needs, take at look at
|
|
||||||
@code{scm_gc_register_collectable_memory} and
|
|
||||||
@code{scm_gc_unregister_collectable_memory}.
|
|
||||||
|
|
||||||
@deftypefn {C Function} {void *} scm_malloc (size_t @var{size})
|
@deftypefn {C Function} {void *} scm_malloc (size_t @var{size})
|
||||||
@deftypefnx {C Function} {void *} scm_calloc (size_t @var{size})
|
@deftypefnx {C Function} {void *} scm_calloc (size_t @var{size})
|
||||||
|
@ -161,6 +180,36 @@ runs the GC to free up some memory when it deems it appropriate.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@deftypefn {C Function} {void *} scm_gc_malloc (size_t @var{size}, const char *@var{what})
|
||||||
|
@deftypefnx {C Function} {void *} scm_gc_malloc_pointerless (size_t @var{size}, const char *@var{what})
|
||||||
|
@deftypefnx {C Function} {void *} scm_gc_realloc (void *@var{mem}, size_t @var{old_size}, size_t @var{new_size}, const char *@var{what});
|
||||||
|
@deftypefnx {C Function} {void *} scm_gc_calloc (size_t @var{size}, const char *@var{what})
|
||||||
|
Allocate @var{size} bytes of automatically-managed memory. The memory
|
||||||
|
is automatically freed when no longer referenced from any live memory
|
||||||
|
block.
|
||||||
|
|
||||||
|
Memory allocated with @code{scm_gc_malloc} or @code{scm_gc_calloc} is
|
||||||
|
scanned for pointers. Memory allocated by
|
||||||
|
@code{scm_gc_malloc_pointerless} is not scanned.
|
||||||
|
|
||||||
|
The @code{scm_gc_realloc} call preserves the ``pointerlessness'' of the
|
||||||
|
memory area pointed to by @var{mem}. Note that you need to pass the old
|
||||||
|
size of a reallocated memory block as well. See below for a motivation.
|
||||||
|
@end deftypefn
|
||||||
|
|
||||||
|
|
||||||
|
@deftypefn {C Function} void scm_gc_free (void *@var{mem}, size_t @var{size}, const char *@var{what})
|
||||||
|
Explicitly free the memory block pointed to by @var{mem}, which was
|
||||||
|
previously allocated by one of the above @code{scm_gc} functions.
|
||||||
|
|
||||||
|
Note that you need to explicitly pass the @var{size} parameter. This
|
||||||
|
is done since it should normally be easy to provide this parameter
|
||||||
|
(for memory that is associated with GC controlled objects) and help keep
|
||||||
|
the memory management overhead very low. However, in Guile 2.x,
|
||||||
|
@var{size} is always ignored.
|
||||||
|
@end deftypefn
|
||||||
|
|
||||||
|
|
||||||
@deftypefn {C Function} void scm_gc_register_collectable_memory (void *@var{mem}, size_t @var{size}, const char *@var{what})
|
@deftypefn {C Function} void scm_gc_register_collectable_memory (void *@var{mem}, size_t @var{size}, const char *@var{what})
|
||||||
Informs the GC that the memory at @var{mem} of size @var{size} can
|
Informs the GC that the memory at @var{mem} of size @var{size} can
|
||||||
potentially be freed during a GC. That is, announce that @var{mem} is
|
potentially be freed during a GC. That is, announce that @var{mem} is
|
||||||
|
@ -170,13 +219,12 @@ object, @var{size} bytes will be freed along with it. The GC will
|
||||||
much bytes of memory are associated with GC controlled objects and the
|
much bytes of memory are associated with GC controlled objects and the
|
||||||
memory system figures this into its decisions when to run a GC.
|
memory system figures this into its decisions when to run a GC.
|
||||||
|
|
||||||
@var{mem} does not need to come from @code{scm_malloc}. You can only
|
|
||||||
call this function once for every memory block.
|
|
||||||
|
|
||||||
The @var{what} argument is used for statistical purposes. It should
|
The @var{what} argument is used for statistical purposes. It should
|
||||||
describe the type of object that the memory will be used for so that
|
describe the type of object that the memory will be used for so that
|
||||||
users can identify just what strange objects are eating up their
|
users can identify just what strange objects are eating up their
|
||||||
memory.
|
memory.
|
||||||
|
|
||||||
|
In Guile 2.x, this function has no effect.
|
||||||
@end deftypefn
|
@end deftypefn
|
||||||
|
|
||||||
@deftypefn {C Function} void scm_gc_unregister_collectable_memory (void *@var{mem}, size_t @var{size})
|
@deftypefn {C Function} void scm_gc_unregister_collectable_memory (void *@var{mem}, size_t @var{size})
|
||||||
|
@ -186,27 +234,10 @@ match up every call to @code{scm_gc_register_collectable_memory} with
|
||||||
a call to @code{scm_gc_unregister_collectable_memory}. If you don't do
|
a call to @code{scm_gc_unregister_collectable_memory}. If you don't do
|
||||||
this, the GC might have a wrong impression of what is going on and run
|
this, the GC might have a wrong impression of what is going on and run
|
||||||
much less efficiently than it could.
|
much less efficiently than it could.
|
||||||
|
|
||||||
|
In Guile 2.x, this function has no effect.
|
||||||
@end deftypefn
|
@end deftypefn
|
||||||
|
|
||||||
@deftypefn {C Function} {void *} scm_gc_malloc (size_t @var{size}, const char *@var{what})
|
|
||||||
@deftypefnx {C Function} {void *} scm_gc_realloc (void *@var{mem}, size_t @var{old_size}, size_t @var{new_size}, const char *@var{what});
|
|
||||||
@deftypefnx {C Function} {void *} scm_gc_calloc (size_t @var{size}, const char *@var{what})
|
|
||||||
Like @code{scm_malloc}, @code{scm_realloc} or @code{scm_calloc}, but
|
|
||||||
also call @code{scm_gc_register_collectable_memory}. Note that you
|
|
||||||
need to pass the old size of a reallocated memory block as well. See
|
|
||||||
below for a motivation.
|
|
||||||
@end deftypefn
|
|
||||||
|
|
||||||
|
|
||||||
@deftypefn {C Function} void scm_gc_free (void *@var{mem}, size_t @var{size}, const char *@var{what})
|
|
||||||
Like @code{free}, but also call @code{scm_gc_unregister_collectable_memory}.
|
|
||||||
|
|
||||||
Note that you need to explicitly pass the @var{size} parameter. This
|
|
||||||
is done since it should normally be easy to provide this parameter
|
|
||||||
(for memory that is associated with GC controlled objects) and this
|
|
||||||
frees us from tracking this value in the GC itself, which will keep
|
|
||||||
the memory management overhead very low.
|
|
||||||
@end deftypefn
|
|
||||||
|
|
||||||
@deftypefn {C Function} void scm_frame_free (void *mem)
|
@deftypefn {C Function} void scm_frame_free (void *mem)
|
||||||
Equivalent to @code{scm_frame_unwind_handler (free, @var{mem},
|
Equivalent to @code{scm_frame_unwind_handler (free, @var{mem},
|
||||||
|
@ -220,6 +251,9 @@ of malloced objects.
|
||||||
@var{what} is the second argument to @code{scm_gc_malloc},
|
@var{what} is the second argument to @code{scm_gc_malloc},
|
||||||
@var{n} is the number of objects of that type currently
|
@var{n} is the number of objects of that type currently
|
||||||
allocated.
|
allocated.
|
||||||
|
|
||||||
|
This function is only available if the @code{GUILE_DEBUG_MALLOC}
|
||||||
|
preprocessor macro was defined when Guile was compiled.
|
||||||
@end deffn
|
@end deffn
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -758,7 +758,7 @@ Record definition with @code{define-record-type} (@pxref{SRFI-9}).
|
||||||
Read hash extension @code{#,()} (@pxref{SRFI-10}).
|
Read hash extension @code{#,()} (@pxref{SRFI-10}).
|
||||||
|
|
||||||
@item (srfi srfi-11)
|
@item (srfi srfi-11)
|
||||||
Multiple-value handling with @code{let-values} and @code{let-values*}
|
Multiple-value handling with @code{let-values} and @code{let*-values}
|
||||||
(@pxref{SRFI-11}).
|
(@pxref{SRFI-11}).
|
||||||
|
|
||||||
@item (srfi srfi-13)
|
@item (srfi srfi-13)
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
@c -*-texinfo-*-
|
@c -*-texinfo-*-
|
||||||
@c This is part of the GNU Guile Reference Manual.
|
@c This is part of the GNU Guile Reference Manual.
|
||||||
@c Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2008
|
@c Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2008, 2009
|
||||||
@c Free Software Foundation, Inc.
|
@c Free Software Foundation, Inc.
|
||||||
@c See the file guile.texi for copying conditions.
|
@c See the file guile.texi for copying conditions.
|
||||||
|
|
||||||
|
@ -113,15 +113,21 @@ string, into a list and return the resulting list with
|
||||||
is returned.
|
is returned.
|
||||||
@end deffn
|
@end deffn
|
||||||
|
|
||||||
@deffn {Scheme Procedure} search-path path filename [extensions]
|
@deffn {Scheme Procedure} search-path path filename [extensions [require-exts?]]
|
||||||
@deffnx {C Function} scm_search_path (path, filename, extensions)
|
@deffnx {C Function} scm_search_path (path, filename, rest)
|
||||||
Search @var{path} for a directory containing a file named
|
Search @var{path} for a directory containing a file named
|
||||||
@var{filename}. The file must be readable, and not a directory.
|
@var{filename}. The file must be readable, and not a directory.
|
||||||
If we find one, return its full filename; otherwise, return
|
If we find one, return its full filename; otherwise, return
|
||||||
@code{#f}. If @var{filename} is absolute, return it unchanged.
|
@code{#f}. If @var{filename} is absolute, return it unchanged.
|
||||||
If given, @var{extensions} is a list of strings; for each
|
If given, @var{extensions} is a list of strings; for each
|
||||||
directory in @var{path}, we search for @var{filename}
|
directory in @var{path}, we search for @var{filename}
|
||||||
concatenated with each @var{extension}.
|
concatenated with each @var{extension}. If @var{require-exts?}
|
||||||
|
is true, require that the returned file name have one of the
|
||||||
|
given extensions; if @var{require-exts?} is not given, it
|
||||||
|
defaults to @code{#f}.
|
||||||
|
|
||||||
|
For compatibility with Guile 1.8 and earlier, the C function takes only
|
||||||
|
three arguments
|
||||||
@end deffn
|
@end deffn
|
||||||
|
|
||||||
@defvar %guile-build-info
|
@defvar %guile-build-info
|
||||||
|
@ -178,6 +184,14 @@ libguile/libpath.h, which is completely generated, so deleting this file
|
||||||
before a build guarantees up-to-date values for that build.
|
before a build guarantees up-to-date values for that build.
|
||||||
@end defvar
|
@end defvar
|
||||||
|
|
||||||
|
@cindex GNU triplet
|
||||||
|
@cindex canonical host type
|
||||||
|
|
||||||
|
@defvar %host-type
|
||||||
|
The canonical host type (GNU triplet) of the host Guile was configured
|
||||||
|
for, e.g., @code{"x86_64-unknown-linux-gnu"} (@pxref{Canonicalizing,,,
|
||||||
|
autoconf, The GNU Autoconf Manual}).
|
||||||
|
@end defvar
|
||||||
|
|
||||||
@node Feature Tracking
|
@node Feature Tracking
|
||||||
@subsection Feature Tracking
|
@subsection Feature Tracking
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
@c -*-texinfo-*-
|
@c -*-texinfo-*-
|
||||||
@c This is part of the GNU Guile Reference Manual.
|
@c This is part of the GNU Guile Reference Manual.
|
||||||
@c Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004
|
@c Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004, 2009
|
||||||
@c Free Software Foundation, Inc.
|
@c Free Software Foundation, Inc.
|
||||||
@c See the file guile.texi for copying conditions.
|
@c See the file guile.texi for copying conditions.
|
||||||
|
|
||||||
|
@ -13,6 +13,7 @@
|
||||||
* Primitive Procedures:: Procedures defined in C.
|
* Primitive Procedures:: Procedures defined in C.
|
||||||
* Compiled Procedures:: Scheme procedures can be compiled.
|
* Compiled Procedures:: Scheme procedures can be compiled.
|
||||||
* Optional Arguments:: Handling keyword, optional and rest arguments.
|
* Optional Arguments:: Handling keyword, optional and rest arguments.
|
||||||
|
* Case-lambda:: One function, multiple arities.
|
||||||
* Procedure Properties:: Procedure properties and meta-information.
|
* Procedure Properties:: Procedure properties and meta-information.
|
||||||
* Procedures with Setters:: Procedures with setters.
|
* Procedures with Setters:: Procedures with setters.
|
||||||
* Macros:: Lisp style macro definitions.
|
* Macros:: Lisp style macro definitions.
|
||||||
|
@ -26,8 +27,6 @@
|
||||||
@subsection Lambda: Basic Procedure Creation
|
@subsection Lambda: Basic Procedure Creation
|
||||||
@cindex lambda
|
@cindex lambda
|
||||||
|
|
||||||
@c FIXME::martin: Review me!
|
|
||||||
|
|
||||||
A @code{lambda} expression evaluates to a procedure. The environment
|
A @code{lambda} expression evaluates to a procedure. The environment
|
||||||
which is in effect when a @code{lambda} expression is evaluated is
|
which is in effect when a @code{lambda} expression is evaluated is
|
||||||
enclosed in the newly created procedure, this is referred to as a
|
enclosed in the newly created procedure, this is referred to as a
|
||||||
|
@ -135,15 +134,21 @@ slightly higher-level abstraction of the Guile implementation.
|
||||||
@node Compiled Procedures
|
@node Compiled Procedures
|
||||||
@subsection Compiled Procedures
|
@subsection Compiled Procedures
|
||||||
|
|
||||||
Procedures that were created when loading a compiled file are
|
In Guile, procedures can be executed by directly interpreting their
|
||||||
themselves compiled. (In contrast, procedures that are defined by
|
source code. Scheme source code is a set of nested lists, after all,
|
||||||
loading a Scheme source file are interpreted, and often not as fast as
|
with each list representing a procedure call.
|
||||||
compiled procedures.)
|
|
||||||
|
|
||||||
Loading compiled files is the normal way that compiled procedures come
|
Most procedures are compiled, however. This means that Guile has done
|
||||||
to being, though procedures can be compiled at runtime as well.
|
some pre-computation on the procedure, to determine what it will need
|
||||||
@xref{Read/Load/Eval/Compile}, for more information on runtime
|
to do each time the procedure runs. Compiled procedures run faster
|
||||||
compilation.
|
than interpreted procedures.
|
||||||
|
|
||||||
|
Loading files is the normal way that compiled procedures come to
|
||||||
|
being. If Guile sees that a file is uncompiled, or that its compiled
|
||||||
|
file is out of date, it will attempt to compile the file when it is
|
||||||
|
loaded, and save the result to disk. Procedures can be compiled at
|
||||||
|
runtime as well. @xref{Read/Load/Eval/Compile}, for more information
|
||||||
|
on runtime compilation.
|
||||||
|
|
||||||
Compiled procedures, also known as @dfn{programs}, respond all
|
Compiled procedures, also known as @dfn{programs}, respond all
|
||||||
procedures that operate on procedures. In addition, there are a few
|
procedures that operate on procedures. In addition, there are a few
|
||||||
|
@ -181,56 +186,34 @@ return @code{#f} if the compiler could determine that this information
|
||||||
was unnecessary.
|
was unnecessary.
|
||||||
@end deffn
|
@end deffn
|
||||||
|
|
||||||
@deffn {Scheme Procedure} program-external program
|
@deffn {Scheme Procedure} program-free-variables program
|
||||||
@deffnx {C Function} scm_program_external (program)
|
@deffnx {C Function} scm_program_free_variables (program)
|
||||||
Returns the set of heap-allocated variables that this program captures
|
Returns the set of free variables that this program captures in its
|
||||||
in its closure, as a list. If a closure is code with data, you can get
|
closure, as a vector. If a closure is code with data, you can get the
|
||||||
the code from @code{program-bytecode}, and the data via
|
code from @code{program-objcode}, and the data via
|
||||||
@code{program-external}.
|
@code{program-free-variables}.
|
||||||
|
|
||||||
|
Some of the values captured are actually in variable ``boxes''.
|
||||||
|
@xref{Variables and the VM}, for more information.
|
||||||
|
|
||||||
Users must not modify the returned value unless they think they're
|
Users must not modify the returned value unless they think they're
|
||||||
really clever.
|
really clever.
|
||||||
@end deffn
|
@end deffn
|
||||||
|
|
||||||
@deffn {Scheme Procedure} program-external-set! program external
|
|
||||||
@deffnx {C Function} scm_program_external_set_x (program, external)
|
|
||||||
Set @var{external} as the set of closure variables on @var{program}.
|
|
||||||
|
|
||||||
The Guile maintainers will not be held responsible for side effects of
|
|
||||||
calling this function, including but not limited to replacement of
|
|
||||||
shampoo with hair dye, and a slight salty taste in tomorrow's dinner.
|
|
||||||
@end deffn
|
|
||||||
|
|
||||||
@deffn {Scheme Procedure} program-arity program
|
|
||||||
@deffnx {C Function} scm_program_arity (program)
|
|
||||||
@deffnx {Scheme Procedure} arity:nargs arity
|
|
||||||
@deffnx {Scheme Procedure} arity:nrest arity
|
|
||||||
@deffnx {Scheme Procedure} arity:nlocs arity
|
|
||||||
@deffnx {Scheme Procedure} arity:nexts arity
|
|
||||||
Accessors for a representation of the ``arity'' of a program.
|
|
||||||
|
|
||||||
@code{nargs} is the number of arguments to the procedure, and
|
|
||||||
@code{nrest} will be non-zero if the last argument is a rest argument.
|
|
||||||
|
|
||||||
The other two accessors determine the number of local and external
|
|
||||||
(heap-allocated) variables that this procedure will need to have
|
|
||||||
allocated.
|
|
||||||
@end deffn
|
|
||||||
|
|
||||||
@deffn {Scheme Procedure} program-meta program
|
@deffn {Scheme Procedure} program-meta program
|
||||||
@deffnx scm_program_meta (program)
|
@deffnx {C Function} scm_program_meta (program)
|
||||||
Return the metadata thunk of @var{program}, or @code{#f} if it has no
|
Return the metadata thunk of @var{program}, or @code{#f} if it has no
|
||||||
metadata.
|
metadata.
|
||||||
|
|
||||||
When called, a metadata thunk returns a list of the following form:
|
When called, a metadata thunk returns a list of the following form:
|
||||||
@code{(@var{bindings} @var{sources} . @var{properties})}. The format
|
@code{(@var{bindings} @var{sources} @var{arities} . @var{properties})}. The format
|
||||||
of each of these elements is discussed below.
|
of each of these elements is discussed below.
|
||||||
@end deffn
|
@end deffn
|
||||||
|
|
||||||
@deffn {Scheme Procedure} program-bindings program
|
@deffn {Scheme Procedure} program-bindings program
|
||||||
@deffnx {Scheme Procedure} make-binding name extp index start end
|
@deffnx {Scheme Procedure} make-binding name boxed? index start end
|
||||||
@deffnx {Scheme Procedure} binding:name binding
|
@deffnx {Scheme Procedure} binding:name binding
|
||||||
@deffnx {Scheme Procedure} binding:extp binding
|
@deffnx {Scheme Procedure} binding:boxed? binding
|
||||||
@deffnx {Scheme Procedure} binding:index binding
|
@deffnx {Scheme Procedure} binding:index binding
|
||||||
@deffnx {Scheme Procedure} binding:start binding
|
@deffnx {Scheme Procedure} binding:start binding
|
||||||
@deffnx {Scheme Procedure} binding:end binding
|
@deffnx {Scheme Procedure} binding:end binding
|
||||||
|
@ -238,9 +221,7 @@ Bindings annotations for programs, along with their accessors.
|
||||||
|
|
||||||
Bindings declare names and liveness extents for block-local variables.
|
Bindings declare names and liveness extents for block-local variables.
|
||||||
The best way to see what these are is to play around with them at a
|
The best way to see what these are is to play around with them at a
|
||||||
REPL. The only tricky bit is that @var{extp} is a boolean, declaring
|
REPL. @xref{VM Concepts}, for more information.
|
||||||
whether the binding is heap-allocated or not. @xref{VM Concepts}, for
|
|
||||||
more information.
|
|
||||||
|
|
||||||
Note that bindings information is stored in a program as part of its
|
Note that bindings information is stored in a program as part of its
|
||||||
metadata thunk, so including it in the generated object code does not
|
metadata thunk, so including it in the generated object code does not
|
||||||
|
@ -262,6 +243,40 @@ following} an instruction, so that backtraces can find the source
|
||||||
location of a call that is in progress.
|
location of a call that is in progress.
|
||||||
@end deffn
|
@end deffn
|
||||||
|
|
||||||
|
@deffn {Scheme Procedure} program-arities program
|
||||||
|
@deffnx {C Function} scm_program_arities (program)
|
||||||
|
@deffnx {Scheme Procedure} program-arity program ip
|
||||||
|
@deffnx {Scheme Procedure} arity:start arity
|
||||||
|
@deffnx {Scheme Procedure} arity:end arity
|
||||||
|
@deffnx {Scheme Procedure} arity:nreq arity
|
||||||
|
@deffnx {Scheme Procedure} arity:nopt arity
|
||||||
|
@deffnx {Scheme Procedure} arity:rest? arity
|
||||||
|
@deffnx {Scheme Procedure} arity:kw arity
|
||||||
|
@deffnx {Scheme Procedure} arity:allow-other-keys? arity
|
||||||
|
Accessors for a representation of the ``arity'' of a program.
|
||||||
|
|
||||||
|
The normal case is that a procedure has one arity. For example,
|
||||||
|
@code{(lambda (x) x)}, takes one required argument, and that's it. One
|
||||||
|
could access that number of required arguments via @code{(arity:nreq
|
||||||
|
(program-arities (lambda (x) x)))}. Similarly, @code{arity:nopt} gets
|
||||||
|
the number of optional arguments, and @code{arity:rest?} returns a true
|
||||||
|
value if the procedure has a rest arg.
|
||||||
|
|
||||||
|
@code{arity:kw} returns a list of @code{(@var{kw} . @var{idx})} pairs,
|
||||||
|
if the procedure has keyword arguments. The @var{idx} refers to the
|
||||||
|
@var{idx}th local variable; @xref{Variables and the VM}, for more
|
||||||
|
information. Finally @code{arity:allow-other-keys?} returns a true
|
||||||
|
value if other keys are allowed. @xref{Optional Arguments}, for more
|
||||||
|
information.
|
||||||
|
|
||||||
|
So what about @code{arity:start} and @code{arity:end}, then? They
|
||||||
|
return the range of bytes in the program's bytecode for which a given
|
||||||
|
arity is valid. You see, a procedure can actually have more than one
|
||||||
|
arity. The question, ``what is a procedure's arity'' only really makes
|
||||||
|
sense at certain points in the program, delimited by these
|
||||||
|
@code{arity:start} and @code{arity:end} values.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
@deffn {Scheme Procedure} program-properties program
|
@deffn {Scheme Procedure} program-properties program
|
||||||
Return the properties of a @code{program} as an association list,
|
Return the properties of a @code{program} as an association list,
|
||||||
keyed by property name (a symbol).
|
keyed by property name (a symbol).
|
||||||
|
@ -285,42 +300,143 @@ Accessors for specific properties.
|
||||||
@node Optional Arguments
|
@node Optional Arguments
|
||||||
@subsection Optional Arguments
|
@subsection Optional Arguments
|
||||||
|
|
||||||
@c FIXME::martin: Review me!
|
|
||||||
|
|
||||||
Scheme procedures, as defined in R5RS, can either handle a fixed number
|
Scheme procedures, as defined in R5RS, can either handle a fixed number
|
||||||
of actual arguments, or a fixed number of actual arguments followed by
|
of actual arguments, or a fixed number of actual arguments followed by
|
||||||
arbitrarily many additional arguments. Writing procedures of variable
|
arbitrarily many additional arguments. Writing procedures of variable
|
||||||
arity can be useful, but unfortunately, the syntactic means for handling
|
arity can be useful, but unfortunately, the syntactic means for handling
|
||||||
argument lists of varying length is a bit inconvenient. It is possible
|
argument lists of varying length is a bit inconvenient. It is possible
|
||||||
to give names to the fixed number of argument, but the remaining
|
to give names to the fixed number of arguments, but the remaining
|
||||||
(optional) arguments can be only referenced as a list of values
|
(optional) arguments can be only referenced as a list of values
|
||||||
(@pxref{Lambda}).
|
(@pxref{Lambda}).
|
||||||
|
|
||||||
Guile comes with the module @code{(ice-9 optargs)}, which makes using
|
For this reason, Guile provides an extension to @code{lambda},
|
||||||
optional arguments much more convenient. In addition, this module
|
@code{lambda*}, which allows the user to define procedures with
|
||||||
provides syntax for handling keywords in argument lists
|
optional and keyword arguments. In addition, Guile's virtual machine
|
||||||
(@pxref{Keywords}).
|
has low-level support for optional and keyword argument dispatch.
|
||||||
|
Calls to procedures with optional and keyword arguments can be made
|
||||||
Before using any of the procedures or macros defined in this section,
|
cheaply, without allocating a rest list.
|
||||||
you have to load the module @code{(ice-9 optargs)} with the statement:
|
|
||||||
|
|
||||||
@cindex @code{optargs}
|
|
||||||
@lisp
|
|
||||||
(use-modules (ice-9 optargs))
|
|
||||||
@end lisp
|
|
||||||
|
|
||||||
@menu
|
@menu
|
||||||
* let-optional Reference:: Locally binding optional arguments.
|
* lambda* and define*:: Creating advanced argument handling procedures.
|
||||||
* let-keywords Reference:: Locally binding keywords arguments.
|
* ice-9 optargs:: (ice-9 optargs) provides some utilities.
|
||||||
* lambda* Reference:: Creating advanced argument handling procedures.
|
|
||||||
* define* Reference:: Defining procedures and macros.
|
|
||||||
@end menu
|
@end menu
|
||||||
|
|
||||||
|
|
||||||
@node let-optional Reference
|
@node lambda* and define*
|
||||||
@subsubsection let-optional Reference
|
@subsubsection lambda* and define*.
|
||||||
|
|
||||||
@c FIXME::martin: Review me!
|
@code{lambda*} is like @code{lambda}, except with some extensions to
|
||||||
|
allow optional and keyword arguments.
|
||||||
|
|
||||||
|
@deffn {library syntax} lambda* ([var@dots{}] @* [#:optional vardef@dots{}] @* [#:key vardef@dots{} [#:allow-other-keys]] @* [#:rest var | . var]) @* body
|
||||||
|
@sp 1
|
||||||
|
Create a procedure which takes optional and/or keyword arguments
|
||||||
|
specified with @code{#:optional} and @code{#:key}. For example,
|
||||||
|
|
||||||
|
@lisp
|
||||||
|
(lambda* (a b #:optional c d . e) '())
|
||||||
|
@end lisp
|
||||||
|
|
||||||
|
is a procedure with fixed arguments @var{a} and @var{b}, optional
|
||||||
|
arguments @var{c} and @var{d}, and rest argument @var{e}. If the
|
||||||
|
optional arguments are omitted in a call, the variables for them are
|
||||||
|
bound to @code{#f}.
|
||||||
|
|
||||||
|
@fnindex define*
|
||||||
|
Likewise, @code{define*} is syntactic sugar for defining procedures
|
||||||
|
using @code{lambda*}.
|
||||||
|
|
||||||
|
@code{lambda*} can also make procedures with keyword arguments. For
|
||||||
|
example, a procedure defined like this:
|
||||||
|
|
||||||
|
@lisp
|
||||||
|
(define* (sir-yes-sir #:key action how-high)
|
||||||
|
(list action how-high))
|
||||||
|
@end lisp
|
||||||
|
|
||||||
|
can be called as @code{(sir-yes-sir #:action 'jump)},
|
||||||
|
@code{(sir-yes-sir #:how-high 13)}, @code{(sir-yes-sir #:action
|
||||||
|
'lay-down #:how-high 0)}, or just @code{(sir-yes-sir)}. Whichever
|
||||||
|
arguments are given as keywords are bound to values (and those not
|
||||||
|
given are @code{#f}).
|
||||||
|
|
||||||
|
Optional and keyword arguments can also have default values to take
|
||||||
|
when not present in a call, by giving a two-element list of variable
|
||||||
|
name and expression. For example in
|
||||||
|
|
||||||
|
@lisp
|
||||||
|
(define* (frob foo #:optional (bar 42) #:key (baz 73))
|
||||||
|
(list foo bar baz))
|
||||||
|
@end lisp
|
||||||
|
|
||||||
|
@var{foo} is a fixed argument, @var{bar} is an optional argument with
|
||||||
|
default value 42, and baz is a keyword argument with default value 73.
|
||||||
|
Default value expressions are not evaluated unless they are needed,
|
||||||
|
and until the procedure is called.
|
||||||
|
|
||||||
|
Normally it's an error if a call has keywords other than those
|
||||||
|
specified by @code{#:key}, but adding @code{#:allow-other-keys} to the
|
||||||
|
definition (after the keyword argument declarations) will ignore
|
||||||
|
unknown keywords.
|
||||||
|
|
||||||
|
If a call has a keyword given twice, the last value is used. For
|
||||||
|
example,
|
||||||
|
|
||||||
|
@lisp
|
||||||
|
(define* (flips #:key (heads 0) (tails 0))
|
||||||
|
(display (list heads tails)))
|
||||||
|
|
||||||
|
(flips #:heads 37 #:tails 42 #:heads 99)
|
||||||
|
@print{} (99 42)
|
||||||
|
@end lisp
|
||||||
|
|
||||||
|
@code{#:rest} is a synonym for the dotted syntax rest argument. The
|
||||||
|
argument lists @code{(a . b)} and @code{(a #:rest b)} are equivalent
|
||||||
|
in all respects. This is provided for more similarity to DSSSL,
|
||||||
|
MIT-Scheme and Kawa among others, as well as for refugees from other
|
||||||
|
Lisp dialects.
|
||||||
|
|
||||||
|
When @code{#:key} is used together with a rest argument, the keyword
|
||||||
|
parameters in a call all remain in the rest list. This is the same as
|
||||||
|
Common Lisp. For example,
|
||||||
|
|
||||||
|
@lisp
|
||||||
|
((lambda* (#:key (x 0) #:allow-other-keys #:rest r)
|
||||||
|
(display r))
|
||||||
|
#:x 123 #:y 456)
|
||||||
|
@print{} (#:x 123 #:y 456)
|
||||||
|
@end lisp
|
||||||
|
|
||||||
|
@code{#:optional} and @code{#:key} establish their bindings
|
||||||
|
successively, from left to right. This means default expressions can
|
||||||
|
refer back to prior parameters, for example
|
||||||
|
|
||||||
|
@lisp
|
||||||
|
(lambda* (start #:optional (end (+ 10 start)))
|
||||||
|
(do ((i start (1+ i)))
|
||||||
|
((> i end))
|
||||||
|
(display i)))
|
||||||
|
@end lisp
|
||||||
|
|
||||||
|
The exception to this left-to-right scoping rule is the rest argument.
|
||||||
|
If there is a rest argument, it is bound after the optional arguments,
|
||||||
|
but before the keyword arguments.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
|
||||||
|
@node ice-9 optargs
|
||||||
|
@subsubsection (ice-9 optargs)
|
||||||
|
|
||||||
|
Before Guile 2.0, @code{lambda*} and @code{define*} were implemented
|
||||||
|
using macros that processed rest list arguments. This was not optimal,
|
||||||
|
as calling procedures with optional arguments had to allocate rest
|
||||||
|
lists at every procedure invocation. Guile 2.0 improved this
|
||||||
|
situation by bringing optional and keyword arguments into Guile's
|
||||||
|
core.
|
||||||
|
|
||||||
|
However there are occasions in which you have a list and want to parse
|
||||||
|
it for optional or keyword arguments. Guile's @code{(ice-9 optargs)}
|
||||||
|
provides some macros to help with that task.
|
||||||
|
|
||||||
The syntax @code{let-optional} and @code{let-optional*} are for
|
The syntax @code{let-optional} and @code{let-optional*} are for
|
||||||
destructuring rest argument lists and giving names to the various list
|
destructuring rest argument lists and giving names to the various list
|
||||||
|
@ -345,13 +461,9 @@ After binding the variables, the expressions @var{expr} @dots{} are
|
||||||
evaluated in order.
|
evaluated in order.
|
||||||
@end deffn
|
@end deffn
|
||||||
|
|
||||||
|
Similarly, @code{let-keywords} and @code{let-keywords*} extract values
|
||||||
@node let-keywords Reference
|
from keyword style argument lists, binding local variables to those
|
||||||
@subsubsection let-keywords Reference
|
values or to defaults.
|
||||||
|
|
||||||
@code{let-keywords} and @code{let-keywords*} extract values from
|
|
||||||
keyword style argument lists, binding local variables to those values
|
|
||||||
or to defaults.
|
|
||||||
|
|
||||||
@deffn {library syntax} let-keywords args allow-other-keys? (binding @dots{}) body @dots{}
|
@deffn {library syntax} let-keywords args allow-other-keys? (binding @dots{}) body @dots{}
|
||||||
@deffnx {library syntax} let-keywords* args allow-other-keys? (binding @dots{}) body @dots{}
|
@deffnx {library syntax} let-keywords* args allow-other-keys? (binding @dots{}) body @dots{}
|
||||||
|
@ -382,175 +494,18 @@ The binding for @code{foo} comes from the @code{#:foo} keyword in
|
||||||
keywords are allowed in the @var{args} list. When true other keys are
|
keywords are allowed in the @var{args} list. When true other keys are
|
||||||
ignored (such as @code{#:xyzzy} in the example), when @code{#f} an
|
ignored (such as @code{#:xyzzy} in the example), when @code{#f} an
|
||||||
error is thrown for anything unknown.
|
error is thrown for anything unknown.
|
||||||
|
|
||||||
@code{let-keywords} is like @code{let} (@pxref{Local Bindings}) in
|
|
||||||
that all bindings are made at once, the defaults expressions are
|
|
||||||
evaluated (if needed) outside the scope of the @code{let-keywords}.
|
|
||||||
|
|
||||||
@code{let-keywords*} is like @code{let*}, each binding is made
|
|
||||||
successively, and the default expressions see the bindings previously
|
|
||||||
made. This is the style used by @code{lambda*} keywords
|
|
||||||
(@pxref{lambda* Reference}). For example,
|
|
||||||
|
|
||||||
@example
|
|
||||||
(define args '(#:foo 3))
|
|
||||||
|
|
||||||
(let-keywords* args #f
|
|
||||||
((foo 99)
|
|
||||||
(bar (+ foo 6)))
|
|
||||||
(display bar))
|
|
||||||
@print{} 9
|
|
||||||
@end example
|
|
||||||
|
|
||||||
The expression for each default is only evaluated if it's needed,
|
|
||||||
ie. if the keyword doesn't appear in @var{args}. So one way to make a
|
|
||||||
keyword mandatory is to throw an error of some sort as the default.
|
|
||||||
|
|
||||||
@example
|
|
||||||
(define args '(#:start 7 #:finish 13))
|
|
||||||
|
|
||||||
(let-keywords* args #t
|
|
||||||
((start 0)
|
|
||||||
(stop (error "missing #:stop argument")))
|
|
||||||
...)
|
|
||||||
@result{} ERROR: missing #:stop argument
|
|
||||||
@end example
|
|
||||||
@end deffn
|
@end deffn
|
||||||
|
|
||||||
|
@code{(ice-9 optargs)} also provides some more @code{define*} sugar,
|
||||||
@node lambda* Reference
|
which is not so useful with modern Guile coding, but still supported:
|
||||||
@subsubsection lambda* Reference
|
|
||||||
|
|
||||||
When using optional and keyword argument lists, @code{lambda} for
|
|
||||||
creating a procedure then @code{let-optional} or @code{let-keywords}
|
|
||||||
is a bit lengthy. @code{lambda*} combines the features of those
|
|
||||||
macros into a single convenient syntax.
|
|
||||||
|
|
||||||
@deffn {library syntax} lambda* ([var@dots{}] @* [#:optional vardef@dots{}] @* [#:key vardef@dots{} [#:allow-other-keys]] @* [#:rest var | . var]) @* body
|
|
||||||
@sp 1
|
|
||||||
Create a procedure which takes optional and/or keyword arguments
|
|
||||||
specified with @code{#:optional} and @code{#:key}. For example,
|
|
||||||
|
|
||||||
@lisp
|
|
||||||
(lambda* (a b #:optional c d . e) '())
|
|
||||||
@end lisp
|
|
||||||
|
|
||||||
is a procedure with fixed arguments @var{a} and @var{b}, optional
|
|
||||||
arguments @var{c} and @var{d}, and rest argument @var{e}. If the
|
|
||||||
optional arguments are omitted in a call, the variables for them are
|
|
||||||
bound to @code{#f}.
|
|
||||||
|
|
||||||
@code{lambda*} can also take keyword arguments. For example, a procedure
|
|
||||||
defined like this:
|
|
||||||
|
|
||||||
@lisp
|
|
||||||
(lambda* (#:key xyzzy larch) '())
|
|
||||||
@end lisp
|
|
||||||
|
|
||||||
can be called with any of the argument lists @code{(#:xyzzy 11)},
|
|
||||||
@code{(#:larch 13)}, @code{(#:larch 42 #:xyzzy 19)}, @code{()}.
|
|
||||||
Whichever arguments are given as keywords are bound to values (and
|
|
||||||
those not given are @code{#f}).
|
|
||||||
|
|
||||||
Optional and keyword arguments can also have default values to take
|
|
||||||
when not present in a call, by giving a two-element list of variable
|
|
||||||
name and expression. For example in
|
|
||||||
|
|
||||||
@lisp
|
|
||||||
(lambda* (foo #:optional (bar 42) #:key (baz 73))
|
|
||||||
(list foo bar baz))
|
|
||||||
@end lisp
|
|
||||||
|
|
||||||
@var{foo} is a fixed argument, @var{bar} is an optional argument with
|
|
||||||
default value 42, and baz is a keyword argument with default value 73.
|
|
||||||
Default value expressions are not evaluated unless they are needed,
|
|
||||||
and until the procedure is called.
|
|
||||||
|
|
||||||
Normally it's an error if a call has keywords other than those
|
|
||||||
specified by @code{#:key}, but adding @code{#:allow-other-keys} to the
|
|
||||||
definition (after the keyword argument declarations) will ignore
|
|
||||||
unknown keywords.
|
|
||||||
|
|
||||||
If a call has a keyword given twice, the last value is used. For
|
|
||||||
example,
|
|
||||||
|
|
||||||
@lisp
|
|
||||||
((lambda* (#:key (heads 0) (tails 0))
|
|
||||||
(display (list heads tails)))
|
|
||||||
#:heads 37 #:tails 42 #:heads 99)
|
|
||||||
@print{} (99 42)
|
|
||||||
@end lisp
|
|
||||||
|
|
||||||
@code{#:rest} is a synonym for the dotted syntax rest argument. The
|
|
||||||
argument lists @code{(a . b)} and @code{(a #:rest b)} are equivalent
|
|
||||||
in all respects. This is provided for more similarity to DSSSL,
|
|
||||||
MIT-Scheme and Kawa among others, as well as for refugees from other
|
|
||||||
Lisp dialects.
|
|
||||||
|
|
||||||
When @code{#:key} is used together with a rest argument, the keyword
|
|
||||||
parameters in a call all remain in the rest list. This is the same as
|
|
||||||
Common Lisp. For example,
|
|
||||||
|
|
||||||
@lisp
|
|
||||||
((lambda* (#:key (x 0) #:allow-other-keys #:rest r)
|
|
||||||
(display r))
|
|
||||||
#:x 123 #:y 456)
|
|
||||||
@print{} (#:x 123 #:y 456)
|
|
||||||
@end lisp
|
|
||||||
|
|
||||||
@code{#:optional} and @code{#:key} establish their bindings
|
|
||||||
successively, from left to right, as per @code{let-optional*} and
|
|
||||||
@code{let-keywords*}. This means default expressions can refer back
|
|
||||||
to prior parameters, for example
|
|
||||||
|
|
||||||
@lisp
|
|
||||||
(lambda* (start #:optional (end (+ 10 start)))
|
|
||||||
(do ((i start (1+ i)))
|
|
||||||
((> i end))
|
|
||||||
(display i)))
|
|
||||||
@end lisp
|
|
||||||
@end deffn
|
|
||||||
|
|
||||||
|
|
||||||
@node define* Reference
|
|
||||||
@subsubsection define* Reference
|
|
||||||
|
|
||||||
@c FIXME::martin: Review me!
|
|
||||||
|
|
||||||
Just like @code{define} has a shorthand notation for defining procedures
|
|
||||||
(@pxref{Lambda Alternatives}), @code{define*} is provided as an
|
|
||||||
abbreviation of the combination of @code{define} and @code{lambda*}.
|
|
||||||
|
|
||||||
@code{define*-public} is the @code{lambda*} version of
|
@code{define*-public} is the @code{lambda*} version of
|
||||||
@code{define-public}; @code{defmacro*} and @code{defmacro*-public} exist
|
@code{define-public}; @code{defmacro*} and @code{defmacro*-public}
|
||||||
for defining macros with the improved argument list handling
|
exist for defining macros with the improved argument list handling
|
||||||
possibilities. The @code{-public} versions not only define the
|
possibilities. The @code{-public} versions not only define the
|
||||||
procedures/macros, but also export them from the current module.
|
procedures/macros, but also export them from the current module.
|
||||||
|
|
||||||
@deffn {library syntax} define* formals body
|
@deffn {library syntax} define*-public formals body
|
||||||
@deffnx {library syntax} define*-public formals body
|
Like a mix of @code{define*} and @code{define-public}.
|
||||||
@code{define*} and @code{define*-public} support optional arguments with
|
|
||||||
a similar syntax to @code{lambda*}. They also support arbitrary-depth
|
|
||||||
currying, just like Guile's define. Some examples:
|
|
||||||
|
|
||||||
@lisp
|
|
||||||
(define* (x y #:optional a (z 3) #:key w . u)
|
|
||||||
(display (list y z u)))
|
|
||||||
@end lisp
|
|
||||||
defines a procedure @code{x} with a fixed argument @var{y}, an optional
|
|
||||||
argument @var{a}, another optional argument @var{z} with default value 3,
|
|
||||||
a keyword argument @var{w}, and a rest argument @var{u}.
|
|
||||||
|
|
||||||
@lisp
|
|
||||||
(define-public* ((foo #:optional bar) #:optional baz) '())
|
|
||||||
@end lisp
|
|
||||||
|
|
||||||
This illustrates currying. A procedure @code{foo} is defined, which,
|
|
||||||
when called with an optional argument @var{bar}, returns a procedure
|
|
||||||
that takes an optional argument @var{baz}.
|
|
||||||
|
|
||||||
Of course, @code{define*[-public]} also supports @code{#:rest} and
|
|
||||||
@code{#:allow-other-keys} in the same way as @code{lambda*}.
|
|
||||||
@end deffn
|
@end deffn
|
||||||
|
|
||||||
@deffn {library syntax} defmacro* name formals body
|
@deffn {library syntax} defmacro* name formals body
|
||||||
|
@ -562,29 +517,105 @@ semantics. Here is an example of a macro with an optional argument:
|
||||||
|
|
||||||
@lisp
|
@lisp
|
||||||
(defmacro* transmorgify (a #:optional b)
|
(defmacro* transmorgify (a #:optional b)
|
||||||
(a 1))
|
(a 1))
|
||||||
@end lisp
|
@end lisp
|
||||||
@end deffn
|
@end deffn
|
||||||
|
|
||||||
|
@node Case-lambda
|
||||||
|
@subsection Case-lambda
|
||||||
|
@cindex SRFI-16
|
||||||
|
@cindex variable arity
|
||||||
|
@cindex arity, variable
|
||||||
|
|
||||||
|
R5RS's rest arguments are indeed useful and very general, but they
|
||||||
|
often aren't the most appropriate or efficient means to get the job
|
||||||
|
done. For example, @code{lambda*} is a much better solution to the
|
||||||
|
optional argument problem than @code{lambda} with rest arguments.
|
||||||
|
|
||||||
|
@fnindex case-lambda
|
||||||
|
Likewise, @code{case-lambda} works well for when you want one
|
||||||
|
procedure to do double duty (or triple, or ...), without the penalty
|
||||||
|
of consing a rest list.
|
||||||
|
|
||||||
|
For example:
|
||||||
|
|
||||||
|
@lisp
|
||||||
|
(define (make-accum n)
|
||||||
|
(case-lambda
|
||||||
|
(() n)
|
||||||
|
((m) (set! n (+ n m)) n)))
|
||||||
|
|
||||||
|
(define a (make-accum 20))
|
||||||
|
(a) @result{} 20
|
||||||
|
(a 10) @result{} 30
|
||||||
|
(a) @result{} 30
|
||||||
|
@end lisp
|
||||||
|
|
||||||
|
The value returned by a @code{case-lambda} form is a procedure which
|
||||||
|
matches the number of actual arguments against the formals in the
|
||||||
|
various clauses, in order. The first matching clause is selected, the
|
||||||
|
corresponding values from the actual parameter list are bound to the
|
||||||
|
variable names in the clauses and the body of the clause is evaluated.
|
||||||
|
If no clause matches, an error is signalled.
|
||||||
|
|
||||||
|
The syntax of the @code{case-lambda} form is defined in the following
|
||||||
|
EBNF grammar. @dfn{Formals} means a formal argument list just like
|
||||||
|
with @code{lambda} (@pxref{Lambda}).
|
||||||
|
|
||||||
|
@example
|
||||||
|
@group
|
||||||
|
<case-lambda>
|
||||||
|
--> (case-lambda <case-lambda-clause>)
|
||||||
|
<case-lambda-clause>
|
||||||
|
--> (<formals> <definition-or-command>*)
|
||||||
|
<formals>
|
||||||
|
--> (<identifier>*)
|
||||||
|
| (<identifier>* . <identifier>)
|
||||||
|
| <identifier>
|
||||||
|
@end group
|
||||||
|
@end example
|
||||||
|
|
||||||
|
Rest lists can be useful with @code{case-lambda}:
|
||||||
|
|
||||||
|
@lisp
|
||||||
|
(define plus
|
||||||
|
(case-lambda
|
||||||
|
(() 0)
|
||||||
|
((a) a)
|
||||||
|
((a b) (+ a b))
|
||||||
|
((a b . rest) (apply plus (+ a b) rest))))
|
||||||
|
(plus 1 2 3) @result{} 6
|
||||||
|
@end lisp
|
||||||
|
|
||||||
|
@fnindex case-lambda*
|
||||||
|
Also, for completeness. Guile defines @code{case-lambda*} as well,
|
||||||
|
which is like @code{case-lambda}, except with @code{lambda*} clauses.
|
||||||
|
A @code{case-lambda*} clause matches if the arguments fill the
|
||||||
|
required arguments, but are not too many for the optional and/or rest
|
||||||
|
arguments.
|
||||||
|
|
||||||
|
Keyword arguments are possible with @code{case-lambda*}, but they do
|
||||||
|
not contribute to the ``matching'' behavior. That is to say,
|
||||||
|
@code{case-lambda*} matches only on required, optional, and rest
|
||||||
|
arguments, and on the predicate; keyword arguments may be present but
|
||||||
|
do not contribute to the ``success'' of a match. In fact a bad keyword
|
||||||
|
argument list may cause an error to be raised.
|
||||||
|
|
||||||
@node Procedure Properties
|
@node Procedure Properties
|
||||||
@subsection Procedure Properties and Meta-information
|
@subsection Procedure Properties and Meta-information
|
||||||
|
|
||||||
@c FIXME::martin: Review me!
|
In addition to the information that is strictly necessary to run,
|
||||||
|
procedures may have other associated information. For example, the
|
||||||
|
name of a procedure is information not for the procedure, but about
|
||||||
|
the procedure. This meta-information can be accessed via the procedure
|
||||||
|
properties interface.
|
||||||
|
|
||||||
Procedures always have attached the environment in which they were
|
The first group of procedures in this meta-interface are predicates to
|
||||||
created and information about how to apply them to actual arguments. In
|
test whether a Scheme object is a procedure, or a special procedure,
|
||||||
addition to that, properties and meta-information can be stored with
|
respectively. @code{procedure?} is the most general predicates, it
|
||||||
procedures. The procedures in this section can be used to test whether
|
returns @code{#t} for any kind of procedure. @code{closure?} does not
|
||||||
a given procedure satisfies a condition; and to access and set a
|
return @code{#t} for primitive procedures, and @code{thunk?} only
|
||||||
procedure's property.
|
returns @code{#t} for procedures which do not accept any arguments.
|
||||||
|
|
||||||
The first group of procedures are predicates to test whether a Scheme
|
|
||||||
object is a procedure, or a special procedure, respectively.
|
|
||||||
@code{procedure?} is the most general predicates, it returns @code{#t}
|
|
||||||
for any kind of procedure. @code{closure?} does not return @code{#t}
|
|
||||||
for primitive procedures, and @code{thunk?} only returns @code{#t} for
|
|
||||||
procedures which do not accept any arguments.
|
|
||||||
|
|
||||||
@rnindex procedure?
|
@rnindex procedure?
|
||||||
@deffn {Scheme Procedure} procedure? obj
|
@deffn {Scheme Procedure} procedure? obj
|
||||||
|
@ -594,7 +625,11 @@ Return @code{#t} if @var{obj} is a procedure.
|
||||||
|
|
||||||
@deffn {Scheme Procedure} closure? obj
|
@deffn {Scheme Procedure} closure? obj
|
||||||
@deffnx {C Function} scm_closure_p (obj)
|
@deffnx {C Function} scm_closure_p (obj)
|
||||||
Return @code{#t} if @var{obj} is a closure.
|
Return @code{#t} if @var{obj} is a closure. This category somewhat
|
||||||
|
misnamed, actually, as it applies only to interpreted procedures, not
|
||||||
|
compiled procedures. But since it has historically been used more to
|
||||||
|
select on implementation details than on essence (closure or not), we
|
||||||
|
keep it here for compatibility. Don't use it in new code, though.
|
||||||
@end deffn
|
@end deffn
|
||||||
|
|
||||||
@deffn {Scheme Procedure} thunk? obj
|
@deffn {Scheme Procedure} thunk? obj
|
||||||
|
@ -602,10 +637,9 @@ Return @code{#t} if @var{obj} is a closure.
|
||||||
Return @code{#t} if @var{obj} is a thunk.
|
Return @code{#t} if @var{obj} is a thunk.
|
||||||
@end deffn
|
@end deffn
|
||||||
|
|
||||||
@c FIXME::martin: Is that true?
|
|
||||||
@cindex procedure properties
|
@cindex procedure properties
|
||||||
Procedure properties are general properties to be attached to
|
Procedure properties are general properties associated with
|
||||||
procedures. These can be the name of a procedure or other relevant
|
procedures. These can be the name of a procedure or other relevant
|
||||||
information, such as debug hints.
|
information, such as debug hints.
|
||||||
|
|
||||||
@deffn {Scheme Procedure} procedure-name proc
|
@deffn {Scheme Procedure} procedure-name proc
|
||||||
|
@ -615,32 +649,34 @@ Return the name of the procedure @var{proc}
|
||||||
|
|
||||||
@deffn {Scheme Procedure} procedure-source proc
|
@deffn {Scheme Procedure} procedure-source proc
|
||||||
@deffnx {C Function} scm_procedure_source (proc)
|
@deffnx {C Function} scm_procedure_source (proc)
|
||||||
Return the source of the procedure @var{proc}.
|
Return the source of the procedure @var{proc}. Returns @code{#f} if
|
||||||
|
the source code is not available.
|
||||||
@end deffn
|
@end deffn
|
||||||
|
|
||||||
@deffn {Scheme Procedure} procedure-environment proc
|
@deffn {Scheme Procedure} procedure-environment proc
|
||||||
@deffnx {C Function} scm_procedure_environment (proc)
|
@deffnx {C Function} scm_procedure_environment (proc)
|
||||||
Return the environment of the procedure @var{proc}.
|
Return the environment of the procedure @var{proc}. Very deprecated.
|
||||||
@end deffn
|
@end deffn
|
||||||
|
|
||||||
@deffn {Scheme Procedure} procedure-properties proc
|
@deffn {Scheme Procedure} procedure-properties proc
|
||||||
@deffnx {C Function} scm_procedure_properties (proc)
|
@deffnx {C Function} scm_procedure_properties (proc)
|
||||||
Return @var{obj}'s property list.
|
Return the properties associated with @var{proc}, as an association
|
||||||
|
list.
|
||||||
@end deffn
|
@end deffn
|
||||||
|
|
||||||
@deffn {Scheme Procedure} procedure-property obj key
|
@deffn {Scheme Procedure} procedure-property proc key
|
||||||
@deffnx {C Function} scm_procedure_property (obj, key)
|
@deffnx {C Function} scm_procedure_property (proc, key)
|
||||||
Return the property of @var{obj} with name @var{key}.
|
Return the property of @var{proc} with name @var{key}.
|
||||||
@end deffn
|
@end deffn
|
||||||
|
|
||||||
@deffn {Scheme Procedure} set-procedure-properties! proc alist
|
@deffn {Scheme Procedure} set-procedure-properties! proc alist
|
||||||
@deffnx {C Function} scm_set_procedure_properties_x (proc, alist)
|
@deffnx {C Function} scm_set_procedure_properties_x (proc, alist)
|
||||||
Set @var{obj}'s property list to @var{alist}.
|
Set @var{proc}'s property list to @var{alist}.
|
||||||
@end deffn
|
@end deffn
|
||||||
|
|
||||||
@deffn {Scheme Procedure} set-procedure-property! obj key value
|
@deffn {Scheme Procedure} set-procedure-property! proc key value
|
||||||
@deffnx {C Function} scm_set_procedure_property_x (obj, key, value)
|
@deffnx {C Function} scm_set_procedure_property_x (proc, key, value)
|
||||||
In @var{obj}'s property list, set the property named @var{key} to
|
In @var{proc}'s property list, set the property named @var{key} to
|
||||||
@var{value}.
|
@var{value}.
|
||||||
@end deffn
|
@end deffn
|
||||||
|
|
||||||
|
@ -899,6 +935,9 @@ given by the <transformer-spec>.
|
||||||
@node Internal Macros
|
@node Internal Macros
|
||||||
@subsection Internal Representation of Macros and Syntax
|
@subsection Internal Representation of Macros and Syntax
|
||||||
|
|
||||||
|
[FIXME: used to be true. Isn't any more. Use syntax-rules or
|
||||||
|
syntax-case please :)]
|
||||||
|
|
||||||
Internally, Guile uses three different flavors of macros. The three
|
Internally, Guile uses three different flavors of macros. The three
|
||||||
flavors are called @dfn{acro} (or @dfn{syntax}), @dfn{macro} and
|
flavors are called @dfn{acro} (or @dfn{syntax}), @dfn{macro} and
|
||||||
@dfn{mmacro}.
|
@dfn{mmacro}.
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
@c -*-texinfo-*-
|
@c -*-texinfo-*-
|
||||||
@c This is part of the GNU Guile Reference Manual.
|
@c This is part of the GNU Guile Reference Manual.
|
||||||
@c Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004, 2007
|
@c Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004, 2007, 2009
|
||||||
@c Free Software Foundation, Inc.
|
@c Free Software Foundation, Inc.
|
||||||
@c See the file guile.texi for copying conditions.
|
@c See the file guile.texi for copying conditions.
|
||||||
|
|
||||||
|
@ -542,10 +542,19 @@ which only ever executes on behalf of one process at any one time.
|
||||||
@node Blocking
|
@node Blocking
|
||||||
@subsection Blocking in Guile Mode
|
@subsection Blocking in Guile Mode
|
||||||
|
|
||||||
A thread must not block outside of a libguile function while it is in
|
Up to Guile version 1.8, a thread blocked in guile mode would prevent
|
||||||
guile mode. The following functions can be used to temporily leave
|
the garbage collector from running. Thus threads had to explicitly
|
||||||
guile mode or to perform some common blocking operations in a supported
|
leave guile mode with @code{scm_without_guile ()} before making a
|
||||||
way.
|
potentially blocking call such as a mutex lock, a @code{select ()}
|
||||||
|
system call, etc. The following functions could be used to temporarily
|
||||||
|
leave guile mode or to perform some common blocking operations in a
|
||||||
|
supported way.
|
||||||
|
|
||||||
|
Starting from Guile 2.0, blocked threads no longer hinder garbage
|
||||||
|
collection. Thus, the functions below are not needed anymore. They can
|
||||||
|
still be used to inform the GC that a thread is about to block, giving
|
||||||
|
it a (small) optimization opportunity for ``stop the world'' garbage
|
||||||
|
collections, should they occur while the thread is blocked.
|
||||||
|
|
||||||
@deftypefn {C Function} {void *} scm_without_guile (void *(*func) (void *), void *data)
|
@deftypefn {C Function} {void *} scm_without_guile (void *(*func) (void *), void *data)
|
||||||
Leave guile mode, call @var{func} on @var{data}, enter guile mode and
|
Leave guile mode, call @var{func} on @var{data}, enter guile mode and
|
||||||
|
@ -783,39 +792,6 @@ Like @code{scm_with_dynamic_state}, but call @var{func} with
|
||||||
@var{data}.
|
@var{data}.
|
||||||
@end deftypefn
|
@end deftypefn
|
||||||
|
|
||||||
@c @node Futures
|
|
||||||
@c @subsection Futures
|
|
||||||
@c @cindex futures
|
|
||||||
|
|
||||||
@c -- Futures are disabled for the time being, see futures.h for an
|
|
||||||
@c -- explanation.
|
|
||||||
|
|
||||||
@c Futures are a convenient way to run a calculation in a new thread, and
|
|
||||||
@c only wait for the result when it's actually needed.
|
|
||||||
|
|
||||||
@c Futures are similar to promises (@pxref{Delayed Evaluation}), in that
|
|
||||||
@c they allow mainline code to continue immediately. But @code{delay}
|
|
||||||
@c doesn't evaluate at all until forced, whereas @code{future} starts
|
|
||||||
@c immediately in a new thread.
|
|
||||||
|
|
||||||
@c @deffn {syntax} future expr
|
|
||||||
@c Begin evaluating @var{expr} in a new thread, and return a ``future''
|
|
||||||
@c object representing the calculation.
|
|
||||||
@c @end deffn
|
|
||||||
|
|
||||||
@c @deffn {Scheme Procedure} make-future thunk
|
|
||||||
@c @deffnx {C Function} scm_make_future (thunk)
|
|
||||||
@c Begin evaluating the call @code{(@var{thunk})} in a new thread, and
|
|
||||||
@c return a ``future'' object representing the calculation.
|
|
||||||
@c @end deffn
|
|
||||||
|
|
||||||
@c @deffn {Scheme Procedure} future-ref f
|
|
||||||
@c @deffnx {C Function} scm_future_ref (f)
|
|
||||||
@c Return the value computed by the future @var{f}. If @var{f} has not
|
|
||||||
@c yet finished executing then wait for it to do so.
|
|
||||||
@c @end deffn
|
|
||||||
|
|
||||||
|
|
||||||
@node Parallel Forms
|
@node Parallel Forms
|
||||||
@subsection Parallel forms
|
@subsection Parallel forms
|
||||||
@cindex parallel forms
|
@cindex parallel forms
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
@c -*-texinfo-*-
|
@c -*-texinfo-*-
|
||||||
@c This is part of the GNU Guile Reference Manual.
|
@c This is part of the GNU Guile Reference Manual.
|
||||||
@c Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004
|
@c Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004, 2009
|
||||||
@c Free Software Foundation, Inc.
|
@c Free Software Foundation, Inc.
|
||||||
@c See the file guile.texi for copying conditions.
|
@c See the file guile.texi for copying conditions.
|
||||||
|
|
||||||
|
@ -8,6 +8,8 @@
|
||||||
@node Smobs
|
@node Smobs
|
||||||
@section Smobs
|
@section Smobs
|
||||||
|
|
||||||
|
@cindex smob
|
||||||
|
|
||||||
This chapter contains reference information related to defining and
|
This chapter contains reference information related to defining and
|
||||||
working with smobs. See @ref{Defining New Types (Smobs)} for a
|
working with smobs. See @ref{Defining New Types (Smobs)} for a
|
||||||
tutorial-like introduction to smobs.
|
tutorial-like introduction to smobs.
|
||||||
|
@ -33,10 +35,48 @@ immediately followed by calls to one or several of
|
||||||
@code{scm_set_smob_print}, and/or @code{scm_set_smob_equalp}.
|
@code{scm_set_smob_print}, and/or @code{scm_set_smob_equalp}.
|
||||||
@end deftypefun
|
@end deftypefun
|
||||||
|
|
||||||
|
@cindex finalizer
|
||||||
|
@cindex finalization
|
||||||
|
|
||||||
|
@deftypefn {C Function} void scm_set_smob_free (scm_t_bits tc, size_t (*free) (SCM obj))
|
||||||
|
This function sets the smob freeing procedure (sometimes referred to as
|
||||||
|
a @dfn{finalizer}) for the smob type specified by the tag
|
||||||
|
@var{tc}. @var{tc} is the tag returned by @code{scm_make_smob_type}.
|
||||||
|
|
||||||
|
The @var{free} procedure must deallocate all resources that are
|
||||||
|
directly associated with the smob instance @var{OBJ}. It must assume
|
||||||
|
that all @code{SCM} values that it references have already been freed
|
||||||
|
and are thus invalid.
|
||||||
|
|
||||||
|
It must also not call any libguile function or macro except
|
||||||
|
@code{scm_gc_free}, @code{SCM_SMOB_FLAGS}, @code{SCM_SMOB_DATA},
|
||||||
|
@code{SCM_SMOB_DATA_2}, and @code{SCM_SMOB_DATA_3}.
|
||||||
|
|
||||||
|
The @var{free} procedure must return 0.
|
||||||
|
|
||||||
|
Note that defining a freeing procedure is not necessary if the resources
|
||||||
|
associated with @var{obj} consists only of memory allocated with
|
||||||
|
@code{scm_gc_malloc} or @code{scm_gc_malloc_pointerless} because this
|
||||||
|
memory is automatically reclaimed by the garbage collector when it is no
|
||||||
|
longer needed (@pxref{Memory Blocks, @code{scm_gc_malloc}}).
|
||||||
|
@end deftypefn
|
||||||
|
|
||||||
|
@cindex precise marking
|
||||||
|
|
||||||
@deftypefn {C Function} void scm_set_smob_mark (scm_t_bits tc, SCM (*mark) (SCM obj))
|
@deftypefn {C Function} void scm_set_smob_mark (scm_t_bits tc, SCM (*mark) (SCM obj))
|
||||||
This function sets the smob marking procedure for the smob type specified by
|
This function sets the smob marking procedure for the smob type specified by
|
||||||
the tag @var{tc}. @var{tc} is the tag returned by @code{scm_make_smob_type}.
|
the tag @var{tc}. @var{tc} is the tag returned by @code{scm_make_smob_type}.
|
||||||
|
|
||||||
|
Defining a marking procedure may sometimes be unnecessary because large
|
||||||
|
parts of the process' memory (with the exception of
|
||||||
|
@code{scm_gc_malloc_pointerless} regions, and @code{malloc}- or
|
||||||
|
@code{scm_malloc}-allocated memory) are scanned for live
|
||||||
|
pointers@footnote{Conversely, in Guile up to the 1.8 series, the marking
|
||||||
|
procedure was always required. The reason is that Guile's GC would only
|
||||||
|
look for pointers in the memory area used for built-in types (the
|
||||||
|
@dfn{cell heap}), not in user-allocated or statically allocated memory.
|
||||||
|
This approach is often referred to as @dfn{precise marking}.}.
|
||||||
|
|
||||||
The @var{mark} procedure must cause @code{scm_gc_mark} to be called
|
The @var{mark} procedure must cause @code{scm_gc_mark} to be called
|
||||||
for every @code{SCM} value that is directly referenced by the smob
|
for every @code{SCM} value that is directly referenced by the smob
|
||||||
instance @var{obj}. One of these @code{SCM} values can be returned
|
instance @var{obj}. One of these @code{SCM} values can be returned
|
||||||
|
@ -49,22 +89,6 @@ It must not call any libguile function or macro except
|
||||||
@code{SCM_SMOB_DATA_2}, and @code{SCM_SMOB_DATA_3}.
|
@code{SCM_SMOB_DATA_2}, and @code{SCM_SMOB_DATA_3}.
|
||||||
@end deftypefn
|
@end deftypefn
|
||||||
|
|
||||||
@deftypefn {C Function} void scm_set_smob_free (scm_t_bits tc, size_t (*free) (SCM obj))
|
|
||||||
This function sets the smob freeing procedure for the smob type
|
|
||||||
specified by the tag @var{tc}. @var{tc} is the tag returned by
|
|
||||||
@code{scm_make_smob_type}.
|
|
||||||
|
|
||||||
The @var{free} procedure must deallocate all resources that are
|
|
||||||
directly associated with the smob instance @var{OBJ}. It must assume
|
|
||||||
that all @code{SCM} values that it references have already been freed
|
|
||||||
and are thus invalid.
|
|
||||||
|
|
||||||
It must also not call any libguile function or macro except
|
|
||||||
@code{scm_gc_free}, @code{SCM_SMOB_FLAGS}, @code{SCM_SMOB_DATA},
|
|
||||||
@code{SCM_SMOB_DATA_2}, and @code{SCM_SMOB_DATA_3}.
|
|
||||||
|
|
||||||
The @var{free} procedure must return 0.
|
|
||||||
@end deftypefn
|
|
||||||
|
|
||||||
@deftypefn {C Function} void scm_set_smob_print (scm_t_bits tc, int (*print) (SCM obj, SCM port, scm_print_state* pstate))
|
@deftypefn {C Function} void scm_set_smob_print (scm_t_bits tc, int (*print) (SCM obj, SCM port, scm_print_state* pstate))
|
||||||
This function sets the smob printing procedure for the smob type
|
This function sets the smob printing procedure for the smob type
|
||||||
|
|
|
@ -236,12 +236,49 @@ which puts the user in the @code{(foo)} module. That is purpose of the
|
||||||
when compiling the subsequent expression.
|
when compiling the subsequent expression.
|
||||||
|
|
||||||
For Scheme, an environment may be one of two things:
|
For Scheme, an environment may be one of two things:
|
||||||
|
|
||||||
@itemize
|
@itemize
|
||||||
@item @code{#f}, in which case compilation is performed in the context
|
@item @code{#f}, in which case compilation is performed in the context
|
||||||
of the current module; or
|
of the current module; or
|
||||||
@item a module, which specifies the context of the compilation.
|
@item a module, which specifies the context of the compilation.
|
||||||
@end itemize
|
@end itemize
|
||||||
|
|
||||||
|
By default, the @code{compile} and @code{compile-file} procedures
|
||||||
|
compile in a fresh module, such that bindings and macros introduced by
|
||||||
|
the expression being compiled are isolated:
|
||||||
|
|
||||||
|
@example
|
||||||
|
(eq? (current-module) (compile '(current-module)))
|
||||||
|
@result{} #f
|
||||||
|
|
||||||
|
(compile '(define hello 'world))
|
||||||
|
(defined? 'hello)
|
||||||
|
@result{} #f
|
||||||
|
|
||||||
|
(define / *)
|
||||||
|
(eq? (compile '/) /)
|
||||||
|
@result{} #f
|
||||||
|
@end example
|
||||||
|
|
||||||
|
Similarly, changes to the @code{current-reader} fluid (@pxref{Loading,
|
||||||
|
@code{current-reader}}) are isolated:
|
||||||
|
|
||||||
|
@example
|
||||||
|
(compile '(fluid-set! current-reader (lambda args 'fail)))
|
||||||
|
(fluid-ref current-reader)
|
||||||
|
@result{} #f
|
||||||
|
@end example
|
||||||
|
|
||||||
|
Nevertheless, having the compiler and @dfn{compilee} share the same name
|
||||||
|
space can be achieved by explicitly passing @code{(current-module)} as
|
||||||
|
the compilation environment:
|
||||||
|
|
||||||
|
@example
|
||||||
|
(define hello 'world)
|
||||||
|
(compile 'hello #:env (current-module))
|
||||||
|
@result{} world
|
||||||
|
@end example
|
||||||
|
|
||||||
@node Tree-IL
|
@node Tree-IL
|
||||||
@subsection Tree-IL
|
@subsection Tree-IL
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,7 @@ Guile
|
||||||
|
|
||||||
@goops{} is the object oriented extension to @guile{}. Its
|
@goops{} is the object oriented extension to @guile{}. Its
|
||||||
implementation is derived from @w{STk-3.99.3} by Erick Gallesio and
|
implementation is derived from @w{STk-3.99.3} by Erick Gallesio and
|
||||||
version 1.3 of Gregor Kiczales @cite{Tiny-Clos}. It is very close in
|
version 1.3 of Gregor Kiczales' @cite{Tiny-Clos}. It is very close in
|
||||||
spirit to CLOS, the Common Lisp Object System (@cite{CLtL2}) but is
|
spirit to CLOS, the Common Lisp Object System (@cite{CLtL2}) but is
|
||||||
adapted for the Scheme language. While GOOPS is not compatible with any
|
adapted for the Scheme language. While GOOPS is not compatible with any
|
||||||
of these systems, GOOPS contains a compatibility module which allows for
|
of these systems, GOOPS contains a compatibility module which allows for
|
||||||
|
|
|
@ -61,6 +61,8 @@ command-line arguments in the same manner as the stock Guile
|
||||||
interpreter. To make that straightforward, Guile provides the
|
interpreter. To make that straightforward, Guile provides the
|
||||||
@code{scm_boot_guile} and @code{scm_shell} function.
|
@code{scm_boot_guile} and @code{scm_shell} function.
|
||||||
|
|
||||||
|
For more about these functions, see @ref{Initialization}.
|
||||||
|
|
||||||
@node A Sample Guile Main Program
|
@node A Sample Guile Main Program
|
||||||
@subsection A Sample Guile Main Program
|
@subsection A Sample Guile Main Program
|
||||||
|
|
||||||
|
|
|
@ -1038,7 +1038,7 @@ Reference Manual}).
|
||||||
@sp 1
|
@sp 1
|
||||||
|
|
||||||
@defun ftw startname proc ['hash-size n]
|
@defun ftw startname proc ['hash-size n]
|
||||||
Walk the filesystem tree descending from @var{startname}, calling
|
Walk the file system tree descending from @var{startname}, calling
|
||||||
@var{proc} for each file and directory.
|
@var{proc} for each file and directory.
|
||||||
|
|
||||||
Hard links and symbolic links are followed. A file or directory is
|
Hard links and symbolic links are followed. A file or directory is
|
||||||
|
@ -1094,7 +1094,7 @@ use @code{throw} or similar to escape.
|
||||||
|
|
||||||
|
|
||||||
@defun nftw startname proc ['chdir] ['depth] ['hash-size n] ['mount] ['physical]
|
@defun nftw startname proc ['chdir] ['depth] ['hash-size n] ['mount] ['physical]
|
||||||
Walk the filesystem tree starting at @var{startname}, calling
|
Walk the file system tree starting at @var{startname}, calling
|
||||||
@var{proc} for each file and directory. @code{nftw} has extra
|
@var{proc} for each file and directory. @code{nftw} has extra
|
||||||
features over the basic @code{ftw} described above.
|
features over the basic @code{ftw} described above.
|
||||||
|
|
||||||
|
@ -1177,7 +1177,7 @@ Set the size of the hash table used to track items already visited.
|
||||||
|
|
||||||
@item @code{mount}
|
@item @code{mount}
|
||||||
Don't cross a mount point, meaning only visit items on the same
|
Don't cross a mount point, meaning only visit items on the same
|
||||||
filesystem as @var{startname} (ie.@: the same @code{stat:dev}).
|
file system as @var{startname} (ie.@: the same @code{stat:dev}).
|
||||||
|
|
||||||
@item @code{physical}
|
@item @code{physical}
|
||||||
Don't follow symbolic links, instead report them to @var{proc} as
|
Don't follow symbolic links, instead report them to @var{proc} as
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
@c -*-texinfo-*-
|
@c -*-texinfo-*-
|
||||||
@c This is part of the GNU Guile Reference Manual.
|
@c This is part of the GNU Guile Reference Manual.
|
||||||
@c Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004, 2006, 2007, 2008
|
@c Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004, 2006, 2007, 2008, 2009
|
||||||
@c Free Software Foundation, Inc.
|
@c Free Software Foundation, Inc.
|
||||||
@c See the file guile.texi for copying conditions.
|
@c See the file guile.texi for copying conditions.
|
||||||
|
|
||||||
|
@ -2225,6 +2225,8 @@ The address of the local host using the loopback device, ie.@:
|
||||||
|
|
||||||
@deffn {Scheme Procedure} inet-aton address
|
@deffn {Scheme Procedure} inet-aton address
|
||||||
@deffnx {C Function} scm_inet_aton (address)
|
@deffnx {C Function} scm_inet_aton (address)
|
||||||
|
This function is deprecated in favor of @code{inet-pton}.
|
||||||
|
|
||||||
Convert an IPv4 Internet address from printable string
|
Convert an IPv4 Internet address from printable string
|
||||||
(dotted decimal notation) to an integer. E.g.,
|
(dotted decimal notation) to an integer. E.g.,
|
||||||
|
|
||||||
|
@ -2235,6 +2237,8 @@ Convert an IPv4 Internet address from printable string
|
||||||
|
|
||||||
@deffn {Scheme Procedure} inet-ntoa inetid
|
@deffn {Scheme Procedure} inet-ntoa inetid
|
||||||
@deffnx {C Function} scm_inet_ntoa (inetid)
|
@deffnx {C Function} scm_inet_ntoa (inetid)
|
||||||
|
This function is deprecated in favor of @code{inet-ntop}.
|
||||||
|
|
||||||
Convert an IPv4 Internet address to a printable
|
Convert an IPv4 Internet address to a printable
|
||||||
(dotted decimal notation) string. E.g.,
|
(dotted decimal notation) string. E.g.,
|
||||||
|
|
||||||
|
@ -2288,8 +2292,8 @@ Convert a network address from an integer to a printable string.
|
||||||
|
|
||||||
@lisp
|
@lisp
|
||||||
(inet-ntop AF_INET 2130706433) @result{} "127.0.0.1"
|
(inet-ntop AF_INET 2130706433) @result{} "127.0.0.1"
|
||||||
(inet-ntop AF_INET6 (- (expt 2 128) 1)) @result{}
|
(inet-ntop AF_INET6 (- (expt 2 128) 1))
|
||||||
ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff
|
@result{} "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"
|
||||||
@end lisp
|
@end lisp
|
||||||
@end deffn
|
@end deffn
|
||||||
|
|
||||||
|
@ -2860,8 +2864,8 @@ same as @code{make-socket-address} would take to make such an object
|
||||||
(@pxref{Network Socket Address}). The return value is unspecified.
|
(@pxref{Network Socket Address}). The return value is unspecified.
|
||||||
|
|
||||||
@example
|
@example
|
||||||
(connect sock AF_INET INADDR_LOCALHOST 23)
|
(connect sock AF_INET INADDR_LOOPBACK 23)
|
||||||
(connect sock (make-socket-address AF_INET INADDR_LOCALHOST 23))
|
(connect sock (make-socket-address AF_INET INADDR_LOOPBACK 23))
|
||||||
@end example
|
@end example
|
||||||
@end deffn
|
@end deffn
|
||||||
|
|
||||||
|
@ -3107,7 +3111,7 @@ returns the contents of the root index URL.
|
||||||
|
|
||||||
@example
|
@example
|
||||||
(let ((s (socket PF_INET SOCK_STREAM 0)))
|
(let ((s (socket PF_INET SOCK_STREAM 0)))
|
||||||
(connect s AF_INET (inet-aton "127.0.0.1") 80)
|
(connect s AF_INET (inet-pton AF_INET "127.0.0.1") 80)
|
||||||
(display "GET / HTTP/1.0\r\n\r\n" s)
|
(display "GET / HTTP/1.0\r\n\r\n" s)
|
||||||
|
|
||||||
(do ((line (read-line s) (read-line s)))
|
(do ((line (read-line s) (read-line s)))
|
||||||
|
@ -3128,7 +3132,7 @@ client.
|
||||||
(let ((s (socket PF_INET SOCK_STREAM 0)))
|
(let ((s (socket PF_INET SOCK_STREAM 0)))
|
||||||
(setsockopt s SOL_SOCKET SO_REUSEADDR 1)
|
(setsockopt s SOL_SOCKET SO_REUSEADDR 1)
|
||||||
;; @r{Specific address?}
|
;; @r{Specific address?}
|
||||||
;; @r{(bind s AF_INET (inet-aton "127.0.0.1") 2904)}
|
;; @r{(bind s AF_INET (inet-pton AF_INET "127.0.0.1") 2904)}
|
||||||
(bind s AF_INET INADDR_ANY 2904)
|
(bind s AF_INET INADDR_ANY 2904)
|
||||||
(listen s 5)
|
(listen s 5)
|
||||||
|
|
||||||
|
|
|
@ -63,6 +63,12 @@ The second line of the script should contain only the characters
|
||||||
operating system never reads this far, but Guile treats this as the end
|
operating system never reads this far, but Guile treats this as the end
|
||||||
of the comment begun on the first line by the @samp{#!} characters.
|
of the comment begun on the first line by the @samp{#!} characters.
|
||||||
|
|
||||||
|
@item
|
||||||
|
If this source code file is not ASCII or ISO-8859-1 encoded, a coding
|
||||||
|
declaration such as @code{coding: utf-8} should appear in a comment
|
||||||
|
somewhere in the first five lines of the file: see @ref{Character
|
||||||
|
Encoding of Source Files}.
|
||||||
|
|
||||||
@item
|
@item
|
||||||
The rest of the file should be a Scheme program.
|
The rest of the file should be a Scheme program.
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
@c -*-texinfo-*-
|
@c -*-texinfo-*-
|
||||||
@c This is part of the GNU Guile Reference Manual.
|
@c This is part of the GNU Guile Reference Manual.
|
||||||
@c Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004, 2006, 2007, 2008
|
@c Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004, 2006, 2007, 2008, 2009
|
||||||
@c Free Software Foundation, Inc.
|
@c Free Software Foundation, Inc.
|
||||||
@c See the file guile.texi for copying conditions.
|
@c See the file guile.texi for copying conditions.
|
||||||
|
|
||||||
|
@ -37,6 +37,7 @@ get the relevant SRFI documents from the SRFI home page
|
||||||
* SRFI-18:: Multithreading support
|
* SRFI-18:: Multithreading support
|
||||||
* SRFI-19:: Time/Date library.
|
* SRFI-19:: Time/Date library.
|
||||||
* SRFI-26:: Specializing parameters
|
* SRFI-26:: Specializing parameters
|
||||||
|
* SRFI-30:: Nested multi-line block comments
|
||||||
* SRFI-31:: A special form `rec' for recursive evaluation
|
* SRFI-31:: A special form `rec' for recursive evaluation
|
||||||
* SRFI-34:: Exception handling.
|
* SRFI-34:: Exception handling.
|
||||||
* SRFI-35:: Conditions.
|
* SRFI-35:: Conditions.
|
||||||
|
@ -134,6 +135,7 @@ The Guile core has the following features,
|
||||||
|
|
||||||
@example
|
@example
|
||||||
guile
|
guile
|
||||||
|
guile-2 ;; starting from Guile 2.x
|
||||||
r5rs
|
r5rs
|
||||||
srfi-0
|
srfi-0
|
||||||
srfi-4
|
srfi-4
|
||||||
|
@ -161,6 +163,23 @@ how to load it with the Guile mechanism.
|
||||||
(use-modules (srfi srfi-8))))
|
(use-modules (srfi srfi-8))))
|
||||||
@end example
|
@end example
|
||||||
|
|
||||||
|
@cindex @code{guile-2} SRFI-0 feature
|
||||||
|
@cindex portability between 2.0 and older versions
|
||||||
|
Likewise, testing the @code{guile-2} feature allows code to be portable
|
||||||
|
between Guile 2.0 and previous versions of Guile. For instance, it
|
||||||
|
makes it possible to write code that accounts for Guile 2.0's compiler,
|
||||||
|
yet be correctly interpreted on 1.8 and earlier versions:
|
||||||
|
|
||||||
|
@example
|
||||||
|
(cond-expand (guile-2 (eval-when (compile)
|
||||||
|
;; This must be evaluated at compile time.
|
||||||
|
(fluid-set! current-reader my-reader)))
|
||||||
|
(guile
|
||||||
|
;; Earlier versions of Guile do not have a
|
||||||
|
;; separate compilation phase.
|
||||||
|
(fluid-set! current-reader my-reader)))
|
||||||
|
@end example
|
||||||
|
|
||||||
It should be noted that @code{cond-expand} is separate from the
|
It should be noted that @code{cond-expand} is separate from the
|
||||||
@code{*features*} mechanism (@pxref{Feature Tracking}), feature
|
@code{*features*} mechanism (@pxref{Feature Tracking}), feature
|
||||||
symbols in one are unrelated to those in the other.
|
symbols in one are unrelated to those in the other.
|
||||||
|
@ -1558,66 +1577,9 @@ The SRFI-14 data type and procedures are always available,
|
||||||
@cindex variable arity
|
@cindex variable arity
|
||||||
@cindex arity, variable
|
@cindex arity, variable
|
||||||
|
|
||||||
@c FIXME::martin: Review me!
|
SRFI-16 defines a variable-arity @code{lambda} form,
|
||||||
|
@code{case-lambda}. This form is available in the default Guile
|
||||||
@findex case-lambda
|
environment. @xref{Case-lambda}, for more information.
|
||||||
The syntactic form @code{case-lambda} creates procedures, just like
|
|
||||||
@code{lambda}, but has syntactic extensions for writing procedures of
|
|
||||||
varying arity easier.
|
|
||||||
|
|
||||||
The syntax of the @code{case-lambda} form is defined in the following
|
|
||||||
EBNF grammar.
|
|
||||||
|
|
||||||
@example
|
|
||||||
@group
|
|
||||||
<case-lambda>
|
|
||||||
--> (case-lambda <case-lambda-clause>)
|
|
||||||
<case-lambda-clause>
|
|
||||||
--> (<formals> <definition-or-command>*)
|
|
||||||
<formals>
|
|
||||||
--> (<identifier>*)
|
|
||||||
| (<identifier>* . <identifier>)
|
|
||||||
| <identifier>
|
|
||||||
@end group
|
|
||||||
@end example
|
|
||||||
|
|
||||||
The value returned by a @code{case-lambda} form is a procedure which
|
|
||||||
matches the number of actual arguments against the formals in the
|
|
||||||
various clauses, in order. @dfn{Formals} means a formal argument list
|
|
||||||
just like with @code{lambda} (@pxref{Lambda}). The first matching clause
|
|
||||||
is selected, the corresponding values from the actual parameter list are
|
|
||||||
bound to the variable names in the clauses and the body of the clause is
|
|
||||||
evaluated. If no clause matches, an error is signalled.
|
|
||||||
|
|
||||||
The following (silly) definition creates a procedure @var{foo} which
|
|
||||||
acts differently, depending on the number of actual arguments. If one
|
|
||||||
argument is given, the constant @code{#t} is returned, two arguments are
|
|
||||||
added and if more arguments are passed, their product is calculated.
|
|
||||||
|
|
||||||
@lisp
|
|
||||||
(define foo (case-lambda
|
|
||||||
((x) #t)
|
|
||||||
((x y) (+ x y))
|
|
||||||
(z
|
|
||||||
(apply * z))))
|
|
||||||
(foo 'bar)
|
|
||||||
@result{}
|
|
||||||
#t
|
|
||||||
(foo 2 4)
|
|
||||||
@result{}
|
|
||||||
6
|
|
||||||
(foo 3 3 3)
|
|
||||||
@result{}
|
|
||||||
27
|
|
||||||
(foo)
|
|
||||||
@result{}
|
|
||||||
1
|
|
||||||
@end lisp
|
|
||||||
|
|
||||||
The last expression evaluates to 1 because the last clause is matched,
|
|
||||||
@var{z} is bound to the empty list and the following multiplication,
|
|
||||||
applied to zero arguments, yields 1.
|
|
||||||
|
|
||||||
|
|
||||||
@node SRFI-17
|
@node SRFI-17
|
||||||
@subsection SRFI-17 - Generalized set!
|
@subsection SRFI-17 - Generalized set!
|
||||||
|
@ -2712,6 +2674,13 @@ or similar is typical.
|
||||||
@end example
|
@end example
|
||||||
@end deffn
|
@end deffn
|
||||||
|
|
||||||
|
@node SRFI-30
|
||||||
|
@subsection SRFI-30 - Nested Multi-line Comments
|
||||||
|
@cindex SRFI-30
|
||||||
|
|
||||||
|
Starting from version 2.0, Guile's @code{read} supports SRFI-30/R6RS
|
||||||
|
nested multi-line comments by default, @ref{Block Comments}.
|
||||||
|
|
||||||
@node SRFI-31
|
@node SRFI-31
|
||||||
@subsection SRFI-31 - A special form `rec' for recursive evaluation
|
@subsection SRFI-31 - A special form `rec' for recursive evaluation
|
||||||
@cindex SRFI-31
|
@cindex SRFI-31
|
||||||
|
|
|
@ -12,7 +12,7 @@ be required to make them available.
|
||||||
* Ports and descriptors:: Ports, file descriptors and how they
|
* Ports and descriptors:: Ports, file descriptors and how they
|
||||||
interact.
|
interact.
|
||||||
* Extended I/O:: Reading and writing to ports.
|
* Extended I/O:: Reading and writing to ports.
|
||||||
* File system:: Working in a hierarchical filesystem.
|
* File system:: Working in a hierarchical file system.
|
||||||
* User database:: Information about users from system databases.
|
* User database:: Information about users from system databases.
|
||||||
* Processes:: Information and control of Unix processes.
|
* Processes:: Information and control of Unix processes.
|
||||||
* Terminals:: Terminals and pseudo-terminals.
|
* Terminals:: Terminals and pseudo-terminals.
|
||||||
|
|
225
emacs/gds-faq.txt
Executable file
225
emacs/gds-faq.txt
Executable file
|
@ -0,0 +1,225 @@
|
||||||
|
|
||||||
|
* Installation
|
||||||
|
|
||||||
|
** How do I install guile-debugging?
|
||||||
|
|
||||||
|
After unpacking the .tar.gz file, run the usual sequence of commands:
|
||||||
|
|
||||||
|
$ ./configure
|
||||||
|
$ make
|
||||||
|
$ sudo make install
|
||||||
|
|
||||||
|
Then you need to make sure that the directory where guile-debugging's
|
||||||
|
Scheme files were installed is included in your Guile's load path.
|
||||||
|
(The sequence above will usually install guile-debugging under
|
||||||
|
/usr/local, and /usr/local is not in Guile's load path by default,
|
||||||
|
unless Guile itself was installed under /usr/local.) You can discover
|
||||||
|
your Guile's default load path by typing
|
||||||
|
|
||||||
|
$ guile -q -c '(begin (write %load-path) (newline))'
|
||||||
|
|
||||||
|
There are two ways to add guile-debugging's installation directory to
|
||||||
|
Guile's load path, if it isn't already there.
|
||||||
|
|
||||||
|
1. Edit or create the `init.scm' file, which Guile reads on startup,
|
||||||
|
so that it includes a line like this:
|
||||||
|
|
||||||
|
(set! %load-path (cons "/usr/local/share/guile" %load-path))
|
||||||
|
|
||||||
|
but with "/usr/local" replaced by the prefix that you installed
|
||||||
|
guile-debugging under, if not /usr/local.
|
||||||
|
|
||||||
|
The init.scm file must be installed (if it does not already exist
|
||||||
|
there) in one of the directories in Guile's default load-path.
|
||||||
|
|
||||||
|
2. Add this line to your .emacs file:
|
||||||
|
|
||||||
|
(setq gds-scheme-directory "/usr/local/share/guile")
|
||||||
|
|
||||||
|
before the `require' or `load' line that loads GDS, but with
|
||||||
|
"/usr/local" replaced by the prefix that you installed
|
||||||
|
guile-debugging under, if not /usr/local.
|
||||||
|
|
||||||
|
Finally, if you want guile-debugging's GDS interface to be loaded
|
||||||
|
automatically whenever you run Emacs, add this line to your .emacs:
|
||||||
|
|
||||||
|
(require 'gds)
|
||||||
|
|
||||||
|
* Troubleshooting
|
||||||
|
|
||||||
|
** "error in process filter" when starting Emacs (or loading GDS)
|
||||||
|
|
||||||
|
This is caused by an internal error in GDS's Scheme code, for which a
|
||||||
|
backtrace will have appeared in the gds-debug buffer, so please switch
|
||||||
|
to the gds-debug buffer and see what it says there.
|
||||||
|
|
||||||
|
The most common cause is a load path problem: Guile cannot find GDS's
|
||||||
|
Scheme code because it is not in the known load path. In this case
|
||||||
|
you should see the error message "no code for module" somewhere in the
|
||||||
|
backtrace. If you see this, please try the remedies described in `How
|
||||||
|
do I install guile-debugging?' above, then restart Emacs and see if
|
||||||
|
the problem has been cured.
|
||||||
|
|
||||||
|
If you don't see "no code for module", or if the described remedies
|
||||||
|
don't fix the problem, please send the contents of the gds-debug
|
||||||
|
buffer to me at <neil@ossau.uklinux.net>, so I can debug the problem.
|
||||||
|
|
||||||
|
If you don't see a backtrace at all in the gds-debug buffer, try the
|
||||||
|
next item ...
|
||||||
|
|
||||||
|
** "error in process filter" at some other time
|
||||||
|
|
||||||
|
This is caused by an internal error somewhere in GDS's Emacs Lisp
|
||||||
|
code. If possible, please
|
||||||
|
|
||||||
|
- switch on the `debug-on-error' option (M-x set-variable RET
|
||||||
|
debug-on-error RET t RET)
|
||||||
|
|
||||||
|
- do whatever you were doing so that the same error happens again
|
||||||
|
|
||||||
|
- send the Emacs Lisp stack trace which pops up to me at
|
||||||
|
<neil@ossau.uklinux.net>.
|
||||||
|
|
||||||
|
If that doesn't work, please just mail me with as much detail as
|
||||||
|
possible of what you were doing when the error occurred.
|
||||||
|
|
||||||
|
* GDS Features
|
||||||
|
|
||||||
|
** How do I inspect variable values?
|
||||||
|
|
||||||
|
Type `e' followed by the name of the variable, then <RET>. This
|
||||||
|
works whenever GDS is displaying a stack for an error at at a
|
||||||
|
breakpoint. (You can actually `e' to evaluate any expression in the
|
||||||
|
local environment of the selected stack frame; inspecting variables is
|
||||||
|
the special case of this where the expression is only a variable name.)
|
||||||
|
|
||||||
|
If GDS is displaying the associated source code in the window above or
|
||||||
|
below the stack, you can see the values of any variables in the
|
||||||
|
highlighted code just by hovering your mouse over them.
|
||||||
|
|
||||||
|
** How do I change a variable's value?
|
||||||
|
|
||||||
|
Type `e' and then `(set! VARNAME NEWVAL)', where VARNAME is the name
|
||||||
|
of the variable you want to set and NEWVAL is an expression which
|
||||||
|
Guile can evaluate to get the new value. This works whenever GDS is
|
||||||
|
displaying a stack for an error at at a breakpoint. The setting will
|
||||||
|
take effect in the local environment of the selected stack frame.
|
||||||
|
|
||||||
|
** How do I change the expression that Guile is about to evaluate?
|
||||||
|
|
||||||
|
Type `t' followed by the expression that you want Guile to evaluate
|
||||||
|
instead, then <RET>.
|
||||||
|
|
||||||
|
Then type one of the commands that tells Guile to continue execution.
|
||||||
|
|
||||||
|
(Tweaking expressions, as described here, is only supported by the
|
||||||
|
latest CVS version of Guile. The GDS stack display tells you when
|
||||||
|
tweaking is possible by adding "(tweakable)" to the first line of the
|
||||||
|
stack window.)
|
||||||
|
|
||||||
|
** How do I return a value from the current stack frame different to what the evaluator has calculated?
|
||||||
|
|
||||||
|
You have to be at the normal exit of the relevant frame first, so if
|
||||||
|
GDS is not already showing you the normally calculated return value,
|
||||||
|
type `o' to finish the evaluation of the selected frame.
|
||||||
|
|
||||||
|
Then type `t' followed by the value you want to return, and <RET>.
|
||||||
|
The value that you type can be any expression, but note that it will
|
||||||
|
not be evaluated before being returned; for example if you type `(+ 2
|
||||||
|
3)', the return value will be a three-element list, not 5.
|
||||||
|
|
||||||
|
Finally type one of the commands that tells Guile to continue
|
||||||
|
execution.
|
||||||
|
|
||||||
|
(Tweaking return values, as described here, is only supported by the
|
||||||
|
latest CVS version of Guile. The GDS stack display tells you when
|
||||||
|
tweaking is possible by adding "(tweakable)" to the first line of the
|
||||||
|
stack window.)
|
||||||
|
|
||||||
|
** How do I step over a line of code?
|
||||||
|
|
||||||
|
Scheme isn't organized by lines, so it doesn't really make sense to
|
||||||
|
think of stepping over lines. Instead please see the next entry on
|
||||||
|
stepping over expressions.
|
||||||
|
|
||||||
|
** How do I step over an expression?
|
||||||
|
|
||||||
|
It depends what you mean by "step over". If you mean that you want
|
||||||
|
Guile to evaluate that expression normally, but then show you its
|
||||||
|
return value, type `o', which does exactly that.
|
||||||
|
|
||||||
|
If you mean that you want to skip the evaluation of that expression
|
||||||
|
(for example because it has side effects that you don't want to
|
||||||
|
happen), use `t' to change the expression to something else which
|
||||||
|
Guile will evaluate instead.
|
||||||
|
|
||||||
|
There has to be a substitute expression so Guile can calculate a value
|
||||||
|
to return to the calling frame. If you know at a particular point
|
||||||
|
that the return value is not important, you can type `t #f <RET>' or
|
||||||
|
`t 0 <RET>'.
|
||||||
|
|
||||||
|
See `How do I change the expression that Guile is about to evaluate?'
|
||||||
|
above for more on using `t'.
|
||||||
|
|
||||||
|
** How do I move up and down the call stack?
|
||||||
|
|
||||||
|
Type `u' to move up and `d' to move down. "Up" in GDS means to a more
|
||||||
|
"inner" frame, and "down" means to a more "outer" frame.
|
||||||
|
|
||||||
|
** How do I run until the next breakpoint?
|
||||||
|
|
||||||
|
Type `g' (for "go").
|
||||||
|
|
||||||
|
** How do I run until the end of the selected stack frame?
|
||||||
|
|
||||||
|
Type `o'.
|
||||||
|
|
||||||
|
** How do I set a breakpoint?
|
||||||
|
|
||||||
|
First identify the code that you want to set the breakpoint in, and
|
||||||
|
what kind of breakpoint you want. To set a breakpoint on entry to a
|
||||||
|
top level procedure, move the cursor to anywhere in the procedure
|
||||||
|
definition, and make sure that the region/mark is inactive. To set a
|
||||||
|
breakpoint on a particular expression (or sequence of expressions) set
|
||||||
|
point and mark so that the region covers the opening parentheses of
|
||||||
|
all the target expressions.
|
||||||
|
|
||||||
|
Then type ...
|
||||||
|
|
||||||
|
`C-c C-b d' for a `debug' breakpoint, which means that GDS will
|
||||||
|
display the stack when the breakpoint is hit
|
||||||
|
|
||||||
|
`C-c C-b t' for a `trace' breakpoint, which means that the start and
|
||||||
|
end of the relevant procedure or expression(s) will be traced to the
|
||||||
|
*GDS Trace* buffer
|
||||||
|
|
||||||
|
`C-c C-b T' for a `trace-subtree' breakpoint, which means that every
|
||||||
|
evaluation step involved in the evaluation of the relevant procedure
|
||||||
|
or expression(s) will be traced to the *GDS Trace* buffer.
|
||||||
|
|
||||||
|
You can also type `C-x <SPC>', which does the same as one of the
|
||||||
|
above, depending on the value of `gds-default-breakpoint-type'.
|
||||||
|
|
||||||
|
** How do I clear a breakpoint?
|
||||||
|
|
||||||
|
Select a region containing the breakpoints that you want to clear, and
|
||||||
|
type `C-c C-b <DEL>'.
|
||||||
|
|
||||||
|
** How do I trace calls to a particular procedure or evaluations of a particular expression?
|
||||||
|
|
||||||
|
In GDS this means setting a breakpoint whose type is `trace' or
|
||||||
|
`trace-subtree'. See `How do I set a breakpoint?' above.
|
||||||
|
|
||||||
|
* Development
|
||||||
|
|
||||||
|
** How can I follow or contribute to guile-debugging's development?
|
||||||
|
|
||||||
|
guile-debugging is hosted at http://gna.org, so please see the project
|
||||||
|
page there. Feel free to raise bugs, tasks containing patches or
|
||||||
|
feature requests, and so on. You can also write directly to me by
|
||||||
|
email: <neil@ossau.uklinux.net>.
|
||||||
|
|
||||||
|
|
||||||
|
Local Variables:
|
||||||
|
mode: outline
|
||||||
|
End:
|
|
@ -206,23 +206,28 @@ Emacs to display an error or trap so that the user can debug it."
|
||||||
"-q"
|
"-q"
|
||||||
"--debug"
|
"--debug"
|
||||||
"-c"
|
"-c"
|
||||||
code))
|
code)))
|
||||||
(client nil))
|
|
||||||
;; Note that this process can be killed automatically on Emacs
|
;; Note that this process can be killed automatically on Emacs
|
||||||
;; exit.
|
;; exit.
|
||||||
(process-kill-without-query proc)
|
(process-kill-without-query proc)
|
||||||
;; Set up a process filter to catch the new client's number.
|
;; Set up a process filter to catch the new client's number.
|
||||||
(set-process-filter proc
|
(set-process-filter proc
|
||||||
(lambda (proc string)
|
(lambda (proc string)
|
||||||
(setq client (string-to-number string))
|
|
||||||
(if (process-buffer proc)
|
(if (process-buffer proc)
|
||||||
(with-current-buffer (process-buffer proc)
|
(with-current-buffer (process-buffer proc)
|
||||||
(insert string)))))
|
(insert string)
|
||||||
|
(or gds-client
|
||||||
|
(save-excursion
|
||||||
|
(goto-char (point-min))
|
||||||
|
(setq gds-client
|
||||||
|
(condition-case nil
|
||||||
|
(read (current-buffer))
|
||||||
|
(error nil)))))))))
|
||||||
;; Accept output from the new process until we have its number.
|
;; Accept output from the new process until we have its number.
|
||||||
(while (not client)
|
(while (not (with-current-buffer (process-buffer proc) gds-client))
|
||||||
(accept-process-output proc))
|
(accept-process-output proc))
|
||||||
;; Return the new process's client number.
|
;; Return the new process's client number.
|
||||||
client))
|
(with-current-buffer (process-buffer proc) gds-client)))
|
||||||
|
|
||||||
;;;; Evaluating code.
|
;;;; Evaluating code.
|
||||||
|
|
||||||
|
@ -419,11 +424,13 @@ through the code."
|
||||||
(map (make-sparse-keymap)))
|
(map (make-sparse-keymap)))
|
||||||
(define-key map [mouse-1] 'gds-show-last-stack)
|
(define-key map [mouse-1] 'gds-show-last-stack)
|
||||||
(define-key map "\C-m" 'gds-show-last-stack)
|
(define-key map "\C-m" 'gds-show-last-stack)
|
||||||
(insert "[click here to show error stack]")
|
(insert "[click here (or RET) to show error stack]")
|
||||||
(add-text-properties beg (point)
|
(add-text-properties beg (point)
|
||||||
(list 'keymap map
|
(list 'keymap map
|
||||||
'mouse-face 'highlight))
|
'mouse-face 'highlight))
|
||||||
(insert "\n")))
|
(insert "\n")
|
||||||
|
(add-text-properties (1- (point)) (point)
|
||||||
|
(list 'keymap map))))
|
||||||
(goto-char (point-min))
|
(goto-char (point-min))
|
||||||
(gds-associate-buffer client))
|
(gds-associate-buffer client))
|
||||||
(pop-to-buffer buf)
|
(pop-to-buffer buf)
|
||||||
|
|
|
@ -43,25 +43,24 @@
|
||||||
:group 'gds
|
:group 'gds
|
||||||
:type '(choice (const :tag "nil" nil) directory))
|
:type '(choice (const :tag "nil" nil) directory))
|
||||||
|
|
||||||
(defun gds-start-server (procname port-or-path protocol-handler &optional bufname)
|
(defun gds-start-server (procname unix-socket-name tcp-port protocol-handler)
|
||||||
"Start a GDS server process called PROCNAME, listening on TCP port
|
"Start a GDS server process called PROCNAME, listening on Unix
|
||||||
or Unix domain socket PORT-OR-PATH. PROTOCOL-HANDLER should be a
|
domain socket UNIX-SOCKET-NAME and TCP port number TCP-PORT.
|
||||||
function that accepts and processes one protocol form. Optional arg
|
PROTOCOL-HANDLER should be a function that accepts and processes
|
||||||
BUFNAME specifies the name of the buffer that is used for process
|
one protocol form."
|
||||||
output; if not specified the buffer name is the same as the process
|
(with-current-buffer (get-buffer-create procname)
|
||||||
name."
|
|
||||||
(with-current-buffer (get-buffer-create (or bufname procname))
|
|
||||||
(erase-buffer)
|
(erase-buffer)
|
||||||
(let* ((code (format "(begin
|
(let* ((code (format "(begin
|
||||||
%s
|
%s
|
||||||
(use-modules (ice-9 gds-server))
|
(use-modules (ice-9 gds-server))
|
||||||
(run-server %S))"
|
(run-server %S %S))"
|
||||||
(if gds-scheme-directory
|
(if gds-scheme-directory
|
||||||
(concat "(set! %load-path (cons "
|
(concat "(set! %load-path (cons "
|
||||||
(format "%S" gds-scheme-directory)
|
(format "%S" gds-scheme-directory)
|
||||||
" %load-path))")
|
" %load-path))")
|
||||||
"")
|
"")
|
||||||
port-or-path))
|
unix-socket-name
|
||||||
|
tcp-port))
|
||||||
(process-connection-type nil) ; use a pipe
|
(process-connection-type nil) ; use a pipe
|
||||||
(proc (start-process procname
|
(proc (start-process procname
|
||||||
(current-buffer)
|
(current-buffer)
|
||||||
|
|
166
emacs/gds-test.el
Normal file
166
emacs/gds-test.el
Normal file
|
@ -0,0 +1,166 @@
|
||||||
|
|
||||||
|
;; Test utility code.
|
||||||
|
(defun gds-test-execute-keys (keys &optional keys2)
|
||||||
|
(execute-kbd-macro (apply 'vector (listify-key-sequence keys))))
|
||||||
|
|
||||||
|
(defvar gds-test-expecting nil)
|
||||||
|
|
||||||
|
(defun gds-test-protocol-hook (form)
|
||||||
|
(message "[protocol: %s]" (car form))
|
||||||
|
(if (eq (car form) gds-test-expecting)
|
||||||
|
(setq gds-test-expecting nil)))
|
||||||
|
|
||||||
|
(defun gds-test-expect-protocol (proc &optional timeout)
|
||||||
|
(message "[expect: %s]" proc)
|
||||||
|
(setq gds-test-expecting proc)
|
||||||
|
(while gds-test-expecting
|
||||||
|
(or (accept-process-output gds-debug-server (or timeout 5))
|
||||||
|
(error "Timed out after %ds waiting for %s" (or timeout 5) proc))))
|
||||||
|
|
||||||
|
(defun gds-test-check-buffer (name &rest strings)
|
||||||
|
(let ((buf (or (get-buffer name) (error "No %s buffer" name))))
|
||||||
|
(save-excursion
|
||||||
|
(set-buffer buf)
|
||||||
|
(goto-char (point-min))
|
||||||
|
(while strings
|
||||||
|
(search-forward (car strings))
|
||||||
|
(setq strings (cdr strings))))))
|
||||||
|
|
||||||
|
(defun TEST (desc)
|
||||||
|
(message "TEST: %s" desc))
|
||||||
|
|
||||||
|
;; Make sure we take GDS elisp code from this code tree.
|
||||||
|
(setq load-path (cons (concat default-directory "emacs/") load-path))
|
||||||
|
|
||||||
|
;; Protect the tests so we can do some cleanups in case of error.
|
||||||
|
(unwind-protect
|
||||||
|
(progn
|
||||||
|
|
||||||
|
;; Visit the tutorial.
|
||||||
|
(find-file "gds-tutorial.txt")
|
||||||
|
|
||||||
|
(TEST "Load up GDS.")
|
||||||
|
(search-forward "(require 'gds)")
|
||||||
|
(setq load-path (cons (concat default-directory "emacs/") load-path))
|
||||||
|
(gds-test-execute-keys "\C-x\C-e")
|
||||||
|
|
||||||
|
;; Install our testing hook.
|
||||||
|
(add-hook 'gds-protocol-hook 'gds-test-protocol-hook)
|
||||||
|
|
||||||
|
(TEST "Help.")
|
||||||
|
(search-forward "(list-ref")
|
||||||
|
(backward-char 2)
|
||||||
|
(gds-test-execute-keys "\C-hg\C-m")
|
||||||
|
(gds-test-expect-protocol 'eval-results 10)
|
||||||
|
(gds-test-check-buffer "*Guile Help*"
|
||||||
|
"help list-ref"
|
||||||
|
"is a primitive procedure in the (guile) module")
|
||||||
|
|
||||||
|
(TEST "Completion.")
|
||||||
|
(re-search-forward "^with-output-to-s")
|
||||||
|
(gds-test-execute-keys "\e\C-i")
|
||||||
|
(beginning-of-line)
|
||||||
|
(or (looking-at "with-output-to-string")
|
||||||
|
(error "Expected completion `with-output-to-string' failed"))
|
||||||
|
|
||||||
|
(TEST "Eval defun.")
|
||||||
|
(search-forward "(display z)")
|
||||||
|
(gds-test-execute-keys "\e\C-x")
|
||||||
|
(gds-test-expect-protocol 'eval-results)
|
||||||
|
(gds-test-check-buffer "*Guile Evaluation*"
|
||||||
|
"(let ((x 1) (y 2))"
|
||||||
|
"Arctangent is: 0.46"
|
||||||
|
"=> 0.46")
|
||||||
|
|
||||||
|
(TEST "Multiple values.")
|
||||||
|
(search-forward "(values 'a ")
|
||||||
|
(gds-test-execute-keys "\e\C-x")
|
||||||
|
(gds-test-expect-protocol 'eval-results)
|
||||||
|
(gds-test-check-buffer "*Guile Evaluation*"
|
||||||
|
"(values 'a"
|
||||||
|
"hello world"
|
||||||
|
"=> a"
|
||||||
|
"=> b"
|
||||||
|
"=> c")
|
||||||
|
|
||||||
|
(TEST "Eval region with multiple expressions.")
|
||||||
|
(search-forward "(display \"Arctangent is: \")")
|
||||||
|
(beginning-of-line)
|
||||||
|
(push-mark nil nil t)
|
||||||
|
(forward-line 3)
|
||||||
|
(gds-test-execute-keys "\C-c\C-r")
|
||||||
|
(gds-test-expect-protocol 'eval-results)
|
||||||
|
(gds-test-check-buffer "*Guile Evaluation*"
|
||||||
|
"(display \"Arctangent is"
|
||||||
|
"Arctangent is:"
|
||||||
|
"=> no (or unspecified) value"
|
||||||
|
"ERROR: Unbound variable: z"
|
||||||
|
"=> error-in-evaluation"
|
||||||
|
"Evaluating expression 3"
|
||||||
|
"=> no (or unspecified) value")
|
||||||
|
|
||||||
|
(TEST "Eval syntactically unbalanced region.")
|
||||||
|
(search-forward "(let ((z (atan x y)))")
|
||||||
|
(beginning-of-line)
|
||||||
|
(push-mark nil nil t)
|
||||||
|
(forward-line 4)
|
||||||
|
(gds-test-execute-keys "\C-c\C-r")
|
||||||
|
(gds-test-expect-protocol 'eval-results)
|
||||||
|
(gds-test-check-buffer "*Guile Evaluation*"
|
||||||
|
"(let ((z (atan"
|
||||||
|
"Reading expressions to evaluate"
|
||||||
|
"ERROR"
|
||||||
|
"end of file"
|
||||||
|
"=> error-in-read")
|
||||||
|
|
||||||
|
(TEST "Stepping through an evaluation.")
|
||||||
|
(search-forward "(for-each (lambda (x)")
|
||||||
|
(forward-line 1)
|
||||||
|
(push-mark nil nil t)
|
||||||
|
(forward-line 1)
|
||||||
|
(gds-test-execute-keys "\C-u\e\C-x")
|
||||||
|
(gds-test-expect-protocol 'stack)
|
||||||
|
(gds-test-execute-keys " ")
|
||||||
|
(gds-test-expect-protocol 'stack)
|
||||||
|
(gds-test-execute-keys "o")
|
||||||
|
(gds-test-expect-protocol 'stack)
|
||||||
|
(gds-test-execute-keys "o")
|
||||||
|
(gds-test-expect-protocol 'stack)
|
||||||
|
(gds-test-execute-keys "o")
|
||||||
|
(gds-test-expect-protocol 'stack)
|
||||||
|
(gds-test-execute-keys "o")
|
||||||
|
(gds-test-expect-protocol 'stack)
|
||||||
|
(gds-test-execute-keys "o")
|
||||||
|
(gds-test-expect-protocol 'stack)
|
||||||
|
(gds-test-execute-keys "o")
|
||||||
|
(gds-test-expect-protocol 'stack)
|
||||||
|
(gds-test-execute-keys "o")
|
||||||
|
(gds-test-expect-protocol 'stack)
|
||||||
|
(gds-test-execute-keys "o")
|
||||||
|
(gds-test-expect-protocol 'stack)
|
||||||
|
(gds-test-execute-keys "o")
|
||||||
|
(gds-test-expect-protocol 'stack)
|
||||||
|
(gds-test-execute-keys "o")
|
||||||
|
(gds-test-expect-protocol 'stack)
|
||||||
|
(gds-test-execute-keys "g")
|
||||||
|
(gds-test-expect-protocol 'eval-results)
|
||||||
|
(gds-test-check-buffer "*Guile Evaluation*"
|
||||||
|
"(for-each (lambda"
|
||||||
|
"Evaluating in current module"
|
||||||
|
"3 cubed is 27"
|
||||||
|
"=> no (or unspecified) value")
|
||||||
|
|
||||||
|
;; Done.
|
||||||
|
(message "====================================")
|
||||||
|
(message "gds-test.el completed without errors")
|
||||||
|
(message "====================================")
|
||||||
|
|
||||||
|
)
|
||||||
|
|
||||||
|
(switch-to-buffer "gds-debug")
|
||||||
|
(write-region (point-min) (point-max) "gds-test.debug")
|
||||||
|
|
||||||
|
(switch-to-buffer "*GDS Transcript*")
|
||||||
|
(write-region (point-min) (point-max) "gds-test.transcript")
|
||||||
|
|
||||||
|
)
|
2
emacs/gds-test.sh
Executable file
2
emacs/gds-test.sh
Executable file
|
@ -0,0 +1,2 @@
|
||||||
|
#!/bin/sh
|
||||||
|
GUILE_LOAD_PATH=$(pwd) emacs --batch --no-site-file -q -l gds-test.el < gds-test.stdin
|
1
emacs/gds-test.stdin
Normal file
1
emacs/gds-test.stdin
Normal file
|
@ -0,0 +1 @@
|
||||||
|
|
223
emacs/gds-tutorial.txt
Executable file
223
emacs/gds-tutorial.txt
Executable file
|
@ -0,0 +1,223 @@
|
||||||
|
|
||||||
|
;; Welcome to the GDS tutorial!
|
||||||
|
|
||||||
|
;; This tutorial teaches the use of GDS by leading you through a set
|
||||||
|
;; of examples where you actually use GDS, in Emacs, along the way.
|
||||||
|
;; To get maximum benefit, therefore, you should be reading this
|
||||||
|
;; tutorial in Emacs.
|
||||||
|
|
||||||
|
;; ** GDS setup
|
||||||
|
|
||||||
|
;; The first thing to do, if you haven't already, is to load the GDS
|
||||||
|
;; library into Emacs. The Emacs Lisp expression for this is:
|
||||||
|
|
||||||
|
(require 'gds)
|
||||||
|
|
||||||
|
;; So, if you don't already have this in your .emacs, either add it
|
||||||
|
;; and then restart Emacs, or evaluate it just for this Emacs session
|
||||||
|
;; by moving the cursor to just after the closing parenthesis and
|
||||||
|
;; typing `C-x C-e'.
|
||||||
|
|
||||||
|
;; (Note that if you _have_ already loaded GDS, and you type `C-x C-e'
|
||||||
|
;; after this expression, you will see a *Guile Evaluation* window
|
||||||
|
;; telling you that the evaluation failed because `require' is
|
||||||
|
;; unbound. Don't worry; this is not a problem, and the rest of the
|
||||||
|
;; tutorial should still work just fine.)
|
||||||
|
|
||||||
|
;; ** Help
|
||||||
|
|
||||||
|
;; GDS makes it easy to access the Guile help system when working on a
|
||||||
|
;; Scheme program in Emacs. For example, suppose that you are writing
|
||||||
|
;; code that uses list-ref, and need to remind yourself about
|
||||||
|
;; list-ref's arguments ...
|
||||||
|
|
||||||
|
(define (penultimate l)
|
||||||
|
(list-ref
|
||||||
|
|
||||||
|
;; Just place the cursor on the word "list-ref" and type `C-h g RET'.
|
||||||
|
;; Try it now!
|
||||||
|
|
||||||
|
;; If GDS is working correctly, a window should have popped up above
|
||||||
|
;; or below showing the Guile help for list-ref.
|
||||||
|
|
||||||
|
;; You can also do an "apropos" search through Guile's help. If you
|
||||||
|
;; couldn't remember the name list-ref, for example, you could search
|
||||||
|
;; for anything matching "list" by typing `C-h C-g' and entering
|
||||||
|
;; "list" at the minibuffer prompt. Try doing this now: you should
|
||||||
|
;; see a longish list of Guile definitions whose names include "list".
|
||||||
|
;; As usual in Emacs, you can use `M-PageUp' and `M-PageDown' to
|
||||||
|
;; conveniently scroll the other window without having to select it.
|
||||||
|
|
||||||
|
;; The functions called by `C-h g' and `C-h C-g' are gds-help-symbol
|
||||||
|
;; and gds-apropos. They both look up the symbol or word at point by
|
||||||
|
;; default, but that default can be overidden by typing something else
|
||||||
|
;; at the minibuffer prompt.
|
||||||
|
|
||||||
|
;; ** Completion
|
||||||
|
|
||||||
|
;; As you are typing Scheme code, you can ask GDS to complete the
|
||||||
|
;; symbol before point for you, by typing `ESC TAB'. GDS selects
|
||||||
|
;; possible completions by matching the text so far against all
|
||||||
|
;; definitions in the Guile environment. (This may be contrasted with
|
||||||
|
;; the "dabbrev" completion performed by `M-/', which selects possible
|
||||||
|
;; completions from the contents of Emacs buffers. So, if you are
|
||||||
|
;; trying to complete "with-ou", to get "with-output-to-string", for
|
||||||
|
;; example, `ESC TAB' will always work, because with-output-to-string
|
||||||
|
;; is always defined in Guile's default environment, whereas `M-/'
|
||||||
|
;; will only work if one of Emacs's buffers happens to contain the
|
||||||
|
;; full name "with-output-to-string".)
|
||||||
|
|
||||||
|
;; To illustrate the idea, here are some partial names that you can
|
||||||
|
;; try completing. For each one, move the cursor to the end of the
|
||||||
|
;; line and type `ESC TAB' to try to complete it.
|
||||||
|
|
||||||
|
list-
|
||||||
|
with-ou
|
||||||
|
with-output-to-s
|
||||||
|
mkst
|
||||||
|
|
||||||
|
;; (If you are not familiar with any of the completed definitions,
|
||||||
|
;; feel free to use `C-h g' to find out about them!)
|
||||||
|
|
||||||
|
;; ** Evaluation
|
||||||
|
|
||||||
|
;; GDS provides several ways for you to evaluate Scheme code from
|
||||||
|
;; within Emacs.
|
||||||
|
|
||||||
|
;; Just like in Emacs Lisp, a single expression in a buffer can be
|
||||||
|
;; evaluated using `C-x C-e' or `C-M-x'. For `C-x C-e', the
|
||||||
|
;; expression is that which ends immediately before point (so that it
|
||||||
|
;; is useful for evaluating something just after you have typed it).
|
||||||
|
;; For `C-M-x', the expression is the "top level defun" around point;
|
||||||
|
;; this means the balanced chunk of code around point whose opening
|
||||||
|
;; parenthesis is in column 0.
|
||||||
|
|
||||||
|
;; Take this code fragment as an example:
|
||||||
|
|
||||||
|
(let ((x 1) (y 2))
|
||||||
|
(let ((z (atan x y)))
|
||||||
|
(display "Arctangent is: ")
|
||||||
|
(display z)
|
||||||
|
(newline)
|
||||||
|
z))
|
||||||
|
|
||||||
|
;; If you move the cursor to the end of the (display z) line and type
|
||||||
|
;; `C-x C-e', the code evaluated is just "(display z)", which normally
|
||||||
|
;; produces an error, because z is not defined in the usual Guile
|
||||||
|
;; environment. If, however, you type `C-M-x' with the cursor in the
|
||||||
|
;; same place, the code evaluated is the whole "(let ((x 1) (y 2))
|
||||||
|
;; ...)" kaboodle, because that is the most recent expression before
|
||||||
|
;; point that starts in column 0.
|
||||||
|
|
||||||
|
;; Try these now. The Guile Evaluation window should pop up again,
|
||||||
|
;; and show you:
|
||||||
|
;; - the expression that was evaluated (probably abbreviated)
|
||||||
|
;; - the module that it was evaluated in
|
||||||
|
;; - anything that the code wrote to its standard output
|
||||||
|
;; - the return value(s) of the evaluation.
|
||||||
|
;; Following the convention of the Emacs Lisp and Guile manuals,
|
||||||
|
;; return values are indicated by the symbol "=>".
|
||||||
|
|
||||||
|
;; To see what happens when an expression has multiple return values,
|
||||||
|
;; try evaluating this one:
|
||||||
|
|
||||||
|
(values 'a (begin (display "hello world\n") 'b) 'c)
|
||||||
|
|
||||||
|
;; You can also evaluate a region of a buffer using `C-c C-r'. If the
|
||||||
|
;; code in the region consists of multiple expressions, GDS evaluates
|
||||||
|
;; them sequentially. For example, try selecting the following three
|
||||||
|
;; lines and typing `C-c C-r'.
|
||||||
|
|
||||||
|
(display "Arctangent is: ")
|
||||||
|
(display z)
|
||||||
|
(newline)
|
||||||
|
|
||||||
|
;; If the code in the region evaluated isn't syntactically balanced,
|
||||||
|
;; GDS will indicate a read error, for example for this code:
|
||||||
|
|
||||||
|
(let ((z (atan x y)))
|
||||||
|
(display "Arctangent is: ")
|
||||||
|
(display z)
|
||||||
|
(newline)
|
||||||
|
|
||||||
|
;; Finally, if you want to evaluate something quickly that is not in a
|
||||||
|
;; buffer, you can use `C-c C-e' and type the code to evaluate at the
|
||||||
|
;; minibuffer prompt. The results are popped up in the same way as
|
||||||
|
;; for code from a buffer.
|
||||||
|
|
||||||
|
;; ** Breakpoints
|
||||||
|
|
||||||
|
;; Before evaluating Scheme code from an Emacs buffer, you may want to
|
||||||
|
;; set some breakpoints in it. With GDS you can set breakpoints in
|
||||||
|
;; Scheme code by typing `C-x SPC'.
|
||||||
|
;;
|
||||||
|
;; To see how this works, select the second line of the following code
|
||||||
|
;; (the `(format ...)' line) and type `C-x SPC'.
|
||||||
|
|
||||||
|
(for-each (lambda (x)
|
||||||
|
(format #t "~A cubed is ~A\n" x (* x x x)))
|
||||||
|
(iota 6))
|
||||||
|
|
||||||
|
;; The two opening parentheses in that line should now be highlighted
|
||||||
|
;; in red, to show that breakpoints have been set at the start of the
|
||||||
|
;; `(format ...)' and `(* x x x)' expressions. Then evaluate the
|
||||||
|
;; whole for-each expression by typing `C-M-x' ...
|
||||||
|
;;
|
||||||
|
;; In the upper half of your Emacs, a buffer appears showing you the
|
||||||
|
;; Scheme stack.
|
||||||
|
;;
|
||||||
|
;; In the lower half, the `(format ...)' expression is highlighted.
|
||||||
|
;;
|
||||||
|
;; What has happened is that Guile started evaluating the for-each
|
||||||
|
;; code, but then hit the breakpoint that you set on the start of the
|
||||||
|
;; format expression. Guile therefore pauses the evaluation at that
|
||||||
|
;; point and passes the stack (which encapsulates everything that is
|
||||||
|
;; interesting about the state of Guile at that point) to GDS. You
|
||||||
|
;; can then explore the stack and decide how to tell Guile to
|
||||||
|
;; continue.
|
||||||
|
;;
|
||||||
|
;; - If you move your mouse over any of the identifiers in the
|
||||||
|
;; highlighted code, a help echo (or tooltip) will appear to tell
|
||||||
|
;; you that identifier's current value. (Note though that this only
|
||||||
|
;; works when the stack buffer is selected. So if you have switched
|
||||||
|
;; to this buffer in order to scroll down and read these lines, you
|
||||||
|
;; will need to switch back to the stack buffer before trying this
|
||||||
|
;; out.)
|
||||||
|
;;
|
||||||
|
;; - In the stack buffer, the "=>" on the left shows you that the top
|
||||||
|
;; frame is currently selected. You can move up and down the stack
|
||||||
|
;; by pressing the up and down arrows (or `u' and `d'). As you do
|
||||||
|
;; this, GDS will change the highlight in the lower window to show
|
||||||
|
;; the code that corresponds to the selected stack frame.
|
||||||
|
;;
|
||||||
|
;; - You can evaluate an arbitrary expression in the local environment
|
||||||
|
;; of the selected stack frame by typing `e' followed by the
|
||||||
|
;; expression.
|
||||||
|
;;
|
||||||
|
;; - You can show various bits of information about the selected frame
|
||||||
|
;; by typing `I', `A' and `S'. Feel free to try these now, to see
|
||||||
|
;; what they do.
|
||||||
|
;;
|
||||||
|
;; You also have control over the continuing evaluation of this code.
|
||||||
|
;; Here are some of the things you can do - please try them as you
|
||||||
|
;; read.
|
||||||
|
;;
|
||||||
|
;; - `g' tells Guile to continue execution normally. In this case
|
||||||
|
;; that means that evaluation will continue until it hits the next
|
||||||
|
;; breakpoint, which is on the `(* x x x)' expression.
|
||||||
|
;;
|
||||||
|
;; - `SPC' tells Guile to continue until the next significant event in
|
||||||
|
;; the same source file as the selected frame. A "significant
|
||||||
|
;; event" means either beginning to evaluate an expression in the
|
||||||
|
;; relevant file, or completing such an evaluation, in which case
|
||||||
|
;; GDS tells you the value that it is returning. Pressing `SPC'
|
||||||
|
;; repeatedly is a nice way to step through all the details of the
|
||||||
|
;; code in a given file, but stepping over calls that involve code
|
||||||
|
;; from other files.
|
||||||
|
;;
|
||||||
|
;; - `o' tells Guile to continue execution until the selected stack
|
||||||
|
;; frame completes, and then to show its return value.
|
||||||
|
|
||||||
|
;; Local Variables:
|
||||||
|
;; mode: scheme
|
||||||
|
;; End:
|
27
emacs/gds.el
27
emacs/gds.el
|
@ -36,10 +36,11 @@
|
||||||
;; The subprocess object for the debug server.
|
;; The subprocess object for the debug server.
|
||||||
(defvar gds-debug-server nil)
|
(defvar gds-debug-server nil)
|
||||||
|
|
||||||
(defvar gds-socket-type-alist '((tcp . 8333)
|
(defvar gds-unix-socket-name (format "/tmp/.gds-socket-%d" (emacs-pid))
|
||||||
(unix . "/tmp/.gds_socket"))
|
"Name of the Unix domain socket that GDS will listen on.")
|
||||||
"Maps each of the possible socket types that the GDS server can
|
|
||||||
listen on to the path that it should bind to for each one.")
|
(defvar gds-tcp-port 8333
|
||||||
|
"The TCP port number that GDS will listen on.")
|
||||||
|
|
||||||
(defun gds-run-debug-server ()
|
(defun gds-run-debug-server ()
|
||||||
"Start (or restart, if already running) the GDS debug server process."
|
"Start (or restart, if already running) the GDS debug server process."
|
||||||
|
@ -47,10 +48,14 @@ listen on to the path that it should bind to for each one.")
|
||||||
(if gds-debug-server (gds-kill-debug-server))
|
(if gds-debug-server (gds-kill-debug-server))
|
||||||
(setq gds-debug-server
|
(setq gds-debug-server
|
||||||
(gds-start-server "gds-debug"
|
(gds-start-server "gds-debug"
|
||||||
(cdr (assq gds-server-socket-type
|
gds-unix-socket-name
|
||||||
gds-socket-type-alist))
|
gds-tcp-port
|
||||||
'gds-debug-protocol))
|
'gds-debug-protocol))
|
||||||
(process-kill-without-query gds-debug-server))
|
(process-kill-without-query gds-debug-server)
|
||||||
|
;; Add the Unix socket name to the environment, so that Guile
|
||||||
|
;; clients started from within this Emacs will be able to use it,
|
||||||
|
;; and thereby ensure that they connect to the GDS in this Emacs.
|
||||||
|
(setenv "GDS_UNIX_SOCKET_NAME" gds-unix-socket-name))
|
||||||
|
|
||||||
(defun gds-kill-debug-server ()
|
(defun gds-kill-debug-server ()
|
||||||
"Kill the GDS debug server process."
|
"Kill the GDS debug server process."
|
||||||
|
@ -137,7 +142,13 @@ listen on to the path that it should bind to for each one.")
|
||||||
|
|
||||||
;;;; Debugger protocol
|
;;;; Debugger protocol
|
||||||
|
|
||||||
|
(defcustom gds-protocol-hook nil
|
||||||
|
"Hook called on receipt of a protocol form from the GDS client."
|
||||||
|
:type 'hook
|
||||||
|
:group 'gds)
|
||||||
|
|
||||||
(defun gds-debug-protocol (client form)
|
(defun gds-debug-protocol (client form)
|
||||||
|
(run-hook-with-args 'gds-protocol-hook form)
|
||||||
(or (eq client '*)
|
(or (eq client '*)
|
||||||
(let ((proc (car form)))
|
(let ((proc (car form)))
|
||||||
(cond ((eq proc 'name)
|
(cond ((eq proc 'name)
|
||||||
|
@ -610,7 +621,7 @@ you would add an element to this alist to transform
|
||||||
:group 'gds)
|
:group 'gds)
|
||||||
|
|
||||||
(defcustom gds-server-socket-type 'tcp
|
(defcustom gds-server-socket-type 'tcp
|
||||||
"What kind of socket the GDS server should listen on."
|
"This option is now obsolete and has no effect."
|
||||||
:group 'gds
|
:group 'gds
|
||||||
:type '(choice (const :tag "TCP" tcp)
|
:type '(choice (const :tag "TCP" tcp)
|
||||||
(const :tag "Unix" unix)))
|
(const :tag "Unix" unix)))
|
||||||
|
|
|
@ -38,8 +38,8 @@ EXTRA_DIST = README ChangeLog-2008 check.test \
|
||||||
\
|
\
|
||||||
safe/README safe/safe safe/untrusted.scm safe/evil.scm
|
safe/README safe/safe safe/untrusted.scm safe/evil.scm
|
||||||
|
|
||||||
AM_CFLAGS = `PATH=$(bindir):$$PATH PKG_CONFIG_PATH=$(libdir)/pkgconfig $(bindir)/guile-config compile`
|
AM_CFLAGS = `PATH=$(bindir)$(PATH_SEPARATOR)$$PATH PKG_CONFIG_PATH=$(libdir)/pkgconfig $(bindir)/guile-config compile`
|
||||||
AM_LIBS = `PATH=$(bindir):$$PATH PKG_CONFIG_PATH=$(libdir)/pkgconfig $(bindir)/guile-config link`
|
AM_LIBS = `PATH=$(bindir)$(PATH_SEPARATOR)$$PATH PKG_CONFIG_PATH=$(libdir)/pkgconfig $(bindir)/guile-config link`
|
||||||
|
|
||||||
|
|
||||||
box/box: box/box.o
|
box/box: box/box.o
|
||||||
|
@ -77,10 +77,10 @@ box-dynamic-module/box.lo: box-dynamic-module/box.c
|
||||||
|
|
||||||
|
|
||||||
installcheck: box/box box-module/box libbox.la libbox-module.la
|
installcheck: box/box box-module/box libbox.la libbox-module.la
|
||||||
LD_LIBRARY_PATH="$(libdir):$$LD_LIBRARY_PATH" \
|
LD_LIBRARY_PATH="$(libdir)$(PATH_SEPARATOR)$$LD_LIBRARY_PATH" \
|
||||||
LTDL_LIBRARY_PATH="$(builddir):$$LTDL_LIBRARY_PATH" \
|
LTDL_LIBRARY_PATH="$(builddir)$(PATH_SEPARATOR)$$LTDL_LIBRARY_PATH" \
|
||||||
GUILE_LOAD_PATH="$(abs_top_srcdir):$$GUILE_LOAD_PATH" \
|
GUILE_LOAD_PATH="$(abs_top_srcdir)$(PATH_SEPARATOR)$$GUILE_LOAD_PATH" \
|
||||||
PATH="$(bindir):$$PATH" \
|
PATH="$(bindir)$(PATH_SEPARATOR)$$PATH" \
|
||||||
GUILE_AUTO_COMPILE=0 \
|
GUILE_AUTO_COMPILE=0 \
|
||||||
srcdir="$(srcdir)" \
|
srcdir="$(srcdir)" \
|
||||||
$(srcdir)/check.test
|
$(srcdir)/check.test
|
||||||
|
|
|
@ -12,7 +12,7 @@ AC_DEFUN([GUILE_COMPAT],
|
||||||
ac_cv_have_scm_t_bits=no)])
|
ac_cv_have_scm_t_bits=no)])
|
||||||
AC_MSG_RESULT($ac_cv_have_scm_t_bits)
|
AC_MSG_RESULT($ac_cv_have_scm_t_bits)
|
||||||
if test $ac_cv_have_scm_t_bits = yes; then
|
if test $ac_cv_have_scm_t_bits = yes; then
|
||||||
AC_DEFINE(HAVE_SCM_T_BITS)
|
AC_DEFINE([HAVE_SCM_T_BITS])
|
||||||
fi
|
fi
|
||||||
LIBS="$guile_compat_save_LIBS"
|
LIBS="$guile_compat_save_LIBS"
|
||||||
CFLAGS="$guile_compat_save_CFLAGS"])
|
CFLAGS="$guile_compat_save_CFLAGS"])
|
||||||
|
|
File diff suppressed because one or more lines are too long
|
@ -4,7 +4,7 @@ exec ${GUILE-guile} -q -l "$0" \
|
||||||
-c '(apply main (cdr (command-line)))' \
|
-c '(apply main (cdr (command-line)))' \
|
||||||
--benchmark-dir="$(dirname $0)" "$@"
|
--benchmark-dir="$(dirname $0)" "$@"
|
||||||
!#
|
!#
|
||||||
;;; Copyright (C) 2008 Free Software Foundation, Inc.
|
;;; Copyright (C) 2008, 2009 Free Software Foundation, Inc.
|
||||||
;;;
|
;;;
|
||||||
;;; This program is free software; you can redistribute it and/or
|
;;; This program is free software; you can redistribute it and/or
|
||||||
;;; modify it under the terms of the GNU Lesser General Public License
|
;;; modify it under the terms of the GNU Lesser General Public License
|
||||||
|
@ -25,6 +25,7 @@ exec ${GUILE-guile} -q -l "$0" \
|
||||||
(ice-9 popen)
|
(ice-9 popen)
|
||||||
(ice-9 regex)
|
(ice-9 regex)
|
||||||
(ice-9 format)
|
(ice-9 format)
|
||||||
|
(ice-9 pretty-print)
|
||||||
(srfi srfi-1)
|
(srfi srfi-1)
|
||||||
(srfi srfi-37))
|
(srfi srfi-37))
|
||||||
|
|
||||||
|
@ -103,23 +104,64 @@ exec ${GUILE-guile} -q -l "$0" \
|
||||||
result)))
|
result)))
|
||||||
|
|
||||||
(define (pretty-print-result benchmark reference bdwgc)
|
(define (pretty-print-result benchmark reference bdwgc)
|
||||||
|
(define ref-heap (assoc-ref reference 'heap-size))
|
||||||
|
(define ref-time (assoc-ref reference 'execution-time))
|
||||||
|
|
||||||
|
(define (distance x1 y1 x2 y2)
|
||||||
|
;; Return the distance between (X1,Y1) and (X2,Y2). Y is the heap size,
|
||||||
|
;; in MiB and X is the execution time in seconds.
|
||||||
|
(let ((y1 (/ y1 (expt 2 20)))
|
||||||
|
(y2 (/ y2 (expt 2 20))))
|
||||||
|
(sqrt (+ (expt (- y1 y2) 2)
|
||||||
|
(expt (- x1 x2) 2)))))
|
||||||
|
|
||||||
|
(define (score time heap)
|
||||||
|
;; Return a score lower than +1.0. The score is positive if the
|
||||||
|
;; distance to the origin of (TIME,HEAP) is smaller than that of
|
||||||
|
;; (REF-TIME,REF-HEAP), negative otherwise.
|
||||||
|
|
||||||
|
;; heap ^ .
|
||||||
|
;; size | . worse
|
||||||
|
;; | . [-]
|
||||||
|
;; | .
|
||||||
|
;; | . . . .ref. . . .
|
||||||
|
;; | .
|
||||||
|
;; | [+] .
|
||||||
|
;; | better .
|
||||||
|
;; 0 +-------------------->
|
||||||
|
;; exec. time
|
||||||
|
|
||||||
|
(let ((ref-dist (distance ref-time ref-heap 0 0))
|
||||||
|
(dist (distance time heap 0 0)))
|
||||||
|
(/ (- ref-dist dist) ref-dist)))
|
||||||
|
|
||||||
|
(define (score-string time heap)
|
||||||
|
;; Return a string denoting a bar to illustrate the score of (TIME,HEAP)
|
||||||
|
;; relative to (REF-TIME,REF-HEAP).
|
||||||
|
(define %max-width 15)
|
||||||
|
|
||||||
|
(let ((s (score time heap)))
|
||||||
|
(make-string (inexact->exact (round (* (if (< s 0.0) (- s) s)
|
||||||
|
%max-width)))
|
||||||
|
(if (< s 0.0)
|
||||||
|
#\-
|
||||||
|
#\+))))
|
||||||
|
|
||||||
(define (print-line name result ref?)
|
(define (print-line name result ref?)
|
||||||
(let ((name (string-pad-right name 23))
|
(let ((name (string-pad-right name 23))
|
||||||
(time (assoc-ref result 'execution-time))
|
(time (assoc-ref result 'execution-time))
|
||||||
(heap (assoc-ref result 'heap-size))
|
(heap (assoc-ref result 'heap-size)))
|
||||||
(ref-heap (assoc-ref reference 'heap-size))
|
(format #t "~a ~6,2f (~,2fx) ~7,3f (~,2fx)~A~%"
|
||||||
(ref-time (assoc-ref reference 'execution-time)))
|
|
||||||
(format #t "~a ~1,2f (~,2fx) ~6,3f (~,2fx)~A~%"
|
|
||||||
name
|
name
|
||||||
(/ heap 1000000.0) (/ heap ref-heap 1.0)
|
(/ heap (expt 2.0 20)) (/ heap ref-heap 1.0)
|
||||||
time (/ time ref-time 1.0)
|
time (/ time ref-time 1.0)
|
||||||
(if (and (not ref?)
|
(if (not ref?)
|
||||||
(<= heap ref-heap) (<= time ref-time))
|
(string-append " "
|
||||||
" !"
|
(score-string time heap))
|
||||||
""))))
|
""))))
|
||||||
|
|
||||||
(format #t "benchmark: `~a'~%" benchmark)
|
(format #t "benchmark: `~a'~%" benchmark)
|
||||||
(format #t " heap size (MiB) execution time (s.)~%")
|
(format #t " heap size (MiB) execution time (s.)~%")
|
||||||
(print-line "Guile" reference #t)
|
(print-line "Guile" reference #t)
|
||||||
(for-each (lambda (bdwgc)
|
(for-each (lambda (bdwgc)
|
||||||
(let ((name (format #f "BDW-GC, FSD=~a~a"
|
(let ((name (format #f "BDW-GC, FSD=~a~a"
|
||||||
|
@ -134,6 +176,12 @@ exec ${GUILE-guile} -q -l "$0" \
|
||||||
(print-line name bdwgc #f)))
|
(print-line name bdwgc #f)))
|
||||||
bdwgc))
|
bdwgc))
|
||||||
|
|
||||||
|
(define (print-raw-result benchmark reference bdwgc)
|
||||||
|
(pretty-print `(,benchmark
|
||||||
|
(reference . ,reference)
|
||||||
|
(bdw-gc . ,bdwgc))))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
;;;
|
;;;
|
||||||
;;; Option processing.
|
;;; Option processing.
|
||||||
|
@ -170,14 +218,22 @@ exec ${GUILE-guile} -q -l "$0" \
|
||||||
(lambda (opt name arg result)
|
(lambda (opt name arg result)
|
||||||
(alist-cons 'log-port (open-output-file arg)
|
(alist-cons 'log-port (open-output-file arg)
|
||||||
(alist-delete 'log-port result
|
(alist-delete 'log-port result
|
||||||
eq?))))))
|
eq?))))
|
||||||
|
(option '("raw") #f #f
|
||||||
|
(lambda (opt name arg result)
|
||||||
|
(alist-cons 'printer print-raw-result
|
||||||
|
(alist-delete 'printer result eq?))))
|
||||||
|
(option '("load-results") #f #f
|
||||||
|
(lambda (opt name arg result)
|
||||||
|
(alist-cons 'load-results? #t result)))))
|
||||||
|
|
||||||
(define %default-options
|
(define %default-options
|
||||||
`((reference-environment . "GUILE=guile")
|
`((reference-environment . "GUILE=guile")
|
||||||
(benchmark-directory . "./gc-benchmarks")
|
(benchmark-directory . "./gc-benchmarks")
|
||||||
(log-port . ,(current-output-port))
|
(log-port . ,(current-output-port))
|
||||||
(profile-options . "")
|
(profile-options . "")
|
||||||
(input . ())))
|
(input . ())
|
||||||
|
(printer . ,pretty-print-result)))
|
||||||
|
|
||||||
(define (show-help)
|
(define (show-help)
|
||||||
(format #t "Usage: run-benchmark [OPTIONS] BENCHMARKS...
|
(format #t "Usage: run-benchmark [OPTIONS] BENCHMARKS...
|
||||||
|
@ -199,6 +255,12 @@ comparison of standard Guile (1.9) and the BDW-GC-based Guile.
|
||||||
Pass OPTS as additional options for `gc-profile.scm'.
|
Pass OPTS as additional options for `gc-profile.scm'.
|
||||||
-l, --log-file=FILE
|
-l, --log-file=FILE
|
||||||
Save output to FILE instead of the standard output.
|
Save output to FILE instead of the standard output.
|
||||||
|
|
||||||
|
--raw Write benchmark results in raw (s-exp) format.
|
||||||
|
--load-results
|
||||||
|
Load raw (s-exp) results instead of actually running
|
||||||
|
the benchmarks.
|
||||||
|
|
||||||
-d, --benchmark-dir=DIR
|
-d, --benchmark-dir=DIR
|
||||||
Use DIR as the GC benchmark directory where `gc-profile.scm'
|
Use DIR as the GC benchmark directory where `gc-profile.scm'
|
||||||
lives (it is automatically determined by default).
|
lives (it is automatically determined by default).
|
||||||
|
@ -234,36 +296,54 @@ Report bugs to <bug-guile@gnu.org>.~%"))
|
||||||
(bdwgc-env (or (assoc-ref args 'bdwgc-environment)
|
(bdwgc-env (or (assoc-ref args 'bdwgc-environment)
|
||||||
(string-append "GUILE=" bench-dir
|
(string-append "GUILE=" bench-dir
|
||||||
"/../meta/guile")))
|
"/../meta/guile")))
|
||||||
(prof-opts (assoc-ref args 'profile-options)))
|
(prof-opts (assoc-ref args 'profile-options))
|
||||||
(for-each (lambda (benchmark)
|
(print (assoc-ref args 'printer)))
|
||||||
(let ((ref (parse-result (run-reference-guile ref-env
|
(define (run benchmark)
|
||||||
bench-dir
|
(let ((ref (parse-result (run-reference-guile ref-env
|
||||||
prof-opts
|
bench-dir
|
||||||
benchmark)))
|
prof-opts
|
||||||
(bdwgc (map (lambda (fsd incremental?
|
benchmark)))
|
||||||
generational? parallel?)
|
(bdwgc (map (lambda (fsd incremental?
|
||||||
(let ((opts
|
generational? parallel?)
|
||||||
(list
|
(let ((opts
|
||||||
(cons 'free-space-divisor fsd)
|
(list
|
||||||
(cons 'incremental? incremental?)
|
(cons 'free-space-divisor fsd)
|
||||||
(cons 'generational? generational?)
|
(cons 'incremental? incremental?)
|
||||||
(cons 'parallel? parallel?))))
|
(cons 'generational? generational?)
|
||||||
(append opts
|
(cons 'parallel? parallel?))))
|
||||||
(parse-result
|
(append opts
|
||||||
(run-bdwgc-guile bdwgc-env
|
(parse-result
|
||||||
bench-dir
|
(run-bdwgc-guile bdwgc-env
|
||||||
prof-opts
|
bench-dir
|
||||||
opts
|
prof-opts
|
||||||
benchmark)))))
|
opts
|
||||||
'( 3 6 9 3 3)
|
benchmark)))))
|
||||||
'(#f #f #f #t #f) ;; incremental
|
'( 3 6 9 3 3)
|
||||||
'(#f #f #f #f #t) ;; generational
|
'(#f #f #f #t #f) ;; incremental
|
||||||
'(#f #f #f #f #f)))) ;; parallel
|
'(#f #f #f #f #t) ;; generational
|
||||||
;;(format #t "ref=~A~%" ref)
|
'(#f #f #f #f #f)))) ;; parallel
|
||||||
;;(format #t "bdw-gc=~A~%" bdwgc)
|
`(,benchmark
|
||||||
|
(reference . ,ref)
|
||||||
|
(bdw-gc . ,bdwgc))))
|
||||||
|
|
||||||
|
(define (load-results file)
|
||||||
|
(with-input-from-file file
|
||||||
|
(lambda ()
|
||||||
|
(let loop ((results '()) (o (read)))
|
||||||
|
(if (eof-object? o)
|
||||||
|
(reverse results)
|
||||||
|
(loop (cons o results)
|
||||||
|
(read)))))))
|
||||||
|
|
||||||
|
(for-each (lambda (result)
|
||||||
|
(let ((benchmark (car result))
|
||||||
|
(ref (assoc-ref (cdr result) 'reference))
|
||||||
|
(bdwgc (assoc-ref (cdr result) 'bdw-gc)))
|
||||||
(with-output-to-port log
|
(with-output-to-port log
|
||||||
(lambda ()
|
(lambda ()
|
||||||
(pretty-print-result benchmark ref bdwgc)
|
(print benchmark ref bdwgc)
|
||||||
(newline)
|
(newline)
|
||||||
(force-output)))))
|
(force-output)))))
|
||||||
benchmark-files))))
|
(if (assoc-ref args 'load-results?)
|
||||||
|
(append-map load-results benchmark-files)
|
||||||
|
(map run benchmark-files))))))
|
||||||
|
|
7
gdbinit
7
gdbinit
|
@ -1,5 +1,8 @@
|
||||||
# -*- GDB-Script -*-
|
# -*- GDB-Script -*-
|
||||||
|
|
||||||
|
handle SIGPWR noprint nostop
|
||||||
|
handle SIGXCPU noprint nostop
|
||||||
|
|
||||||
define newline
|
define newline
|
||||||
call (void)scm_newline (scm_current_error_port ())
|
call (void)scm_newline (scm_current_error_port ())
|
||||||
end
|
end
|
||||||
|
@ -195,3 +198,7 @@ end
|
||||||
define inst
|
define inst
|
||||||
p scm_instruction_table[$arg0]
|
p scm_instruction_table[$arg0]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
define gbt
|
||||||
|
call scm_display_backtrace (scm_make_stack(0x404,0x304), scm_current_error_port (), 0x704, 0x704, 0x704)
|
||||||
|
end
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
;;;; readline.scm --- support functions for command-line editing
|
;;;; readline.scm --- support functions for command-line editing
|
||||||
;;;;
|
;;;;
|
||||||
;;;; Copyright (C) 1997, 1999, 2000, 2001, 2002, 2006 Free Software Foundation, Inc.
|
;;;; Copyright (C) 1997, 1999, 2000, 2001, 2002, 2006, 2009 Free Software Foundation, Inc.
|
||||||
;;;;
|
;;;;
|
||||||
;;;; This program is free software; you can redistribute it and/or modify
|
;;;; This program is free software; you can redistribute it and/or modify
|
||||||
;;;; it under the terms of the GNU General Public License as published by
|
;;;; it under the terms of the GNU General Public License as published by
|
||||||
|
@ -24,11 +24,15 @@
|
||||||
|
|
||||||
|
|
||||||
(define-module (ice-9 readline)
|
(define-module (ice-9 readline)
|
||||||
:use-module (ice-9 session)
|
#:use-module (ice-9 session)
|
||||||
:use-module (ice-9 regex)
|
#:use-module (ice-9 regex)
|
||||||
:use-module (ice-9 buffered-input)
|
#:use-module (ice-9 buffered-input)
|
||||||
:no-backtrace
|
#:no-backtrace
|
||||||
:export (filename-completion-function))
|
#:export (filename-completion-function
|
||||||
|
add-history
|
||||||
|
read-history
|
||||||
|
write-history
|
||||||
|
clear-history))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -204,7 +208,7 @@
|
||||||
(let ((repl-read-hook (lambda () (run-hook before-read-hook))))
|
(let ((repl-read-hook (lambda () (run-hook before-read-hook))))
|
||||||
(set-current-input-port (readline-port))
|
(set-current-input-port (readline-port))
|
||||||
(set! repl-reader
|
(set! repl-reader
|
||||||
(lambda (repl-prompt)
|
(lambda (repl-prompt . reader)
|
||||||
(let ((outer-new-input-prompt new-input-prompt)
|
(let ((outer-new-input-prompt new-input-prompt)
|
||||||
(outer-continuation-prompt continuation-prompt)
|
(outer-continuation-prompt continuation-prompt)
|
||||||
(outer-read-hook read-hook))
|
(outer-read-hook read-hook))
|
||||||
|
@ -213,7 +217,9 @@
|
||||||
(set-buffered-input-continuation?! (readline-port) #f)
|
(set-buffered-input-continuation?! (readline-port) #f)
|
||||||
(set-readline-prompt! repl-prompt "... ")
|
(set-readline-prompt! repl-prompt "... ")
|
||||||
(set-readline-read-hook! repl-read-hook))
|
(set-readline-read-hook! repl-read-hook))
|
||||||
(lambda () ((or (fluid-ref current-reader) read)))
|
(lambda () ((or (and (pair? reader) (car reader))
|
||||||
|
(fluid-ref current-reader)
|
||||||
|
read)))
|
||||||
(lambda ()
|
(lambda ()
|
||||||
(set-readline-prompt! outer-new-input-prompt outer-continuation-prompt)
|
(set-readline-prompt! outer-new-input-prompt outer-continuation-prompt)
|
||||||
(set-readline-read-hook! outer-read-hook))))))
|
(set-readline-read-hook! outer-read-hook))))))
|
||||||
|
|
|
@ -128,6 +128,7 @@ rl_free_line_state ()
|
||||||
|
|
||||||
static int promptp;
|
static int promptp;
|
||||||
static SCM input_port;
|
static SCM input_port;
|
||||||
|
static SCM output_port;
|
||||||
static SCM before_read;
|
static SCM before_read;
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
@ -138,7 +139,7 @@ current_input_getc (FILE *in SCM_UNUSED)
|
||||||
scm_apply (before_read, SCM_EOL, SCM_EOL);
|
scm_apply (before_read, SCM_EOL, SCM_EOL);
|
||||||
promptp = 0;
|
promptp = 0;
|
||||||
}
|
}
|
||||||
return scm_getc (input_port);
|
return scm_get_byte_or_eof (input_port);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int in_readline = 0;
|
static int in_readline = 0;
|
||||||
|
@ -255,7 +256,12 @@ internal_readline (SCM text)
|
||||||
promptp = 1;
|
promptp = 1;
|
||||||
s = readline (prompt);
|
s = readline (prompt);
|
||||||
if (s)
|
if (s)
|
||||||
ret = scm_from_locale_string (s);
|
{
|
||||||
|
scm_t_port *pt = SCM_PTAB_ENTRY (output_port);
|
||||||
|
|
||||||
|
ret = scm_from_stringn (s, strlen (s), pt->encoding,
|
||||||
|
SCM_FAILED_CONVERSION_ESCAPE_SEQUENCE);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
ret = SCM_EOF_VAL;
|
ret = SCM_EOF_VAL;
|
||||||
|
|
||||||
|
@ -311,6 +317,7 @@ scm_readline_init_ports (SCM inp, SCM outp)
|
||||||
}
|
}
|
||||||
|
|
||||||
input_port = inp;
|
input_port = inp;
|
||||||
|
output_port = outp;
|
||||||
#ifndef __MINGW32__
|
#ifndef __MINGW32__
|
||||||
rl_instream = stream_from_fport (inp, "r", s_scm_readline);
|
rl_instream = stream_from_fport (inp, "r", s_scm_readline);
|
||||||
rl_outstream = stream_from_fport (outp, "w", s_scm_readline);
|
rl_outstream = stream_from_fport (outp, "w", s_scm_readline);
|
||||||
|
@ -550,7 +557,7 @@ scm_init_readline ()
|
||||||
rl_basic_word_break_characters = "\t\n\"'`;()";
|
rl_basic_word_break_characters = "\t\n\"'`;()";
|
||||||
rl_readline_name = "Guile";
|
rl_readline_name = "Guile";
|
||||||
|
|
||||||
reentry_barrier_mutex = scm_permanent_object (scm_make_mutex ());
|
reentry_barrier_mutex = scm_make_mutex ();
|
||||||
scm_init_opts (scm_readline_options,
|
scm_init_opts (scm_readline_options,
|
||||||
scm_readline_opts);
|
scm_readline_opts);
|
||||||
#if HAVE_RL_GET_KEYMAP
|
#if HAVE_RL_GET_KEYMAP
|
||||||
|
|
|
@ -1,69 +0,0 @@
|
||||||
## Process this file with automake to produce Makefile.in.
|
|
||||||
##
|
|
||||||
## Copyright (C) 2000, 2006, 2009 Free Software Foundation, Inc.
|
|
||||||
##
|
|
||||||
## This file is part of GUILE.
|
|
||||||
##
|
|
||||||
## GUILE is free software; you can redistribute it and/or modify it
|
|
||||||
## under the terms of the GNU Lesser General Public License as
|
|
||||||
## published by the Free Software Foundation; either version 3, or
|
|
||||||
## (at your option) any later version.
|
|
||||||
##
|
|
||||||
## GUILE is distributed in the hope that it will be useful, but
|
|
||||||
## WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
## GNU Lesser General Public License for more details.
|
|
||||||
##
|
|
||||||
## You should have received a copy of the GNU Lesser General Public
|
|
||||||
## License along with GUILE; see the file COPYING.LESSER. If not,
|
|
||||||
## write to the Free Software Foundation, Inc., 51 Franklin Street,
|
|
||||||
## Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
AUTOMAKE_OPTIONS = gnu
|
|
||||||
|
|
||||||
# These should be installed and distributed.
|
|
||||||
|
|
||||||
elisp_sources = \
|
|
||||||
elisp/base.scm \
|
|
||||||
elisp/example.el \
|
|
||||||
elisp/interface.scm \
|
|
||||||
elisp/transform.scm \
|
|
||||||
elisp/expand.scm \
|
|
||||||
elisp/variables.scm \
|
|
||||||
\
|
|
||||||
elisp/primitives/buffers.scm \
|
|
||||||
elisp/primitives/char-table.scm \
|
|
||||||
elisp/primitives/features.scm \
|
|
||||||
elisp/primitives/fns.scm \
|
|
||||||
elisp/primitives/format.scm \
|
|
||||||
elisp/primitives/guile.scm \
|
|
||||||
elisp/primitives/keymaps.scm \
|
|
||||||
elisp/primitives/lists.scm \
|
|
||||||
elisp/primitives/load.scm \
|
|
||||||
elisp/primitives/match.scm \
|
|
||||||
elisp/primitives/numbers.scm \
|
|
||||||
elisp/primitives/pure.scm \
|
|
||||||
elisp/primitives/read.scm \
|
|
||||||
elisp/primitives/signal.scm \
|
|
||||||
elisp/primitives/strings.scm \
|
|
||||||
elisp/primitives/symprop.scm \
|
|
||||||
elisp/primitives/syntax.scm \
|
|
||||||
elisp/primitives/system.scm \
|
|
||||||
elisp/primitives/time.scm \
|
|
||||||
\
|
|
||||||
elisp/internals/evaluation.scm \
|
|
||||||
elisp/internals/format.scm \
|
|
||||||
elisp/internals/fset.scm \
|
|
||||||
elisp/internals/lambda.scm \
|
|
||||||
elisp/internals/load.scm \
|
|
||||||
elisp/internals/null.scm \
|
|
||||||
elisp/internals/set.scm \
|
|
||||||
elisp/internals/signal.scm \
|
|
||||||
elisp/internals/time.scm \
|
|
||||||
elisp/internals/trace.scm
|
|
||||||
|
|
||||||
subpkgdatadir = $(pkgdatadir)/$(GUILE_EFFECTIVE_VERSION)/lang
|
|
||||||
nobase_subpkgdata_DATA = $(elisp_sources)
|
|
||||||
TAGS_FILES = $(nobase_subpkgdata_DATA)
|
|
||||||
|
|
||||||
EXTRA_DIST = $(elisp_sources) elisp/ChangeLog-2008
|
|
|
@ -1,401 +0,0 @@
|
||||||
2008-04-14 Neil Jerram <neil@ossau.uklinux.net>
|
|
||||||
|
|
||||||
* primitives/symprop.scm (get): Use lambda->nil.
|
|
||||||
|
|
||||||
* primitives/strings.scm (aset): New primitive.
|
|
||||||
|
|
||||||
* internals/load.scm (load): Use in-vicinity (instead of
|
|
||||||
string-append) to add a slash if needed.
|
|
||||||
|
|
||||||
2004-02-08 Mikael Djurfeldt <djurfeldt@nada.kth.se>
|
|
||||||
|
|
||||||
* primitives/Makefile.am (TAGS_FILES), internals/Makefile.am
|
|
||||||
(TAGS_FILES), Makefile.am (TAGS_FILES): Use this variable instead
|
|
||||||
of ETAGS_ARGS so that TAGS can be built using separate build
|
|
||||||
directory.
|
|
||||||
|
|
||||||
2003-11-01 Neil Jerram <neil@ossau.uklinux.net>
|
|
||||||
|
|
||||||
* internals/format.scm (format), internals/signal.scm (error),
|
|
||||||
internals/load.scm (load): Export using #:replace to avoid
|
|
||||||
duplicate binding warnings.
|
|
||||||
|
|
||||||
2003-01-05 Marius Vollmer <mvo@zagadka.ping.de>
|
|
||||||
|
|
||||||
* primitives/Makefile.am (elisp_sources): Added char-table.scm.
|
|
||||||
|
|
||||||
2002-12-28 Neil Jerram <neil@ossau.uklinux.net>
|
|
||||||
|
|
||||||
* base.scm (lang): Use char-table module.
|
|
||||||
|
|
||||||
* primitives/char-table.scm (lang): New (stub definitions).
|
|
||||||
|
|
||||||
2002-12-08 Rob Browning <rlb@defaultvalue.org>
|
|
||||||
|
|
||||||
* Makefile.am (subpkgdatadir): VERSION -> GUILE_EFFECTIVE_VERSION.
|
|
||||||
|
|
||||||
* primitives/Makefile.am (subpkgdatadir): VERSION ->
|
|
||||||
GUILE_EFFECTIVE_VERSION.
|
|
||||||
|
|
||||||
* internals/Makefile.am (subpkgdatadir): VERSION ->
|
|
||||||
GUILE_EFFECTIVE_VERSION.
|
|
||||||
|
|
||||||
2002-02-13 Neil Jerram <neil@ossau.uklinux.net>
|
|
||||||
|
|
||||||
* base.scm (load-emacs): Add optional parameters for specifying an
|
|
||||||
alternative load path, and for debugging this. (Thanks to
|
|
||||||
Thien-Thi Nguyen!)
|
|
||||||
|
|
||||||
* primitives/syntax.scm (setq): Use `set'.
|
|
||||||
|
|
||||||
* internals/set.scm (set): Fixed to support variables that are
|
|
||||||
imported from other modules.
|
|
||||||
|
|
||||||
2002-02-12 Neil Jerram <neil@ossau.uklinux.net>
|
|
||||||
|
|
||||||
* transform.scm (scheme): Use set-current-module to ensure
|
|
||||||
expected behaviour of resolve-module.
|
|
||||||
|
|
||||||
2002-02-08 Neil Jerram <neil@ossau.uklinux.net>
|
|
||||||
|
|
||||||
* STATUS: New file.
|
|
||||||
|
|
||||||
* README: Updated.
|
|
||||||
|
|
||||||
* interface.scm (translate-elisp): New exported procedure.
|
|
||||||
(elisp-function): Symbol var is `obj', not `symbol'.
|
|
||||||
|
|
||||||
* internals/lambda.scm, primitives/fns.scm: Fix confusion between
|
|
||||||
interactive-spec and interactive-specification.
|
|
||||||
|
|
||||||
* internals/lambda.scm (transform-lambda), primitives/syntax.scm
|
|
||||||
(defmacro): Bind unspecified optional and rest arguments to #nil,
|
|
||||||
not #f.
|
|
||||||
|
|
||||||
* internals/null.scm (->nil, lambda->nil): New, exported.
|
|
||||||
(null): Use ->nil.
|
|
||||||
|
|
||||||
* primitives/features.scm (featurep), primitives/fns.scm
|
|
||||||
(fboundp, subrp): Use ->nil.
|
|
||||||
|
|
||||||
* internals/lists.scm (cons, setcdr, memq, member, assq, assoc):
|
|
||||||
Simplified.
|
|
||||||
(car, cdr): Return #nil rather than #f.
|
|
||||||
|
|
||||||
* primitives/load.scm (current-load-list), primitives/pure.scm
|
|
||||||
(purify-flag): Set to #nil, not #f.
|
|
||||||
|
|
||||||
* primitives/match.scm (string-match): Return #nil rather than #f.
|
|
||||||
|
|
||||||
* primitives/numbers.scm (integerp, numberp),
|
|
||||||
primitives/strings.scm (string-lessp, stringp): Use lambda->nil.
|
|
||||||
|
|
||||||
* primitives/symprop.scm (boundp): Use ->nil.
|
|
||||||
(symbolp, local-variable-if-set-p): Return #nil rather than #f.
|
|
||||||
|
|
||||||
* primitives/syntax.scm (prog1, prog2): Mangle variable names
|
|
||||||
further to lessen possibility of conflicts.
|
|
||||||
(if, and, or, cond): Return #nil rather than #f.
|
|
||||||
(cond): Return #t rather than t (which is undefined).
|
|
||||||
(let, let*): Bind uninitialized variables to #nil, not #f.
|
|
||||||
|
|
||||||
* transform.scm: Resolve inconsistency in usage of `map', and add
|
|
||||||
an explanatory note. Also cleaned up use of subsidiary
|
|
||||||
transformation functions. Also use cons-source wherever possible.
|
|
||||||
(transform-datum, transform-quote): New.
|
|
||||||
(transform-quasiquote): Renamed from `transform-inside-qq'.
|
|
||||||
(transform-application): Apply `transform-quote' to application
|
|
||||||
args.
|
|
||||||
(cars->nil): Removed.
|
|
||||||
|
|
||||||
* internals/null.scm (null), primitives/lists.scm (cons, car, cdr,
|
|
||||||
setcdr, memq, member, assq, assoc, nth): Update to take into
|
|
||||||
account new libguile support for Elisp nil value.
|
|
||||||
|
|
||||||
2002-02-06 Neil Jerram <neil@ossau.uklinux.net>
|
|
||||||
|
|
||||||
* example.el (time): New macro, for performance measurement.
|
|
||||||
Accompanying comment compares results for Guile and Emacs.
|
|
||||||
|
|
||||||
* transform.scm (scheme): New macro.
|
|
||||||
(transformer): New implementation of `scheme' escape that doesn't
|
|
||||||
rely on (lang elisp base) importing Guile bindings.
|
|
||||||
|
|
||||||
* base.scm: No longer import anything from (guile).
|
|
||||||
(load-emacs): Add scheme form to ensure that keywords
|
|
||||||
read option is set correctly.
|
|
||||||
|
|
||||||
* primitives/syntax.scm (defmacro, let, let*): Unquote uses of
|
|
||||||
`@bind' in transformed code.
|
|
||||||
(if): Unquote uses of `nil-cond' in transformed code.
|
|
||||||
|
|
||||||
* internals/lambda.scm (transform-lambda): Unquote use of `@bind'
|
|
||||||
in transformed code.
|
|
||||||
|
|
||||||
* transform.scm (transformer-macro): Don't quote `list' in
|
|
||||||
transformed code.
|
|
||||||
(transform-application): Don't quote `@fop' in transformed code.
|
|
||||||
(transformer): No need to treat `@bind' and `@fop' as special
|
|
||||||
cases in input to the transformer.
|
|
||||||
|
|
||||||
2002-02-04 Neil Jerram <neil@ossau.uklinux.net>
|
|
||||||
|
|
||||||
* primitives/syntax.scm (parse-formals, transform-lambda,
|
|
||||||
interactive-spec, set-not-subr!, transform-lambda/interactive):
|
|
||||||
Move into internals/lambda.scm so that these can also be used
|
|
||||||
by...
|
|
||||||
|
|
||||||
* internals/fset.scm (elisp-apply): Use `eval' and
|
|
||||||
`transform-lambda/interactive' to turn a quoted lambda expression
|
|
||||||
into a Scheme procedure.
|
|
||||||
|
|
||||||
* transform.scm (m-quasiquote): Don't quote `quasiquote' in
|
|
||||||
transformed code.
|
|
||||||
(transformer): Transform '() to #nil.
|
|
||||||
|
|
||||||
2002-02-03 Neil Jerram <neil@ossau.uklinux.net>
|
|
||||||
|
|
||||||
* internals/Makefile.am (elisp_sources): Add lambda.scm.
|
|
||||||
|
|
||||||
* internals/lambda.scm (lang): New file.
|
|
||||||
|
|
||||||
2002-02-01 Neil Jerram <neil@ossau.uklinux.net>
|
|
||||||
|
|
||||||
* transform.scm (transformer), primitives/syntax.scm (let*):
|
|
||||||
Unquote uses of `begin' in transformed code.
|
|
||||||
|
|
||||||
2002-01-29 Neil Jerram <neil@ossau.uklinux.net>
|
|
||||||
|
|
||||||
* transform.scm (transform-1, transform-2, transform-3,
|
|
||||||
transform-list): Removed (unused).
|
|
||||||
|
|
||||||
* transform.scm, primitives/syntax.scm: Add commas everywhere
|
|
||||||
before use of (guile) primitives in generated code, so that (lang
|
|
||||||
elisp base) doesn't have to import bindings from (guile).
|
|
||||||
|
|
||||||
* base.scm: Move use-modules expressions inside the define-module,
|
|
||||||
and add #:pure so that we don't import bindings from (guile).
|
|
||||||
|
|
||||||
2002-01-25 Neil Jerram <neil@ossau.uklinux.net>
|
|
||||||
|
|
||||||
* transform.scm (transform-application): Preserve source
|
|
||||||
properties of original elisp expression by using cons-source.
|
|
||||||
|
|
||||||
* transform.scm: Don't handle special forms specially in the
|
|
||||||
translator. Instead, define them as macros in ...
|
|
||||||
|
|
||||||
* primitives/syntax.scm: New file; special form definitions.
|
|
||||||
|
|
||||||
* primitives/fns.scm (run-hooks): Rewritten correctly.
|
|
||||||
|
|
||||||
* primitives/symprop.scm (symbol-value): Use `value'.
|
|
||||||
|
|
||||||
* internals/set.scm (value): New function.
|
|
||||||
|
|
||||||
* primitives/fns.scm: Use (lang elisp internals null), as null is
|
|
||||||
no longer a primitive. Change generated #f values to %nil.
|
|
||||||
|
|
||||||
* internals/null.scm (null): Handle nil symbol.
|
|
||||||
|
|
||||||
* primitives/lists.scm (memq, member, assq, assoc): Handle all
|
|
||||||
possible nil values.
|
|
||||||
|
|
||||||
* transform.scm (transformer): Translate `nil' and `t' to #nil and
|
|
||||||
#t.
|
|
||||||
|
|
||||||
* base.scm: Remove setting of 'language read-option.
|
|
||||||
|
|
||||||
2001-11-03 Neil Jerram <neil@ossau.uklinux.net>
|
|
||||||
|
|
||||||
* README (Resources): Fill in missing URLs.
|
|
||||||
|
|
||||||
2001-11-02 Neil Jerram <neil@ossau.uklinux.net>
|
|
||||||
|
|
||||||
* Makefile.am (elisp_sources): Added base.scm, example.el,
|
|
||||||
interface.scm; removed emacs.scm.
|
|
||||||
|
|
||||||
* README: Updated accordingly.
|
|
||||||
|
|
||||||
* internals/load.scm (load): Avoid using `load-path' if the
|
|
||||||
supplied file name begins with a slash.
|
|
||||||
|
|
||||||
* internals/fset.scm: Support export of defuns, defmacros and
|
|
||||||
defvars to a module specified by the fluid `elisp-export-module'.
|
|
||||||
This allows us to automate the importing of Elisp definitions into
|
|
||||||
Scheme.
|
|
||||||
|
|
||||||
* example.el: New file: example code for `load-elisp-file'.
|
|
||||||
|
|
||||||
* interface.scm: New file - mechanisms to exchange definitions
|
|
||||||
between Scheme and Elisp.
|
|
||||||
|
|
||||||
Following changes try to make the Elisp evaluation module less
|
|
||||||
Emacs-dependent; in other words, so that it isn't necessary to try
|
|
||||||
to load the whole Emacs environment before evaluating basic
|
|
||||||
non-Emacs-specific Elisp code.
|
|
||||||
|
|
||||||
* variables.scm, internals/evaluation.scm: Changed (lang elisp
|
|
||||||
emacs) to (lang elisp base).
|
|
||||||
|
|
||||||
* emacs.scm (lang): Removed.
|
|
||||||
|
|
||||||
* base.scm (lang): New file (non-emacs-specific replacement for
|
|
||||||
emacs.scm).
|
|
||||||
|
|
||||||
2001-10-28 Neil Jerram <neil@ossau.uklinux.net>
|
|
||||||
|
|
||||||
* primitives/symprop.scm (symbol-name): New primitive.
|
|
||||||
|
|
||||||
* primitives/strings.scm (stringp): New primitive.
|
|
||||||
|
|
||||||
* primitives/pure.scm (purify-flag): New variable.
|
|
||||||
|
|
||||||
* primitives/numbers.scm (numberp): New primitive.
|
|
||||||
|
|
||||||
* internals/fset.scm (fset): Set procedure and macro name
|
|
||||||
properties usefully to match Elisp symbol names. Also bind Elisp
|
|
||||||
function definition variables to similarly named symbols in the
|
|
||||||
(lang elisp variables) module.
|
|
||||||
|
|
||||||
* transform.scm (transformer, m-unwind-protect): Added support for
|
|
||||||
`unwind-protect'.
|
|
||||||
(m-quasiquote): Use 'quasiquote rather than 'quote.
|
|
||||||
(transform-lambda, m-defmacro): When no rest arguments, set the
|
|
||||||
rest parameter to '() rather than #f. It shouldn't make any
|
|
||||||
difference, but it feels more right.
|
|
||||||
|
|
||||||
* README: Enlarged description of current status.
|
|
||||||
|
|
||||||
* Makefile.am (elisp_sources): Added variables.scm.
|
|
||||||
|
|
||||||
* variables.scm: New file.
|
|
||||||
|
|
||||||
2001-10-26 Neil Jerram <neil@ossau.uklinux.net>
|
|
||||||
|
|
||||||
* buffers.scm, calling.scm: Removed. These should have
|
|
||||||
disappeared during the reorganization described below, but I
|
|
||||||
missed them by mistake.
|
|
||||||
|
|
||||||
* primitives/symprop.scm (set, boundp, symbol-value): Changed to
|
|
||||||
use (module-xx the-elisp-module ...) rather than (local-xx ...).
|
|
||||||
(symbolp): Accept either symbols or keywords.
|
|
||||||
(set-default, default-boundp, default-value,
|
|
||||||
local-variable-if-set-p): New.
|
|
||||||
|
|
||||||
* primitives/match.scm (string-match, match-data): Store last
|
|
||||||
match data in Emacs rather than Guile form, to simplify
|
|
||||||
implementation of ...
|
|
||||||
(set-match-data, store-match-data): New.
|
|
||||||
|
|
||||||
* primitives/load.scm (autoload, current-load-list): New. (But
|
|
||||||
autoload is just stubbed, not properly implemented.)
|
|
||||||
|
|
||||||
* primitives/lists.scm (nth, listp, consp, nconc): New.
|
|
||||||
|
|
||||||
* primitives/fns.scm (byte-code-function-p, run-hooks): New.
|
|
||||||
|
|
||||||
* transform.scm (transform-application, transformer-macro): New
|
|
||||||
scheme for transforming procedure arguments while leaving macro
|
|
||||||
args untransformed. (See also associated change in libguile.)
|
|
||||||
(m-defconst): Simplified, now uses m-setq.
|
|
||||||
|
|
||||||
* Makefile.am: Changed so that it only deals with files directly
|
|
||||||
in this directory; otherwise files don't install cleanly.
|
|
||||||
|
|
||||||
* internals/Makefile.am, primitives/Makefile.am,
|
|
||||||
internals/.cvsignore, primitives/.cvsignore: New files.
|
|
||||||
|
|
||||||
2001-10-26 Neil Jerram <neil@ossau.uklinux.net>
|
|
||||||
|
|
||||||
* transform.scm (transformer): New handling for (1) quasiquoting
|
|
||||||
syntax like "(` ...)" as well as the more normal "` ..."; (2)
|
|
||||||
`function'; (3) interactive specification in lambda body.
|
|
||||||
Simplied handling for `setq'.
|
|
||||||
(transform-inside-qq): Fixed to handle improper as well as proper
|
|
||||||
lists.
|
|
||||||
(transform-lambda/interactive): New; wraps transform-lambda to
|
|
||||||
handle setting of various procedure properties.
|
|
||||||
(transform-lambda, m-defmacro): Changed `args' and `num-args' to
|
|
||||||
`%--args' and `%--num-args' in the hope of avoiding lexical
|
|
||||||
vs. dynamic name clashes.
|
|
||||||
(m-and): Use #f instead of '() where a condition fails.
|
|
||||||
|
|
||||||
Plus big hierarchy reorganization, in which most of the previous
|
|
||||||
occupants of lang/elisp moved to lang/elisp/primitives, with some
|
|
||||||
internal processing being split out into lang/elisp/internals.
|
|
||||||
The upshot looks like this:
|
|
||||||
|
|
||||||
* internals/trace.scm, internals/set.scm, internals/load.scm,
|
|
||||||
internals/fset.scm, internals/signal.scm, internals/time.scm,
|
|
||||||
internals/format.scm, internals/null.scm,
|
|
||||||
internals/evaluation.scm, primitives/buffers.scm,
|
|
||||||
primitives/features.scm, primitives/format.scm,
|
|
||||||
primitives/time.scm, primitives/guile.scm, primitives/keymaps.scm,
|
|
||||||
primitives/lists.scm, primitives/load.scm, primitives/match.scm,
|
|
||||||
primitives/numbers.scm, primitives/pure.scm, primitives/read.scm,
|
|
||||||
primitives/signal.scm, primitives/strings.scm,
|
|
||||||
primitives/symprop.scm, primitives/system.scm, primitives/fns.scm:
|
|
||||||
New files.
|
|
||||||
|
|
||||||
* features.scm, format.scm, fset.scm, guile.scm, keymaps.scm,
|
|
||||||
lists.scm, load.scm, match.scm, numbers.scm, pure.scm, read.scm,
|
|
||||||
signal.scm, strings.scm, symprop.scm, system.scm, time.scm,
|
|
||||||
trace.scm: Removed files.
|
|
||||||
|
|
||||||
2001-10-23 Neil Jerram <neil@ossau.uklinux.net>
|
|
||||||
|
|
||||||
* match.scm (string-match): New implementation using new
|
|
||||||
`make-emacs-regexp' primitive; old workaround implementation
|
|
||||||
renamed to `string-match-workaround'.
|
|
||||||
|
|
||||||
2001-10-21 Neil Jerram <neil@ossau.uklinux.net>
|
|
||||||
|
|
||||||
* transform.scm (m-defun, m-defmacro, m-let, m-defvar,
|
|
||||||
m-defconst): Use more selective tracing mechanism (provided by new
|
|
||||||
file trace.scm).
|
|
||||||
|
|
||||||
* symprop.scm (get, boundp), transform.scm (transform-lambda,
|
|
||||||
m-defmacro): Remove unnecessary uses of nil-ify and t-ify.
|
|
||||||
|
|
||||||
* match.scm (string-match): Workaround Guile/libc regex
|
|
||||||
parenthesis bug.
|
|
||||||
|
|
||||||
* emacs.scm: Move elisp primitive definitions into more specific
|
|
||||||
files, so that emacs.scm contains only overall code.
|
|
||||||
|
|
||||||
* Makefile.am: Added new files.
|
|
||||||
|
|
||||||
* numbers.scm, trace.scm, time.scm, pure.scm, system.scm,
|
|
||||||
read.scm, calling.scm, guile.scm: New files.
|
|
||||||
|
|
||||||
2001-10-20 Neil Jerram <neil@ossau.uklinux.net>
|
|
||||||
|
|
||||||
* Makefile.am (elisp_sources): Added match.scm and strings.scm.
|
|
||||||
|
|
||||||
* match.scm, strings.scm: New files.
|
|
||||||
|
|
||||||
2001-10-19 Neil Jerram <neil@ossau.uklinux.net>
|
|
||||||
|
|
||||||
* transform.scm: Replace uses of `nil' by `#f' or `'()'.
|
|
||||||
|
|
||||||
* Makefile.am (elisp_sources): Added lists.scm.
|
|
||||||
|
|
||||||
* load.scm (the-elisp-module): Corrected (lang elisp emacs) module
|
|
||||||
name.
|
|
||||||
|
|
||||||
* lists.scm (lang): New file containing list-related primitives.
|
|
||||||
|
|
||||||
* emacs.scm: Corrected module name.
|
|
||||||
|
|
||||||
2001-10-19 Neil Jerram <neil@ossau.uklinux.net>
|
|
||||||
|
|
||||||
Initial implementation of an Emacs Lisp translator, based on
|
|
||||||
transformer code originally written by Mikael Djurfeldt.
|
|
||||||
|
|
||||||
* Makefile.am, .cvsignore: New.
|
|
||||||
|
|
||||||
* ChangeLog, README, buffers.scm, emacs.scm, features.scm,
|
|
||||||
format.scm, fset.scm, keymaps.scm, load.scm, signal.scm,
|
|
||||||
symprop.scm, transform.scm: New files.
|
|
||||||
|
|
||||||
|
|
|
@ -1,303 +0,0 @@
|
||||||
-*- outline -*-
|
|
||||||
|
|
||||||
This directory holds the Scheme side of a translator for Emacs Lisp.
|
|
||||||
|
|
||||||
* Usage
|
|
||||||
|
|
||||||
To load up the base Elisp environment:
|
|
||||||
|
|
||||||
(use-modules (lang elisp base))
|
|
||||||
|
|
||||||
Then you can switch into this module
|
|
||||||
|
|
||||||
(define-module (lang elisp base))
|
|
||||||
|
|
||||||
and start typing away in Elisp, or evaluate an individual Elisp
|
|
||||||
expression from Scheme:
|
|
||||||
|
|
||||||
(eval EXP (resolve-module '(lang elisp base)))
|
|
||||||
|
|
||||||
A more convenient, higher-level interface is provided by (lang elisp
|
|
||||||
interface):
|
|
||||||
|
|
||||||
(use-modules (lang elisp interface))
|
|
||||||
|
|
||||||
With this interface, you can evaluate an Elisp expression
|
|
||||||
|
|
||||||
(eval-elisp EXP)
|
|
||||||
|
|
||||||
load an Elisp file with no effect on the Scheme world
|
|
||||||
|
|
||||||
(load-elisp-file "/home/neil/Guile/cvs/guile-core/lang/elisp/example.el")
|
|
||||||
|
|
||||||
load an Elisp file, automatically importing top level definitions into
|
|
||||||
Scheme
|
|
||||||
|
|
||||||
(use-elisp-file "/home/neil/Guile/cvs/guile-core/lang/elisp/example.el")
|
|
||||||
|
|
||||||
export Scheme objects to Elisp
|
|
||||||
|
|
||||||
(export-to-elisp + - * my-func 'my-var)
|
|
||||||
|
|
||||||
and try to bootstrap a complete Emacs environment:
|
|
||||||
|
|
||||||
(load-emacs)
|
|
||||||
|
|
||||||
* Status
|
|
||||||
|
|
||||||
Please see the STATUS file for the full position.
|
|
||||||
|
|
||||||
** Trying to load a complete Emacs environment.
|
|
||||||
|
|
||||||
To try this, type `(use-modules (lang elisp interface))' and then
|
|
||||||
`(load-emacs)'. The following output shows how far I get when I try
|
|
||||||
this.
|
|
||||||
|
|
||||||
guile> (use-modules (lang elisp interface))
|
|
||||||
guile> (load-emacs)
|
|
||||||
Calling loadup.el to clothe the bare Emacs...
|
|
||||||
Loading /usr/share/emacs/20.7/lisp/loadup.el...
|
|
||||||
Using load-path ("/usr/share/emacs/20.7/lisp/" "/usr/share/emacs/20.7/lisp/emacs-lisp/")
|
|
||||||
Loading /usr/share/emacs/20.7/lisp/byte-run.el...
|
|
||||||
Loading /usr/share/emacs/20.7/lisp/byte-run.el...done
|
|
||||||
Loading /usr/share/emacs/20.7/lisp/subr.el...
|
|
||||||
Loading /usr/share/emacs/20.7/lisp/subr.el...done
|
|
||||||
Loading /usr/share/emacs/20.7/lisp/version.el...
|
|
||||||
Loading /usr/share/emacs/20.7/lisp/version.el...done
|
|
||||||
Loading /usr/share/emacs/20.7/lisp/map-ynp.el...
|
|
||||||
Loading /usr/share/emacs/20.7/lisp/map-ynp.el...done
|
|
||||||
Loading /usr/share/emacs/20.7/lisp/widget.el...
|
|
||||||
Loading /usr/share/emacs/20.7/lisp/emacs-lisp/cl.el...
|
|
||||||
Loading /usr/share/emacs/20.7/lisp/emacs-lisp/cl.el...done
|
|
||||||
Loading /usr/share/emacs/20.7/lisp/widget.el...done
|
|
||||||
Loading /usr/share/emacs/20.7/lisp/custom.el...
|
|
||||||
Loading /usr/share/emacs/20.7/lisp/custom.el...done
|
|
||||||
Loading /usr/share/emacs/20.7/lisp/cus-start.el...
|
|
||||||
Note, built-in variable `abbrev-all-caps' not bound
|
|
||||||
... [many other variable not bound messages] ...
|
|
||||||
Loading /usr/share/emacs/20.7/lisp/cus-start.el...done
|
|
||||||
Loading /usr/share/emacs/20.7/lisp/international/mule.el...
|
|
||||||
<unnamed port>: In procedure make-char-table in expression (@fop make-char-table (# #)):
|
|
||||||
<unnamed port>: Symbol's function definition is void
|
|
||||||
ABORT: (misc-error)
|
|
||||||
|
|
||||||
Type "(backtrace)" to get more information or "(debug)" to enter the debugger.
|
|
||||||
guile>
|
|
||||||
|
|
||||||
That's 3279 lines ("wc -l") of Elisp code already, which isn't bad!
|
|
||||||
|
|
||||||
I think that progress beyond this point basically means implementing
|
|
||||||
multilingual and multibyte strings properly for Guile. Which is a
|
|
||||||
_lot_ of work and requires IMO a very clear plan for Guile's role with
|
|
||||||
respect to Emacs.
|
|
||||||
|
|
||||||
* Design
|
|
||||||
|
|
||||||
When thinking about how to implement an Elisp translator for Guile, it
|
|
||||||
is important to realize that the great power of Emacs does not arise
|
|
||||||
from Elisp (seen as a language in syntactic terms) alone, but from the
|
|
||||||
combination of this language with the collection of primitives
|
|
||||||
provided by the Emacs C source code. Therefore, to be of practical
|
|
||||||
use, an Elisp translator needs to be more than just a transformer that
|
|
||||||
translates sexps to Scheme expressions.
|
|
||||||
|
|
||||||
The finished translator should consist of several parts...
|
|
||||||
|
|
||||||
** Syntax transformation
|
|
||||||
|
|
||||||
Although syntax transformation isn't all we need, we do still need it!
|
|
||||||
|
|
||||||
This part is implemented by the (lang elisp transform) module; it is
|
|
||||||
close to complete and seems to work pretty reliably.
|
|
||||||
|
|
||||||
Note that transformed expressions use the `@fop' and `@bind' macros
|
|
||||||
provided by...
|
|
||||||
|
|
||||||
** C support for transformed expressions
|
|
||||||
|
|
||||||
For performance and historical reasons (and perhaps necessity - I
|
|
||||||
haven't thought about it enough yet), some of the transformation
|
|
||||||
support is written in C.
|
|
||||||
|
|
||||||
*** @fop
|
|
||||||
|
|
||||||
The `@fop' macro is used to dispatch Elisp applications. Its first
|
|
||||||
argument is a symbol, and this symbol's function slot is examined to
|
|
||||||
find a procedure or macro to apply to the remaining arguments. `@fop'
|
|
||||||
also handles aliasing (`defalias'): in this case the function slot
|
|
||||||
contains another symbol.
|
|
||||||
|
|
||||||
Once `@fop' has found the appropriate procedure or macro to apply, it
|
|
||||||
returns an application expression in which that procedure or macro
|
|
||||||
replaces the `@fop' and the original symbol. Hence no Elisp-specific
|
|
||||||
evaluator support is required to perform the application.
|
|
||||||
|
|
||||||
*** @bind
|
|
||||||
|
|
||||||
Currently, Elisp variables are the same as Scheme variables, so
|
|
||||||
variable references are effectively untransformed.
|
|
||||||
|
|
||||||
The `@bind' macro does Elisp-style dynamic variable binding.
|
|
||||||
Basically, it locates the named top level variables, `set!'s them to
|
|
||||||
new values, evaluates its body, and then uses `set!' again to restore
|
|
||||||
the original values.
|
|
||||||
|
|
||||||
Because of the body evaluation, `@bind' requires evaluator support.
|
|
||||||
In fact, the `@bind' macro code does little more than replace itself
|
|
||||||
with the memoized SCM_IM_BIND. Most of the work is done by the
|
|
||||||
evaluator when it hits SCM_IM_BIND.
|
|
||||||
|
|
||||||
One theoretical problem with `@bind' is that any local Scheme variable
|
|
||||||
in the same scope and with the same name as an Elisp variable will
|
|
||||||
shadow the Elisp variable. But in practice it's difficult to set up
|
|
||||||
such a situation; an exception is the translator code itself, so there
|
|
||||||
we mangle the relevant Scheme variable names a bit to avoid the
|
|
||||||
problem.
|
|
||||||
|
|
||||||
Other possible problems with this approach are that it might not be
|
|
||||||
possible to implement buffer local variables properly, and that
|
|
||||||
`@bind' might become too inefficient when we implement full support
|
|
||||||
for undefining Scheme variables. So we might in future have to
|
|
||||||
transform Elisp variable references after all.
|
|
||||||
|
|
||||||
*** Truth value stuff
|
|
||||||
|
|
||||||
Following extensive discussions on the Guile mailing list between
|
|
||||||
September 2001 and January 2002, we decided to go with Jim Blandy's
|
|
||||||
proposal. See devel/translation/lisp-and-scheme.text for details.
|
|
||||||
|
|
||||||
- The Elisp nil value is a new immediate SCM_MAKIFLAG, eq?-distinct
|
|
||||||
from both #f and '() (and of course any other Scheme value). It can
|
|
||||||
be accessed via the (guile) binding `%nil', and prints as `#nil'.
|
|
||||||
|
|
||||||
- All Elisp primitives treat #nil, #f and '() as identical.
|
|
||||||
|
|
||||||
- Scheme truth-testing primitives have been modified so that they
|
|
||||||
treat #nil the same as #f.
|
|
||||||
|
|
||||||
- Scheme list-manipulating primitives have been modified so that they
|
|
||||||
treat #nil the same as '().
|
|
||||||
|
|
||||||
- The Elisp t value is the same as #t.
|
|
||||||
|
|
||||||
** Emacs editing primitives
|
|
||||||
|
|
||||||
Buffers, keymaps, text properties, windows, frames etc. etc.
|
|
||||||
|
|
||||||
Basically, everything that is implemented as a primitive in the Emacs
|
|
||||||
C code needs to be implemented either in Scheme or in C for Guile.
|
|
||||||
|
|
||||||
The Scheme files in the primitives subdirectory implement some of
|
|
||||||
these primitives in Scheme. Not because that is the right decision,
|
|
||||||
but because this is a proof of concept and it's quicker to write badly
|
|
||||||
performing code in Scheme.
|
|
||||||
|
|
||||||
Ultimately, most of these primitive definitions should really come
|
|
||||||
from the Emacs C code itself, translated or preprocessed in a way that
|
|
||||||
makes it compile with Guile. I think this is pretty close to the work
|
|
||||||
that Ken Raeburn has been doing on the Emacs codebase.
|
|
||||||
|
|
||||||
** Reading and printing support
|
|
||||||
|
|
||||||
Elisp is close enough to Scheme that it's convenient to coopt the
|
|
||||||
existing Guile reader rather than to write a new one from scratch, but
|
|
||||||
there are a few syntactic differences that will require changes in
|
|
||||||
reading and printing. None of the following changes has yet been
|
|
||||||
implemented.
|
|
||||||
|
|
||||||
- Character syntax is `?a' rather than `#\a'. (Not done. More
|
|
||||||
precisely, `?a' in Elisp isn't character syntax but an alternative
|
|
||||||
integer syntax. Note that we could support most of the `?a' syntax
|
|
||||||
simply by doing
|
|
||||||
|
|
||||||
(define ?a (char->integer #\a)
|
|
||||||
(define ?b (char->integer #\b)
|
|
||||||
|
|
||||||
and so on.)
|
|
||||||
|
|
||||||
- Vector syntax is `[1 2 3]' rather than `#(1 2 3)'.
|
|
||||||
|
|
||||||
- When in an Elisp environment, #nil and #t should print as `nil' and
|
|
||||||
`t'.
|
|
||||||
|
|
||||||
** The Elisp evaluation module (lang elisp base)
|
|
||||||
|
|
||||||
Fundamentally, Guile's module system can't be used to package Elisp
|
|
||||||
code in the same way it is used for Scheme code, because Elisp
|
|
||||||
function definitions are stored as symbol properties (in the symbol's
|
|
||||||
"function slot") and so are global. On the other hand, it is useful
|
|
||||||
(necessary?) to associate some particular module with Elisp evaluation
|
|
||||||
because
|
|
||||||
|
|
||||||
- Elisp variables are currently implemented as Scheme variables and so
|
|
||||||
need to live in some module
|
|
||||||
|
|
||||||
- a syntax transformer is a property of a module.
|
|
||||||
|
|
||||||
Therefore we have the (lang elisp base) module, which acts as the
|
|
||||||
repository for all Elisp variables and the site of all Elisp
|
|
||||||
evaluation.
|
|
||||||
|
|
||||||
The initial environment provided by this module is intended to be a
|
|
||||||
non-Emacs-dependent subset of Elisp. To get the idea, imagine someone
|
|
||||||
who wants to write an extension function for, say Gnucash, and simply
|
|
||||||
prefers to write in Elisp rather than in Scheme. He/she therefore
|
|
||||||
doesn't buffers, keymaps and so on, just the basic language syntax and
|
|
||||||
core data functions like +, *, concat, length etc., plus specific
|
|
||||||
functions made available by Gnucash.
|
|
||||||
|
|
||||||
(lang elisp base) achieves this by
|
|
||||||
|
|
||||||
- importing Scheme definitions for some Emacs primitives from the
|
|
||||||
files in the primitives subdirectory
|
|
||||||
|
|
||||||
- then switching into Elisp syntax.
|
|
||||||
|
|
||||||
After this point, `(eval XXX (resolve-module '(lang elisp base)))'
|
|
||||||
will evaluate XXX as an Elisp expression in the (lang elisp base)
|
|
||||||
module. (`eval-elisp' in (lang elisp interface) is a more convenient
|
|
||||||
wrapper for this.)
|
|
||||||
|
|
||||||
** Full Emacs environment
|
|
||||||
|
|
||||||
The difference between the initial (lang elisp base) environment and a
|
|
||||||
fully loaded Emacs equivalent is
|
|
||||||
|
|
||||||
- more primitives: buffers, char-tables and many others
|
|
||||||
|
|
||||||
- the bootstrap Elisp code that an undumped Emacs loads during
|
|
||||||
installation by calling `(load "loadup.el")'.
|
|
||||||
|
|
||||||
We don't have all the missing primitives, but we can already get
|
|
||||||
through some of loadup.el. The Elisp function `load-emacs' (defined
|
|
||||||
in (lang elisp base) initiates the loading of loadup.el; (lang elisp
|
|
||||||
interface) exports `load-emacs' to Scheme.
|
|
||||||
|
|
||||||
`load-emacs' loads so much Elisp code that it's an excellent way to
|
|
||||||
test the translator. In current practice, it runs for a while and
|
|
||||||
then fails when it gets to an undefined primitive or a bug in the
|
|
||||||
translator. Eventually, it should go all the way. (And then we can
|
|
||||||
worry about adding unexec support to Guile!) For the output that
|
|
||||||
currently results from calling `(load-emacs)', see above in the Status
|
|
||||||
section.
|
|
||||||
|
|
||||||
* Resources
|
|
||||||
|
|
||||||
** Ken Raeburn's Guile Emacs page
|
|
||||||
|
|
||||||
http://www.mit.edu/~raeburn/guilemacs/
|
|
||||||
|
|
||||||
** Keisuke Nishida's Gemacs project
|
|
||||||
|
|
||||||
http://gemacs.sourceforge.net
|
|
||||||
|
|
||||||
** Jim Blandy's nil/#f/() notes
|
|
||||||
|
|
||||||
http://sanpietro.red-bean.com/guile/guile/old/3114.html
|
|
||||||
|
|
||||||
Also now stored as guile-core/devel/translation/lisp-and-scheme.text
|
|
||||||
in Guile CVS.
|
|
||||||
|
|
||||||
** Mikael Djurfeldt's notes on translation
|
|
||||||
|
|
||||||
See file guile-core/devel/translation/langtools.text in Guile CVS.
|
|
|
@ -1,35 +0,0 @@
|
||||||
-*-text-*-
|
|
||||||
|
|
||||||
I've now finished my currently planned work on the Emacs Lisp
|
|
||||||
translator in guile-core CVS.
|
|
||||||
|
|
||||||
It works well enough for experimentation and playing around with --
|
|
||||||
see the README file for details of what it _can_ do -- but has two
|
|
||||||
serious restrictions:
|
|
||||||
|
|
||||||
- Most Emacs Lisp primitives are not yet implemented. In particular,
|
|
||||||
there are no buffer-related primitives.
|
|
||||||
|
|
||||||
- Performance compares badly with Emacs. Using a handful of
|
|
||||||
completely unscientific tests, I found that Guile was between 2 and
|
|
||||||
20 times slower than Emacs. (See the comment in
|
|
||||||
lang/elisp/example.el for details of tests and results.)
|
|
||||||
|
|
||||||
Interestingly, both these restrictions point in the same direction:
|
|
||||||
the way forward is to define the primitives by compiling a
|
|
||||||
preprocessed version of the Emacs source code, not by trying to
|
|
||||||
implement them in Scheme. (Which, of course, is what Ken Raeburn's
|
|
||||||
project is already trying to do.)
|
|
||||||
|
|
||||||
Given this conclusion, I expect that most of the translator's Scheme
|
|
||||||
code will eventually become obsolete, replaced by bits of Emacs C
|
|
||||||
code. Until then, though, it should have a role:
|
|
||||||
|
|
||||||
- as a guide to the Guile Emacs project on how to interface to the
|
|
||||||
Elisp support in libguile (notably, usage of `@fop' and `@bind')
|
|
||||||
|
|
||||||
- as a proof of concept and fun thing to experiment with
|
|
||||||
|
|
||||||
- as a working translator that could help us develop our picture of
|
|
||||||
how we want to integrate translator usage in general with the rest
|
|
||||||
of Guile.
|
|
|
@ -1,48 +0,0 @@
|
||||||
(define-module (lang elisp base)
|
|
||||||
|
|
||||||
;; Be pure. Nothing in this module requires symbols that map to the
|
|
||||||
;; standard Guile builtins, and it creates a problem if this module
|
|
||||||
;; has access to them, as @bind can dynamically change their values.
|
|
||||||
;; Transformer output always uses the values of builtin procedures
|
|
||||||
;; and macros directly.
|
|
||||||
#:pure
|
|
||||||
|
|
||||||
;; {Elisp Primitives}
|
|
||||||
;;
|
|
||||||
;; In other words, Scheme definitions of elisp primitives. This
|
|
||||||
;; should (ultimately) include everything that Emacs defines in C.
|
|
||||||
#:use-module (lang elisp primitives buffers)
|
|
||||||
#:use-module (lang elisp primitives char-table)
|
|
||||||
#:use-module (lang elisp primitives features)
|
|
||||||
#:use-module (lang elisp primitives format)
|
|
||||||
#:use-module (lang elisp primitives fns)
|
|
||||||
#:use-module (lang elisp primitives guile)
|
|
||||||
#:use-module (lang elisp primitives keymaps)
|
|
||||||
#:use-module (lang elisp primitives lists)
|
|
||||||
#:use-module (lang elisp primitives load)
|
|
||||||
#:use-module (lang elisp primitives match)
|
|
||||||
#:use-module (lang elisp primitives numbers)
|
|
||||||
#:use-module (lang elisp primitives pure)
|
|
||||||
#:use-module (lang elisp primitives read)
|
|
||||||
#:use-module (lang elisp primitives signal)
|
|
||||||
#:use-module (lang elisp primitives strings)
|
|
||||||
#:use-module (lang elisp primitives symprop)
|
|
||||||
#:use-module (lang elisp primitives syntax)
|
|
||||||
#:use-module (lang elisp primitives system)
|
|
||||||
#:use-module (lang elisp primitives time)
|
|
||||||
|
|
||||||
;; Now switch into Emacs Lisp syntax.
|
|
||||||
#:use-syntax (lang elisp transform))
|
|
||||||
|
|
||||||
;;; Everything below here is written in Elisp.
|
|
||||||
|
|
||||||
(defun load-emacs (&optional new-load-path debug)
|
|
||||||
(if debug (message "load-path: %s" load-path))
|
|
||||||
(cond (new-load-path
|
|
||||||
(message "Setting load-path to: %s" new-load-path)
|
|
||||||
(setq load-path new-load-path)))
|
|
||||||
(if debug (message "load-path: %s" load-path))
|
|
||||||
(scheme (read-set! keywords 'prefix))
|
|
||||||
(message "Calling loadup.el to clothe the bare Emacs...")
|
|
||||||
(load "loadup.el")
|
|
||||||
(message "Guile Emacs now fully clothed"))
|
|
|
@ -1,39 +0,0 @@
|
||||||
|
|
||||||
(defun html-page (title &rest contents)
|
|
||||||
(concat "<HTML>\n"
|
|
||||||
"<HEAD>\n"
|
|
||||||
"<TITLE>" title "</TITLE>\n"
|
|
||||||
"</HEAD>\n"
|
|
||||||
"<BODY>\n"
|
|
||||||
(apply 'concat contents)
|
|
||||||
"</BODY>\n"
|
|
||||||
"</HTML>\n"))
|
|
||||||
|
|
||||||
(defmacro time (repeat-count &rest body)
|
|
||||||
`(let ((count ,repeat-count)
|
|
||||||
(beg (current-time))
|
|
||||||
end)
|
|
||||||
(while (> count 0)
|
|
||||||
(setq count (- count 1))
|
|
||||||
,@body)
|
|
||||||
(setq end (current-time))
|
|
||||||
(+ (* 1000000.0 (+ (* 65536.0 (- (car end) (car beg)))
|
|
||||||
(- (cadr end) (cadr beg))))
|
|
||||||
(* 1.0 (- (caddr end) (caddr beg))))))
|
|
||||||
|
|
||||||
;Non-scientific performance measurements (Guile measurements are with
|
|
||||||
;`guile -q --no-debug'):
|
|
||||||
;
|
|
||||||
;(time 100000 (+ 3 4))
|
|
||||||
; => 225,071 (Emacs) 4,000,000 (Guile)
|
|
||||||
;(time 100000 (lambda () 1))
|
|
||||||
; => 2,410,456 (Emacs) 4,000,000 (Guile)
|
|
||||||
;(time 100000 (apply 'concat (mapcar (lambda (s) (concat s "." s)) '("a" "b" "c" "d"))))
|
|
||||||
; => 10,185,792 (Emacs) 136,000,000 (Guile)
|
|
||||||
;(defun sc (s) (concat s "." s))
|
|
||||||
;(time 100000 (apply 'concat (mapcar 'sc '("a" "b" "c" "d"))))
|
|
||||||
; => 7,870,055 (Emacs) 26,700,000 (Guile)
|
|
||||||
;
|
|
||||||
;Sadly, it looks like the translator's performance sucks quite badly
|
|
||||||
;when compared with Emacs. But the translator is still very new, so
|
|
||||||
;there's probably plenty of room of improvement.
|
|
|
@ -1,4 +0,0 @@
|
||||||
(define-module (lang elisp expand)
|
|
||||||
#:export (expand))
|
|
||||||
|
|
||||||
(define (expand x) x)
|
|
|
@ -1,140 +0,0 @@
|
||||||
(define-module (lang elisp interface)
|
|
||||||
#:use-syntax (lang elisp expand)
|
|
||||||
#:use-module (lang elisp internals evaluation)
|
|
||||||
#:use-module (lang elisp internals fset)
|
|
||||||
#:use-module ((lang elisp internals load) #:select ((load . elisp:load)))
|
|
||||||
#:use-module ((lang elisp transform) #:select (transformer))
|
|
||||||
#:export (eval-elisp
|
|
||||||
translate-elisp
|
|
||||||
elisp-function
|
|
||||||
elisp-variable
|
|
||||||
load-elisp-file
|
|
||||||
load-elisp-library
|
|
||||||
use-elisp-file
|
|
||||||
use-elisp-library
|
|
||||||
export-to-elisp
|
|
||||||
load-emacs))
|
|
||||||
|
|
||||||
;;; This file holds my ideas for the mechanisms that would be useful
|
|
||||||
;;; to exchange definitions between Scheme and Elisp.
|
|
||||||
|
|
||||||
(define (eval-elisp x)
|
|
||||||
"Evaluate the Elisp expression @var{x}."
|
|
||||||
(save-module-excursion
|
|
||||||
(lambda ()
|
|
||||||
(set-current-module the-elisp-module)
|
|
||||||
(primitive-eval x))))
|
|
||||||
|
|
||||||
(define (translate-elisp x)
|
|
||||||
"Translate the Elisp expression @var{x} to equivalent Scheme code."
|
|
||||||
(transformer x))
|
|
||||||
|
|
||||||
(define (elisp-function sym)
|
|
||||||
"Return the procedure or macro that implements @var{sym} in Elisp.
|
|
||||||
If @var{sym} has no Elisp function definition, return @code{#f}."
|
|
||||||
(fref sym))
|
|
||||||
|
|
||||||
(define (elisp-variable sym)
|
|
||||||
"Return the variable that implements @var{sym} in Elisp.
|
|
||||||
If @var{sym} has no Elisp variable definition, return @code{#f}."
|
|
||||||
(module-variable the-elisp-module sym))
|
|
||||||
|
|
||||||
(define (load-elisp-file file-name)
|
|
||||||
"Load @var{file-name} into the Elisp environment.
|
|
||||||
@var{file-name} is assumed to name a file containing Elisp code."
|
|
||||||
;; This is the same as Elisp's `load-file', so use that if it is
|
|
||||||
;; available, otherwise duplicate the definition of `load-file' from
|
|
||||||
;; files.el.
|
|
||||||
(let ((load-file (elisp-function 'load-file)))
|
|
||||||
(if load-file
|
|
||||||
(load-file file-name)
|
|
||||||
(elisp:load file-name #f #f #t))))
|
|
||||||
|
|
||||||
(define (load-elisp-library library)
|
|
||||||
"Load library @var{library} into the Elisp environment.
|
|
||||||
@var{library} should name an Elisp code library that can be found in
|
|
||||||
one of the directories of @code{load-path}."
|
|
||||||
;; This is the same as Elisp's `load-file', so use that if it is
|
|
||||||
;; available, otherwise duplicate the definition of `load-file' from
|
|
||||||
;; files.el.
|
|
||||||
(let ((load-library (elisp-function 'load-library)))
|
|
||||||
(if load-library
|
|
||||||
(load-library library)
|
|
||||||
(elisp:load library))))
|
|
||||||
|
|
||||||
(define export-module-name
|
|
||||||
(let ((counter 0))
|
|
||||||
(lambda ()
|
|
||||||
(set! counter (+ counter 1))
|
|
||||||
(list 'lang 'elisp
|
|
||||||
(string->symbol (string-append "imports:"
|
|
||||||
(number->string counter)))))))
|
|
||||||
|
|
||||||
(define use-elisp-file
|
|
||||||
(procedure->memoizing-macro
|
|
||||||
(lambda (exp env)
|
|
||||||
"Load Elisp code file @var{file-name} and import its definitions
|
|
||||||
into the current Scheme module. If any @var{imports} are specified,
|
|
||||||
they are interpreted as selection and renaming specifiers as per
|
|
||||||
@code{use-modules}."
|
|
||||||
(let ((file-name (cadr exp))
|
|
||||||
(env (cddr exp)))
|
|
||||||
(let ((export-module-name (export-module-name)))
|
|
||||||
`(begin
|
|
||||||
(fluid-set! ,elisp-export-module (resolve-module ',export-module-name))
|
|
||||||
(beautify-user-module! (resolve-module ',export-module-name))
|
|
||||||
(load-elisp-file ,file-name)
|
|
||||||
(use-modules (,export-module-name ,@imports))
|
|
||||||
(fluid-set! ,elisp-export-module #f)))))))
|
|
||||||
|
|
||||||
(define use-elisp-library
|
|
||||||
(procedure->memoizing-macro
|
|
||||||
(lambda (exp env)
|
|
||||||
"Load Elisp library @var{library} and import its definitions into
|
|
||||||
the current Scheme module. If any @var{imports} are specified, they
|
|
||||||
are interpreted as selection and renaming specifiers as per
|
|
||||||
@code{use-modules}."
|
|
||||||
(let ((library (cadr exp))
|
|
||||||
(env (cddr exp)))
|
|
||||||
(let ((export-module-name (export-module-name)))
|
|
||||||
`(begin
|
|
||||||
(fluid-set! ,elisp-export-module (resolve-module ',export-module-name))
|
|
||||||
(beautify-user-module! (resolve-module ',export-module-name))
|
|
||||||
(load-elisp-library ,library)
|
|
||||||
(use-modules (,export-module-name ,@imports))
|
|
||||||
(fluid-set! ,elisp-export-module #f)))))))
|
|
||||||
|
|
||||||
(define (export-to-elisp . defs)
|
|
||||||
"Export procedures and variables specified by @var{defs} to Elisp.
|
|
||||||
Each @var{def} is either an object, in which case that object must be
|
|
||||||
a named procedure or macro and is exported to Elisp under its Scheme
|
|
||||||
name; or a symbol, in which case the variable named by that symbol is
|
|
||||||
exported under its Scheme name; or a pair @var{(obj . name)}, in which
|
|
||||||
case @var{obj} must be a procedure, macro or symbol as already
|
|
||||||
described and @var{name} specifies the name under which that object is
|
|
||||||
exported to Elisp."
|
|
||||||
(for-each (lambda (def)
|
|
||||||
(let ((obj (if (pair? def) (car def) def))
|
|
||||||
(name (if (pair? def) (cdr def) #f)))
|
|
||||||
(cond ((procedure? obj)
|
|
||||||
(or name
|
|
||||||
(set! name (procedure-name obj)))
|
|
||||||
(if name
|
|
||||||
(fset name obj)
|
|
||||||
(error "No procedure name specified or deducible:" obj)))
|
|
||||||
((macro? obj)
|
|
||||||
(or name
|
|
||||||
(set! name (macro-name obj)))
|
|
||||||
(if name
|
|
||||||
(fset name obj)
|
|
||||||
(error "No macro name specified or deducible:" obj)))
|
|
||||||
((symbol? obj)
|
|
||||||
(or name
|
|
||||||
(set! name obj))
|
|
||||||
(module-add! the-elisp-module name
|
|
||||||
(module-ref (current-module) obj)))
|
|
||||||
(else
|
|
||||||
(error "Can't export this kind of object to Elisp:" obj)))))
|
|
||||||
defs))
|
|
||||||
|
|
||||||
(define load-emacs (elisp-function 'load-emacs))
|
|
|
@ -1,13 +0,0 @@
|
||||||
(define-module (lang elisp internals evaluation)
|
|
||||||
#:export (the-elisp-module))
|
|
||||||
|
|
||||||
;;;; {Elisp Evaluation}
|
|
||||||
|
|
||||||
;;;; All elisp evaluation happens within the same module - namely
|
|
||||||
;;;; (lang elisp base). This is necessary both because elisp itself
|
|
||||||
;;;; has no concept of different modules - reflected for example in
|
|
||||||
;;;; its single argument `eval' function - and because Guile's current
|
|
||||||
;;;; implementation of elisp stores elisp function definitions in
|
|
||||||
;;;; slots in global symbol objects.
|
|
||||||
|
|
||||||
(define the-elisp-module (resolve-module '(lang elisp base)))
|
|
|
@ -1,62 +0,0 @@
|
||||||
(define-module (lang elisp internals format)
|
|
||||||
#:pure
|
|
||||||
#:use-module (ice-9 r5rs)
|
|
||||||
#:use-module ((ice-9 format) #:select ((format . scheme:format)))
|
|
||||||
#:use-module (lang elisp internals fset)
|
|
||||||
#:use-module (lang elisp internals signal)
|
|
||||||
#:replace (format)
|
|
||||||
#:export (message))
|
|
||||||
|
|
||||||
(define (format control-string . args)
|
|
||||||
|
|
||||||
(define (cons-string str ls)
|
|
||||||
(let loop ((sl (string->list str))
|
|
||||||
(ls ls))
|
|
||||||
(if (null? sl)
|
|
||||||
ls
|
|
||||||
(loop (cdr sl) (cons (car sl) ls)))))
|
|
||||||
|
|
||||||
(let loop ((input (string->list control-string))
|
|
||||||
(args args)
|
|
||||||
(output '())
|
|
||||||
(mid-control #f))
|
|
||||||
(if (null? input)
|
|
||||||
(if mid-control
|
|
||||||
(error "Format string ends in middle of format specifier")
|
|
||||||
(list->string (reverse output)))
|
|
||||||
(if mid-control
|
|
||||||
(case (car input)
|
|
||||||
((#\%)
|
|
||||||
(loop (cdr input)
|
|
||||||
args
|
|
||||||
(cons #\% output)
|
|
||||||
#f))
|
|
||||||
(else
|
|
||||||
(loop (cdr input)
|
|
||||||
(cdr args)
|
|
||||||
(cons-string (case (car input)
|
|
||||||
((#\s) (scheme:format #f "~A" (car args)))
|
|
||||||
((#\d) (number->string (car args)))
|
|
||||||
((#\o) (number->string (car args) 8))
|
|
||||||
((#\x) (number->string (car args) 16))
|
|
||||||
((#\e) (number->string (car args))) ;FIXME
|
|
||||||
((#\f) (number->string (car args))) ;FIXME
|
|
||||||
((#\g) (number->string (car args))) ;FIXME
|
|
||||||
((#\c) (let ((a (car args)))
|
|
||||||
(if (char? a)
|
|
||||||
(string a)
|
|
||||||
(string (integer->char a)))))
|
|
||||||
((#\S) (scheme:format #f "~S" (car args)))
|
|
||||||
(else
|
|
||||||
(error "Invalid format operation %%%c" (car input))))
|
|
||||||
output)
|
|
||||||
#f)))
|
|
||||||
(case (car input)
|
|
||||||
((#\%)
|
|
||||||
(loop (cdr input) args output #t))
|
|
||||||
(else
|
|
||||||
(loop (cdr input) args (cons (car input) output) #f)))))))
|
|
||||||
|
|
||||||
(define (message control-string . args)
|
|
||||||
(display (apply format control-string args))
|
|
||||||
(newline))
|
|
|
@ -1,113 +0,0 @@
|
||||||
(define-module (lang elisp internals fset)
|
|
||||||
#:use-module (lang elisp internals evaluation)
|
|
||||||
#:use-module (lang elisp internals lambda)
|
|
||||||
#:use-module (lang elisp internals signal)
|
|
||||||
#:export (fset
|
|
||||||
fref
|
|
||||||
fref/error-if-void
|
|
||||||
elisp-apply
|
|
||||||
interactive-specification
|
|
||||||
not-subr?
|
|
||||||
elisp-export-module))
|
|
||||||
|
|
||||||
(define the-variables-module (resolve-module '(lang elisp variables)))
|
|
||||||
|
|
||||||
;; By default, Guile GC's unreachable symbols. So we need to make
|
|
||||||
;; sure they stay reachable!
|
|
||||||
(define syms '())
|
|
||||||
|
|
||||||
;; elisp-export-module, if non-#f, holds a module to which definitions
|
|
||||||
;; should be exported under their normal symbol names. This is used
|
|
||||||
;; when importing Elisp definitions into Scheme.
|
|
||||||
(define elisp-export-module (make-fluid))
|
|
||||||
|
|
||||||
;; Store the procedure, macro or alias symbol PROC in SYM's function
|
|
||||||
;; slot.
|
|
||||||
(define (fset sym proc)
|
|
||||||
(or (memq sym syms)
|
|
||||||
(set! syms (cons sym syms)))
|
|
||||||
(let ((vcell (symbol-fref sym))
|
|
||||||
(vsym #f)
|
|
||||||
(export-module (fluid-ref elisp-export-module)))
|
|
||||||
;; Playing around with variables and name properties... For the
|
|
||||||
;; reasoning behind this, see the commentary in (lang elisp
|
|
||||||
;; variables).
|
|
||||||
(cond ((procedure? proc)
|
|
||||||
;; A procedure created from Elisp will already have a name
|
|
||||||
;; property attached, with value of the form
|
|
||||||
;; <elisp-defun:NAME> or <elisp-lambda>. Any other
|
|
||||||
;; procedure coming through here must be an Elisp primitive
|
|
||||||
;; definition, so we give it a name of the form
|
|
||||||
;; <elisp-subr:NAME>.
|
|
||||||
(or (procedure-name proc)
|
|
||||||
(set-procedure-property! proc
|
|
||||||
'name
|
|
||||||
(symbol-append '<elisp-subr: sym '>)))
|
|
||||||
(set! vsym (procedure-name proc)))
|
|
||||||
((macro? proc)
|
|
||||||
;; Macros coming through here must be defmacros, as all
|
|
||||||
;; primitive special forms are handled directly by the
|
|
||||||
;; transformer.
|
|
||||||
(set-procedure-property! (macro-transformer proc)
|
|
||||||
'name
|
|
||||||
(symbol-append '<elisp-defmacro: sym '>))
|
|
||||||
(set! vsym (procedure-name (macro-transformer proc))))
|
|
||||||
(else
|
|
||||||
;; An alias symbol.
|
|
||||||
(set! vsym (symbol-append '<elisp-defalias: sym '>))))
|
|
||||||
;; This is the important bit!
|
|
||||||
(if (variable? vcell)
|
|
||||||
(variable-set! vcell proc)
|
|
||||||
(begin
|
|
||||||
(set! vcell (make-variable proc))
|
|
||||||
(symbol-fset! sym vcell)
|
|
||||||
;; Playing with names and variables again - see above.
|
|
||||||
(module-add! the-variables-module vsym vcell)
|
|
||||||
(module-export! the-variables-module (list vsym))))
|
|
||||||
;; Export variable to the export module, if non-#f.
|
|
||||||
(if (and export-module
|
|
||||||
(or (procedure? proc)
|
|
||||||
(macro? proc)))
|
|
||||||
(begin
|
|
||||||
(module-add! export-module sym vcell)
|
|
||||||
(module-export! export-module (list sym))))))
|
|
||||||
|
|
||||||
;; Retrieve the procedure or macro stored in SYM's function slot.
|
|
||||||
;; Note the asymmetry w.r.t. fset: if fref finds an alias symbol, it
|
|
||||||
;; recursively calls fref on that symbol. Returns #f if SYM's
|
|
||||||
;; function slot doesn't contain a valid definition.
|
|
||||||
(define (fref sym)
|
|
||||||
(let ((var (symbol-fref sym)))
|
|
||||||
(if (and var (variable? var))
|
|
||||||
(let ((proc (variable-ref var)))
|
|
||||||
(cond ((symbol? proc)
|
|
||||||
(fref proc))
|
|
||||||
(else
|
|
||||||
proc)))
|
|
||||||
#f)))
|
|
||||||
|
|
||||||
;; Same as fref, but signals an Elisp error if SYM's function
|
|
||||||
;; definition is void.
|
|
||||||
(define (fref/error-if-void sym)
|
|
||||||
(or (fref sym)
|
|
||||||
(signal 'void-function (list sym))))
|
|
||||||
|
|
||||||
;; Maps a procedure to its (interactive ...) spec.
|
|
||||||
(define interactive-specification (make-object-property))
|
|
||||||
|
|
||||||
;; Maps a procedure to #t if it is NOT a built-in.
|
|
||||||
(define not-subr? (make-object-property))
|
|
||||||
|
|
||||||
(define (elisp-apply function . args)
|
|
||||||
(apply apply
|
|
||||||
(cond ((symbol? function)
|
|
||||||
(fref/error-if-void function))
|
|
||||||
((procedure? function)
|
|
||||||
function)
|
|
||||||
((and (pair? function)
|
|
||||||
(eq? (car function) 'lambda))
|
|
||||||
(eval (transform-lambda/interactive function '<elisp-lambda>)
|
|
||||||
the-root-module))
|
|
||||||
(else
|
|
||||||
(signal 'invalid-function (list function))))
|
|
||||||
args))
|
|
|
@ -1,109 +0,0 @@
|
||||||
(define-module (lang elisp internals lambda)
|
|
||||||
#:use-syntax (lang elisp expand)
|
|
||||||
#:use-module (lang elisp internals fset)
|
|
||||||
#:use-module (lang elisp transform)
|
|
||||||
#:export (parse-formals
|
|
||||||
transform-lambda/interactive
|
|
||||||
interactive-spec))
|
|
||||||
|
|
||||||
;;; Parses a list of elisp formals, e.g. (x y &optional b &rest r) and
|
|
||||||
;;; returns three values: (i) list of symbols for required arguments,
|
|
||||||
;;; (ii) list of symbols for optional arguments, (iii) rest symbol, or
|
|
||||||
;;; #f if there is no rest argument.
|
|
||||||
(define (parse-formals formals)
|
|
||||||
(letrec ((do-required
|
|
||||||
(lambda (required formals)
|
|
||||||
(if (null? formals)
|
|
||||||
(values (reverse required) '() #f)
|
|
||||||
(let ((next-sym (car formals)))
|
|
||||||
(cond ((not (symbol? next-sym))
|
|
||||||
(error "Bad formals (non-symbol in required list)"))
|
|
||||||
((eq? next-sym '&optional)
|
|
||||||
(do-optional required '() (cdr formals)))
|
|
||||||
((eq? next-sym '&rest)
|
|
||||||
(do-rest required '() (cdr formals)))
|
|
||||||
(else
|
|
||||||
(do-required (cons next-sym required)
|
|
||||||
(cdr formals))))))))
|
|
||||||
(do-optional
|
|
||||||
(lambda (required optional formals)
|
|
||||||
(if (null? formals)
|
|
||||||
(values (reverse required) (reverse optional) #f)
|
|
||||||
(let ((next-sym (car formals)))
|
|
||||||
(cond ((not (symbol? next-sym))
|
|
||||||
(error "Bad formals (non-symbol in optional list)"))
|
|
||||||
((eq? next-sym '&rest)
|
|
||||||
(do-rest required optional (cdr formals)))
|
|
||||||
(else
|
|
||||||
(do-optional required
|
|
||||||
(cons next-sym optional)
|
|
||||||
(cdr formals))))))))
|
|
||||||
(do-rest
|
|
||||||
(lambda (required optional formals)
|
|
||||||
(if (= (length formals) 1)
|
|
||||||
(let ((next-sym (car formals)))
|
|
||||||
(if (symbol? next-sym)
|
|
||||||
(values (reverse required) (reverse optional) next-sym)
|
|
||||||
(error "Bad formals (non-symbol rest formal)")))
|
|
||||||
(error "Bad formals (more than one rest formal)")))))
|
|
||||||
|
|
||||||
(do-required '() (cond ((list? formals)
|
|
||||||
formals)
|
|
||||||
((symbol? formals)
|
|
||||||
(list '&rest formals))
|
|
||||||
(else
|
|
||||||
(error "Bad formals (not a list or a single symbol)"))))))
|
|
||||||
|
|
||||||
(define (transform-lambda exp)
|
|
||||||
(call-with-values (lambda () (parse-formals (cadr exp)))
|
|
||||||
(lambda (required optional rest)
|
|
||||||
(let ((num-required (length required))
|
|
||||||
(num-optional (length optional)))
|
|
||||||
`(,lambda %--args
|
|
||||||
(,let ((%--num-args (,length %--args)))
|
|
||||||
(,cond ((,< %--num-args ,num-required)
|
|
||||||
(,error "Wrong number of args (not enough required args)"))
|
|
||||||
,@(if rest
|
|
||||||
'()
|
|
||||||
`(((,> %--num-args ,(+ num-required num-optional))
|
|
||||||
(,error "Wrong number of args (too many args)"))))
|
|
||||||
(else
|
|
||||||
(, @bind ,(append (map (lambda (i)
|
|
||||||
(list (list-ref required i)
|
|
||||||
`(,list-ref %--args ,i)))
|
|
||||||
(iota num-required))
|
|
||||||
(map (lambda (i)
|
|
||||||
(let ((i+nr (+ i num-required)))
|
|
||||||
(list (list-ref optional i)
|
|
||||||
`(,if (,> %--num-args ,i+nr)
|
|
||||||
(,list-ref %--args ,i+nr)
|
|
||||||
,%nil))))
|
|
||||||
(iota num-optional))
|
|
||||||
(if rest
|
|
||||||
(list (list rest
|
|
||||||
`(,if (,> %--num-args
|
|
||||||
,(+ num-required
|
|
||||||
num-optional))
|
|
||||||
(,list-tail %--args
|
|
||||||
,(+ num-required
|
|
||||||
num-optional))
|
|
||||||
,%nil)))
|
|
||||||
'()))
|
|
||||||
,@(map transformer (cddr exp)))))))))))
|
|
||||||
|
|
||||||
(define (set-not-subr! proc boolean)
|
|
||||||
(set! (not-subr? proc) boolean))
|
|
||||||
|
|
||||||
(define (transform-lambda/interactive exp name)
|
|
||||||
(fluid-set! interactive-spec #f)
|
|
||||||
(let* ((x (transform-lambda exp))
|
|
||||||
(is (fluid-ref interactive-spec)))
|
|
||||||
`(,let ((%--lambda ,x))
|
|
||||||
(,set-procedure-property! %--lambda (,quote name) (,quote ,name))
|
|
||||||
(,set-not-subr! %--lambda #t)
|
|
||||||
,@(if is
|
|
||||||
`((,set! (,interactive-specification %--lambda) (,quote ,is)))
|
|
||||||
'())
|
|
||||||
%--lambda)))
|
|
||||||
|
|
||||||
(define interactive-spec (make-fluid))
|
|
|
@ -1,44 +0,0 @@
|
||||||
(define-module (lang elisp internals load)
|
|
||||||
#:use-module (ice-9 optargs)
|
|
||||||
#:use-module (lang elisp internals signal)
|
|
||||||
#:use-module (lang elisp internals format)
|
|
||||||
#:use-module (lang elisp internals evaluation)
|
|
||||||
#:replace (load)
|
|
||||||
#:export (load-path))
|
|
||||||
|
|
||||||
(define load-path '("/usr/share/emacs/20.7/lisp/"
|
|
||||||
"/usr/share/emacs/20.7/lisp/emacs-lisp/"))
|
|
||||||
|
|
||||||
(define* (load file #:optional noerror nomessage nosuffix must-suffix)
|
|
||||||
(define (load1 filename)
|
|
||||||
(let ((pathname (let loop ((dirs (if (char=? (string-ref filename 0) #\/)
|
|
||||||
'("")
|
|
||||||
load-path)))
|
|
||||||
(cond ((null? dirs) #f)
|
|
||||||
((file-exists? (in-vicinity (car dirs) filename))
|
|
||||||
(in-vicinity (car dirs) filename))
|
|
||||||
(else (loop (cdr dirs)))))))
|
|
||||||
(if pathname
|
|
||||||
(begin
|
|
||||||
(or nomessage
|
|
||||||
(message "Loading %s..." pathname))
|
|
||||||
(with-input-from-file pathname
|
|
||||||
(lambda ()
|
|
||||||
(let loop ((form (read)))
|
|
||||||
(or (eof-object? form)
|
|
||||||
(begin
|
|
||||||
;; Note that `eval' already incorporates use
|
|
||||||
;; of the specified module's transformer.
|
|
||||||
(eval form the-elisp-module)
|
|
||||||
(loop (read)))))))
|
|
||||||
(or nomessage
|
|
||||||
(message "Loading %s...done" pathname))
|
|
||||||
#t)
|
|
||||||
#f)))
|
|
||||||
(or (and (not nosuffix)
|
|
||||||
(load1 (string-append file ".el")))
|
|
||||||
(and (not must-suffix)
|
|
||||||
(load1 file))
|
|
||||||
noerror
|
|
||||||
(signal 'file-error
|
|
||||||
(list "Cannot open load file" file))))
|
|
|
@ -1,13 +0,0 @@
|
||||||
(define-module (lang elisp internals null)
|
|
||||||
#:export (->nil lambda->nil null))
|
|
||||||
|
|
||||||
(define (->nil x)
|
|
||||||
(or x %nil))
|
|
||||||
|
|
||||||
(define (lambda->nil proc)
|
|
||||||
(lambda args
|
|
||||||
(->nil (apply proc args))))
|
|
||||||
|
|
||||||
(define (null obj)
|
|
||||||
(->nil (or (not obj)
|
|
||||||
(null? obj))))
|
|
|
@ -1,20 +0,0 @@
|
||||||
(define-module (lang elisp internals set)
|
|
||||||
#:use-module (lang elisp internals evaluation)
|
|
||||||
#:use-module (lang elisp internals signal)
|
|
||||||
#:export (set value))
|
|
||||||
|
|
||||||
;; Set SYM's variable value to VAL, and return VAL.
|
|
||||||
(define (set sym val)
|
|
||||||
(if (module-defined? the-elisp-module sym)
|
|
||||||
(module-set! the-elisp-module sym val)
|
|
||||||
(module-define! the-elisp-module sym val))
|
|
||||||
val)
|
|
||||||
|
|
||||||
;; Return SYM's variable value. If it has none, signal an error if
|
|
||||||
;; MUST-EXIST is true, just return #nil otherwise.
|
|
||||||
(define (value sym must-exist)
|
|
||||||
(if (module-defined? the-elisp-module sym)
|
|
||||||
(module-ref the-elisp-module sym)
|
|
||||||
(if must-exist
|
|
||||||
(error "Symbol's value as variable is void:" sym)
|
|
||||||
%nil)))
|
|
|
@ -1,18 +0,0 @@
|
||||||
(define-module (lang elisp internals signal)
|
|
||||||
#:use-module (lang elisp internals format)
|
|
||||||
#:replace (error)
|
|
||||||
#:export (signal
|
|
||||||
wta))
|
|
||||||
|
|
||||||
(define (signal error-symbol data)
|
|
||||||
(scm-error 'elisp-signal
|
|
||||||
#f
|
|
||||||
"Signalling ~A with data ~S"
|
|
||||||
(list error-symbol data)
|
|
||||||
#f))
|
|
||||||
|
|
||||||
(define (error . args)
|
|
||||||
(signal 'error (list (apply format args))))
|
|
||||||
|
|
||||||
(define (wta expected actual pos)
|
|
||||||
(signal 'wrong-type-argument (list expected actual)))
|
|
|
@ -1,14 +0,0 @@
|
||||||
(define-module (lang elisp internals time)
|
|
||||||
#:use-module (ice-9 optargs)
|
|
||||||
#:export (format-time-string))
|
|
||||||
|
|
||||||
(define* (format-time-string format-string #:optional time universal)
|
|
||||||
(strftime format-string
|
|
||||||
((if universal gmtime localtime)
|
|
||||||
(if time
|
|
||||||
(+ (ash (car time) 16)
|
|
||||||
(let ((time-cdr (cdr time)))
|
|
||||||
(if (pair? time-cdr)
|
|
||||||
(car time-cdr)
|
|
||||||
time-cdr)))
|
|
||||||
(current-time)))))
|
|
|
@ -1,28 +0,0 @@
|
||||||
(define-module (lang elisp internals trace)
|
|
||||||
#:export (trc trc-syms trc-all trc-none))
|
|
||||||
|
|
||||||
(define *syms* #f)
|
|
||||||
|
|
||||||
(define (trc-syms . syms)
|
|
||||||
(set! *syms* syms))
|
|
||||||
|
|
||||||
(define (trc-all)
|
|
||||||
(set! *syms* #f))
|
|
||||||
|
|
||||||
(define (trc-none)
|
|
||||||
(set! *syms* '()))
|
|
||||||
|
|
||||||
(define (trc . args)
|
|
||||||
(let ((sym (car args))
|
|
||||||
(args (cdr args)))
|
|
||||||
(if (or (and *syms*
|
|
||||||
(memq sym *syms*))
|
|
||||||
(not *syms*))
|
|
||||||
(begin
|
|
||||||
(write sym)
|
|
||||||
(display ": ")
|
|
||||||
(write args)
|
|
||||||
(newline)))))
|
|
||||||
|
|
||||||
;; Default to no tracing.
|
|
||||||
(trc-none)
|
|
|
@ -1,16 +0,0 @@
|
||||||
(define-module (lang elisp primitives buffers)
|
|
||||||
#:use-module (ice-9 optargs)
|
|
||||||
#:use-module (lang elisp internals fset))
|
|
||||||
|
|
||||||
(fset 'buffer-disable-undo
|
|
||||||
(lambda* (#:optional buffer)
|
|
||||||
'unimplemented))
|
|
||||||
|
|
||||||
(fset 're-search-forward
|
|
||||||
(lambda* (regexp #:optional bound noerror count)
|
|
||||||
'unimplemented))
|
|
||||||
|
|
||||||
(fset 're-search-backward
|
|
||||||
(lambda* (regexp #:optional bound noerror count)
|
|
||||||
'unimplemented))
|
|
||||||
|
|
|
@ -1,24 +0,0 @@
|
||||||
(define-module (lang elisp primitives char-table)
|
|
||||||
#:use-module (lang elisp internals fset)
|
|
||||||
#:use-module (lang elisp internals null)
|
|
||||||
#:use-module (ice-9 optargs))
|
|
||||||
|
|
||||||
(fset 'make-char-table
|
|
||||||
(lambda* (purpose #:optional init)
|
|
||||||
"Return a newly created char-table, with purpose PURPOSE.
|
|
||||||
Each element is initialized to INIT, which defaults to nil.
|
|
||||||
PURPOSE should be a symbol which has a `char-table-extra-slots' property.
|
|
||||||
The property's value should be an integer between 0 and 10."
|
|
||||||
(list purpose (vector init))))
|
|
||||||
|
|
||||||
(fset 'define-charset
|
|
||||||
(lambda (charset-id charset-symbol info-vector)
|
|
||||||
(list 'charset charset-id charset-symbol info-vector)))
|
|
||||||
|
|
||||||
(fset 'setup-special-charsets
|
|
||||||
(lambda ()
|
|
||||||
'unimplemented))
|
|
||||||
|
|
||||||
(fset 'make-char-internal
|
|
||||||
(lambda ()
|
|
||||||
'unimplemented))
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue