1
Fork 0
mirror of https://git.savannah.gnu.org/git/guile.git synced 2025-04-29 19:30:36 +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:
Andy Wingo 2009-12-11 10:21:31 +01:00
commit e42573315b
597 changed files with 39198 additions and 66642 deletions

8
.gitignore vendored
View file

@ -72,6 +72,8 @@ gdb-pre-inst-guile
cscope.out
cscope.files
*.log
gds-test.debug
gds-test.transcript
INSTALL
*.aux
*.cp
@ -106,8 +108,14 @@ INSTALL
/lib/time.h
/lib/unistd.h
/lib/unistr/.dirstamp
/lib/arpa/inet.h
/lib/stdio.h
/lib/sys/stat.h
/GPATH
/GRTAGS
/GSYMS
/GTAGS
/meta/guile-tools
/meta/guile-config
/lib/locale.h
/module/ice-9/eval.go.stamp

1
.gnuploadrc Normal file
View file

@ -0,0 +1 @@
--user ludo@gnu.org

4
.x-sc_GPL_version Normal file
View file

@ -0,0 +1,4 @@
^lib/
^gc-benchmarks/
^libguile/libgettext.h
^libguile/mkstemp.c

View file

@ -0,0 +1 @@
^lib/

View file

@ -0,0 +1 @@
^lib/

View file

@ -0,0 +1 @@
^libguile/stime.c

View file

@ -0,0 +1 @@
^gc-benchmarks/

View file

@ -0,0 +1,6 @@
^libguile/
^guile-readline/
^gc-benchmarks/
^emacs/
^NEWS
^doc/

View file

@ -0,0 +1 @@
^module/ice-9/match.scm

1
.x-sc_m4_quote_check Normal file
View file

@ -0,0 +1 @@
m4/version-etc.m4

3
.x-sc_makefile_check Normal file
View file

@ -0,0 +1,3 @@
lib(guile)?/
guile-readline/
srfi/

29
AUTHORS
View file

@ -206,8 +206,34 @@ In the subdirectory doc, changes to:
Many changes throughout.
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:
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:
deprecated.texi goops.texi scheme-ideas.texi
scheme-reading.texi
@ -227,6 +253,7 @@ In the subdirectory doc, changes to:
scm.texi scripts.texi script-getopt.texi
In the subdirectory doc/maint, wrote:
docstring.el
Many other changes throughout.
Thien-Thi Nguyen:
In the top-level directory, wrote:

127
GNUmakefile Normal file
View 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

View file

@ -2,15 +2,11 @@
GUILE_MAJOR_VERSION=1
GUILE_MINOR_VERSION=9
GUILE_MICRO_VERSION=2
GUILE_MICRO_VERSION=5
GUILE_EFFECTIVE_VERSION=${GUILE_MAJOR_VERSION}.${GUILE_MINOR_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
# 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
@ -54,9 +50,3 @@ LIBGUILE_SRFI_SRFI_60_INTERFACE_CURRENT=3
LIBGUILE_SRFI_SRFI_60_INTERFACE_REVISION=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_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}"

View file

@ -25,7 +25,7 @@
AUTOMAKE_OPTIONS = 1.10
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
include_HEADERS = libguile.h
@ -40,6 +40,8 @@ ACLOCAL_AMFLAGS = -I m4
DISTCLEANFILES = check-guile.log
DISTCHECK_CONFIGURE_FLAGS = --enable-error-on-warning
dist-hook: gen-ChangeLog
clean-local:

368
NEWS
View file

@ -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
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,
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
** Compiled procedures may now have more than one arity.
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
unlikely that any code out there actually used this functionality.
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.
** Removed deprecated uniform array procedures:
dimensions->uniform-array, list->uniform-array, array-prototype
** VM calling convention change: callee-parsed arguments
Instead, use make-typed-array, list->typed-array, or array-type,
respectively.
As an internal implementation detail, compiled procedures are now
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
Interested users should see the ChangeLog for more information.
Changes in 1.9.x (since the 1.8.x series):
* 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
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
** 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
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'
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
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 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
character. Strings manage their own allocation, switching if needed.
Currently no locale conversion is performed. Extended characters may be
written in a string using the hexadecimal escapes `\xXX', `\uXXXX', or
`\UXXXXXX', for 8-bit, 16-bit, or 24-bit codepoints, respectively.
Extended characters may be written in a literal string using the
hexadecimal escapes `\xXX', `\uXXXX', or `\UXXXXXX', for 8-bit, 16-bit,
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
@ -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
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
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'.
** 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.
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
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:
dimensions->uniform-array, list->uniform-array, array-prototype
Instead, use make-typed-array, list->typed-array, or array-type,
respectively.
** Last but not least, the `λ' macro can be used in lieu of `lambda'
* 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.
** 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'.
** 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_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.
** 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
** 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
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' 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
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
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
** 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)

13
README
View file

@ -33,6 +33,7 @@ Guile depends on the following external libraries.
- libintl
- libltdl
- libunistring
- libgc
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
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 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
available from http://www.gnu.org/software/libtool/
available from http://www.gnu.org/software/libtool/ .
- GNU libunistring
@ -81,6 +82,12 @@ Guile requires the following external packages:
`utf*->string' procedures. It is available from
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 =====================================

6
THANKS
View file

@ -30,6 +30,7 @@ For fixes or providing information which led to a fix:
Rob Browning
Adrian Bunk
Michael Carmack
R Clayton
Stephen Compall
Brian Crowder
Christopher Cramer
@ -52,6 +53,7 @@ For fixes or providing information which led to a fix:
Roland Haeder
Sven Hartrumpf
Eric Hanchrow
Judy Hawkins
Sam Hocevar
Patrick Horgan
Ales Hvezda
@ -74,6 +76,7 @@ For fixes or providing information which led to a fix:
Antoine Mathys
Dan McMahill
Roger Mc Murtrie
Scott McPeak
Tim Mooney
Han-Wen Nienhuys
Jan Nieuwenhuizen
@ -83,6 +86,7 @@ For fixes or providing information which led to a fix:
Peter O'Gorman
Pieter Pareit
Jack Pavlovsky
Derek Peschel
Arno Peters
Ron Peterson
David Pirotte
@ -94,6 +98,7 @@ For fixes or providing information which led to a fix:
Werner Scheinast
Bill Schottstaedt
Frank Schwidom
John Steele Scott
Thiemo Seufer
Scott Shedden
Alex Shinn
@ -114,6 +119,7 @@ For fixes or providing information which led to a fix:
Andreas Vögele
Michael Talbot-Wilson
Michael Tuexen
Thomas Wawrzinek
Mark H. Weaver
Jon Wilson
Andy Wingo

View file

@ -57,7 +57,7 @@ AC_DEFUN([GUILE_HEADER_LIBC_WITH_UNISTD],
]
)
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
included <unistd.h>. On some systems, they conflict, and libc.h
should be omitted. See GUILE_HEADER_LIBC_WITH_UNISTD in
@ -267,7 +267,7 @@ if test "x$acx_pthread_ok" = xyes; then
done
AC_MSG_RESULT($attr_name)
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
uses a non-standard name on your system.])
fi
@ -302,7 +302,7 @@ AC_SUBST(PTHREAD_CC)
# Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND:
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
acx_pthread_ok=no
@ -311,6 +311,64 @@ fi
AC_LANG_RESTORE
])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
dnl Check all the things needed by `guile-readline', the Readline

View file

@ -1,6 +1,8 @@
# -*- makefile -*-
GOBJECTS = $(SOURCES:%.scm=%.go)
GUILE_WARNINGS = -Wunbound-variable -Warity-mismatch
moddir = $(pkgdatadir)/$(GUILE_EFFECTIVE_VERSION)/$(modpath)
nobase_mod_DATA = $(SOURCES) $(NOCOMP_SOURCES)
ccachedir = $(pkglibdir)/$(GUILE_EFFECTIVE_VERSION)/ccache/$(modpath)
@ -30,4 +32,6 @@ install-data-hook:
SUFFIXES = .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 "$@" "$<"

View file

@ -15,9 +15,13 @@ autoconf --version
echo ""
automake --version
echo ""
libtool --version
if test "`uname -s`" = Darwin; then
glibtool --version
else
libtool --version
fi
echo ""
${M4:-/usr/bin/m4} --version
${M4:-m4} --version
echo ""
######################################################################

View file

@ -1,6 +1,6 @@
#! /bin/sh
# 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.
#
# Example invocations:
@ -21,7 +21,7 @@ if [ x"$1" = x-i ] ; then
shift
shift
else
guile=${top_builddir}/pre-inst-guile
guile=${top_builddir}/meta/guile
fi
GUILE_LOAD_PATH=$BENCHMARK_SUITE_DIR

View file

@ -1,6 +1,6 @@
SCM_BENCHMARKS = benchmarks/0-reference.bm \
benchmarks/bytevectors.bm \
benchmarks/continuations.bm \
benchmarks/continuations.bm \
benchmarks/if.bm \
benchmarks/logand.bm \
benchmarks/read.bm \

View file

@ -1,2 +1,6 @@
(define-module (benchmarks 0-reference)
:use-module (benchmark-suite lib))
(benchmark "reference benchmark for iteration counts" 330000
#t)

View file

@ -1,4 +1,4 @@
;;; -*- mode: scheme; coding: latin-1; -*-
;;; coding: latin1 -*- mode: scheme; coding: latin-1; -*-
;;; R6RS Byte Vectors.
;;;
;;; Copyright 2009 Ludovic Courtès <ludo@gnu.org>

View file

@ -1,4 +1,4 @@
;;; -*- mode: scheme; coding: latin-1; -*-
;;; coding: latin1 -*- mode: scheme; coding: latin-1; -*-
;;; chars.bm
;;;
;;; Copyright (C) 2009 Free Software Foundation, Inc.

View file

@ -1,5 +1,9 @@
(define-module (benchmarks continuations)
:use-module (benchmark-suite lib))
(define (callee continuation)
(continuation #t))
(benchmark "call/cc" 300
(benchmark "call/cc" 12000
(call-with-current-continuation callee))

View file

@ -1,3 +1,7 @@
(define-module (benchmarks if)
:use-module (benchmark-suite lib))
(with-benchmark-prefix "if-<expr>-then-else"
(benchmark "executing then" 330000

View file

@ -1,3 +1,7 @@
(define-module (benchmarks logand)
:use-module (benchmark-suite lib))
(define bignum (1- (expt 2 128)))
(let* ((i 0))

View file

@ -49,14 +49,14 @@
(benchmark "_IONBF" 5 ;; this one is very slow
(exercise-read (list _IONBF)))
(benchmark "_IOLBF" 100
(benchmark "_IOLBF" 10
(exercise-read (list _IOLBF)))
(benchmark "_IOFBF 4096" 100
(benchmark "_IOFBF 4096" 10
(exercise-read (list _IOFBF 4096)))
(benchmark "_IOFBF 8192" 100
(benchmark "_IOFBF 8192" 10
(exercise-read (list _IOFBF 8192)))
(benchmark "_IOFBF 16384" 100
(benchmark "_IOFBF 16384" 10
(exercise-read (list _IOFBF 16384))))

View file

@ -1,4 +1,4 @@
;;; -*- mode: scheme; coding: latin-1; -*-
;;; coding: latin1 -*- mode: scheme; coding: latin-1; -*-
;;; srfi-13.bm
;;;
;;; Copyright (C) 2009 Free Software Foundation, Inc.
@ -122,7 +122,7 @@ Italiam, fato profugus, Laviniaque venit")
(string-ref long-string k)
(loop (+ k 1))))))
(benchmark "copy" 1100
(benchmark "copy" 20000
(string-copy short-string)
(string-copy medium-string)
(string-copy long-string)
@ -130,7 +130,7 @@ Italiam, fato profugus, Laviniaque venit")
(substring/copy medium-string 10 20)
(substring/copy long-string 100 200))
(benchmark "pad" 6800
(benchmark "pad" 34000
(string-pad short-string 100)
(string-pad medium-string 100)
(string-pad long-string 100))

View file

@ -36,12 +36,12 @@
(with-benchmark-prefix "uniform-vector-read!"
(benchmark "uniform-vector-write" 500
(benchmark "uniform-vector-write" 4000
(let ((output (open-output-file file-name)))
(uniform-vector-write buf output)
(close output)))
(benchmark "uniform-vector-read!" 500
(benchmark "uniform-vector-read!" 20000
(let ((input (open-input-file file-name)))
(setvbuf input _IONBF)
(uniform-vector-read! buf input)

View file

@ -325,7 +325,7 @@
;;; A short form for benchmarks.
(defmacro benchmark (name iterations body . rest)
`(,run-benchmark ,name ,iterations (lambda () ,body ,@rest)))
`(run-benchmark ,name ,iterations (lambda () ,body ,@rest)))
;;;; BENCHMARK NAMES

View 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
View 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
View 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:

View file

@ -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.
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
# for the Emacs time-stamp write hook (at end) to update it.
# 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;
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
--version output version information and exit
@ -96,15 +101,17 @@ sub quoted_cmd(@)
{
my $since_date = '1970-01-01 UTC';
my $format_string = '%s%n%b%n';
GetOptions
(
help => sub { usage 0 },
version => sub { print "$ME version $VERSION\n"; exit },
'since=s' => \$since_date,
'format=s' => \$format_string,
) or usage 1;
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
or die ("$ME: failed to run `". quoted_cmd (@cmd) ."': $!\n"
. "(Is your Git too old? Version 1.5.1 or later is required.)\n");
@ -174,6 +181,7 @@ sub quoted_cmd(@)
}
# Local Variables:
# mode: perl
# indent-tabs-mode: nil
# eval: (add-hook 'write-file-hooks 'time-stamp)
# time-stamp-start: "my $VERSION = '"

115
build-aux/gnu-web-doc-update Executable file
View 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
View 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
View 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
View 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
View file

@ -0,0 +1 @@
old_NEWS_hash = d41d8cd98f00b204e9800998ecf8427e

View file

@ -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 the output.
dnl
AC_INIT(patsubst(m4_esyscmd(. ./GUILE-VERSION && echo ${PACKAGE}),[
]),
AC_INIT([GNU Guile],
patsubst(m4_esyscmd(. ./GUILE-VERSION && echo ${GUILE_VERSION}),[
]),
[bug-guile@gnu.org])
@ -64,6 +63,7 @@ AC_PROG_INSTALL
AC_PROG_CC
gl_EARLY
AC_PROG_CPP
AC_PROG_SED
AC_PROG_AWK
dnl Gnulib.
@ -86,13 +86,16 @@ AM_CONDITIONAL(HAVE_MAKEINFO, test "$have_makeinfo" = yes)
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.)
#
#--------------------------------------------------------------------
GUILE_ERROR_ON_WARNING="yes"
GUILE_ERROR_ON_WARNING="no"
AC_ARG_ENABLE(error-on-warning,
[ --enable-error-on-warning treat compile warnings as errors],
@ -113,7 +116,7 @@ AC_ARG_ENABLE(debug-freelist,
AC_ARG_ENABLE(debug-malloc,
[ --enable-debug-malloc include malloc debugging code],
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.])
fi)
@ -162,7 +165,7 @@ else
fi
SCM_I_GSC_ENABLE_DEPRECATED=1
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.])
AC_ARG_ENABLE(elisp,
@ -209,7 +212,7 @@ AC_ARG_WITH([64-calls],
AC_MSG_RESULT($use_64_calls)
case "$use_64_calls" in
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.])
;;
esac
@ -244,14 +247,14 @@ fi
if test "$enable_posix" = yes; then
AC_LIBOBJ([filesys])
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.])
fi
if test "$enable_networking" = yes; then
AC_LIBOBJ([net_db])
AC_LIBOBJ([socket])
AC_DEFINE(HAVE_NETWORKING, 1,
AC_DEFINE([HAVE_NETWORKING], 1,
[Define this if you want support for networking in Guile.])
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([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([intptr_t],[scm_stdint_has_intptr=1],,[#include <stdint.h>])
AC_CHECK_TYPE([uintptr_t],[scm_stdint_has_uintptr=1],,[#include <stdint.h>])
fi
# 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([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([intptr_t],[scm_inttypes_has_intptr=1],,[#include <inttypes.h>])
AC_CHECK_TYPE([uintptr_t],[scm_inttypes_has_uintptr=1],,[#include <inttypes.h>])
fi
# Try hard to find definitions for some required scm_t_*int* types.
@ -572,6 +579,46 @@ else
fi
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_INTTYPES_H])
@ -634,7 +681,7 @@ AC_CHECK_TYPES(complex double,,,
# On MacOS X <sys/socklen.h> contains socklen_t, so must include that
# when testing.
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.])],
[#if HAVE_SYS_TYPES_H
#include <sys/types.h>
@ -680,7 +727,7 @@ case $host in
fi
if test "$enable_shared" = yes ; then
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.])
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.
# sethostname - the function itself check because it's not in mingw,
# 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
# declaration isn't anywhere.
# cuserid - on Tru64 5.1b the declaration is documented to be available
# 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_DECLS([sethostname, hstrerror, cuserid])
@ -751,7 +797,7 @@ AC_CHECK_DECLS([sethostname, hstrerror, cuserid])
# libraries already in that list.
#
AC_SEARCH_LIBS(crypt, crypt,
[AC_DEFINE(HAVE_CRYPT,1,
[AC_DEFINE([HAVE_CRYPT],1,
[Define to 1 if you have the `crypt' function.])])
# When compiling with GCC on some OSs (Solaris, AIX), _Complex_I doesn't
@ -769,7 +815,7 @@ complex double z;
]], [[
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_COMPILE_IFELSE([AC_LANG_PROGRAM([[
#if HAVE_COMPLEX_H
@ -779,7 +825,7 @@ complex double z;
]],[[
z = 1.0fi;
]])],
[AC_DEFINE(GUILE_I,1.0fi)
[AC_DEFINE([GUILE_I],1.0fi)
AC_MSG_RESULT([1.0fi])],
[ac_cv_type_complex_double=no
AC_MSG_RESULT([not available])])])
@ -812,7 +858,7 @@ main (void)
[guile_cv_use_csqrt="yes, hopefully (cross-compiling)"])])
case $guile_cv_use_csqrt in
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
fi
@ -826,6 +872,11 @@ AC_LIB_HAVE_LINKFLAGS(gmp,
AC_MSG_ERROR([GNU MP 4.1 or greater not found, see README]))
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
#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])])
case "$guile_cv_func_usleep_return_type" in
"void" )
AC_DEFINE(USLEEP_RETURNS_VOID, 1,
AC_DEFINE([USLEEP_RETURNS_VOID], 1,
[Define if the system headers declare usleep to return void.])
;;
esac
AC_CHECK_HEADER(sys/un.h, have_sys_un_h=1)
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.])
fi
@ -890,8 +941,7 @@ AC_CHECK_FUNCS(sethostent gethostent endhostent dnl
setprotoent getprotoent endprotoent dnl
setservent getservent endservent dnl
getnetbyaddr getnetbyname dnl
inet_lnaof inet_makeaddr inet_netof hstrerror dnl
inet_pton inet_ntop)
inet_lnaof inet_makeaddr inet_netof hstrerror)
# 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
@ -912,7 +962,7 @@ extern char *__libc_stack_end;]],
AC_MSG_RESULT($guile_cv_have_libc_stack_end)
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.])
fi
@ -927,7 +977,7 @@ AC_CACHE_VAL(guile_cv_have_h_errno,
[guile_cv_have_h_errno=no])])
AC_MSG_RESULT($guile_cv_have_h_errno)
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
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])])
AC_MSG_RESULT($guile_cv_have_uint32_t)
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.])
fi
@ -961,7 +1011,7 @@ AC_CACHE_VAL(guile_cv_have_ipv6,
[guile_cv_have_ipv6=no])])
AC_MSG_RESULT($guile_cv_have_ipv6)
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
# 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])])
AC_MSG_RESULT($guile_cv_have_sin6_scope_id)
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.])
fi
@ -1034,7 +1084,7 @@ else
fi])dnl
AC_MSG_RESULT($guile_cv_localtime_cache)
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
if test "$enable_regex" = yes; then
@ -1052,7 +1102,7 @@ if test "$enable_regex" = yes; then
if test "$ac_cv_func_regcomp_norx" = yes ||
test "$ac_cv_func_regcomp_regex" = yes ||
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.])
fi
fi
@ -1084,7 +1134,7 @@ AC_LINK_IFELSE(AC_LANG_SOURCE(
volatile double x = 0.0;
int main () { return (isinf(x) != 0); }]]),
[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.])],
[AC_MSG_RESULT([no])])
AC_MSG_CHECKING([for isnan])
@ -1093,7 +1143,7 @@ AC_LINK_IFELSE(AC_LANG_SOURCE(
volatile double x = 0.0;
int main () { return (isnan(x) != 0); }]]),
[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.])],
[AC_MSG_RESULT([no])])
@ -1167,9 +1217,35 @@ main ()
[],
[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)
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.])
fi
@ -1183,7 +1259,7 @@ AC_CACHE_VAL(scm_cv_struct_linger,
[scm_cv_struct_linger="no"]))
AC_MSG_RESULT($scm_cv_struct_linger)
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
getsockopt and setsockopt system calls.])
fi
@ -1202,7 +1278,7 @@ AC_CACHE_VAL(scm_cv_struct_timespec,
[scm_cv_struct_timespec="no"]))
AC_MSG_RESULT($scm_cv_struct_timespec)
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>.])
fi
@ -1299,6 +1375,7 @@ case "$with_threads" in
;;
"no" | "null")
SCM_I_GSC_USE_NULL_THREADS=1
SCM_I_GSC_HAVE_THREAD_STORAGE_CLASS=0
with_threads="null-threads"
;;
* )
@ -1347,12 +1424,14 @@ int main ()
#endif
]])],
[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],
[])
CFLAGS="$old_CFLAGS"
AC_MSG_RESULT($works)
GUILE_THREAD_LOCAL_STORAGE
fi # with_threads=pthreads
@ -1400,6 +1479,7 @@ AC_ARG_VAR(GUILE_FOR_BUILD,[guile for build system])
AC_SUBST(GUILE_FOR_BUILD)
## If we're using GCC, ask for aggressive warnings.
GCC_CFLAGS=""
case "$GCC" in
yes )
## We had -Wstrict-prototypes in here for a bit, but Guile does too
@ -1407,19 +1487,30 @@ case "$GCC" in
## less than exasperating.
## -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).
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
# not be "warning free"
if test "${GUILE_ERROR_ON_WARNING}" = yes
then
GCC_CFLAGS="${GCC_CFLAGS} -Werror"
POTENTIAL_GCC_CFLAGS="${POTENTIAL_GCC_CFLAGS} -Werror"
enable_compile_warnings=no
fi
for flag in $POTENTIAL_GCC_CFLAGS
do
gl_WARN_ADD([$flag], [GCC_CFLAGS])
done
;;
esac
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
## need to generate a list of .lo files corresponding to the .o files
## 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 Note: `sitedir' must be kept in sync with `GUILE_SITE_DIR' in `guile.m4'.
pkgdatadir="$datadir/guile"
pkgdatadir="$datadir/$PACKAGE_TARNAME"
sitedir="$pkgdatadir/site"
AC_SUBST([sitedir])
@ -1523,7 +1614,6 @@ AC_CONFIG_FILES([
doc/tutorial/Makefile
emacs/Makefile
examples/Makefile
lang/Makefile
libguile/Makefile
srfi/Makefile
guile-readline/Makefile

96
doc/gendocs_template Normal file
View 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 &amp; GNU inquiries to
<a href="mailto:gnu@gnu.org">&lt;gnu@gnu.org&gt;</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%%">&lt;%%EMAIL%%&gt;</a>.
</p>
<p>Copyright &copy; 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>

View file

@ -1750,22 +1750,6 @@ current interfaces. If a file cannot be opened with the access
requested, @code{open-file} throws an exception.
@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
@c snarfed from gc.c:276
@deffn {Scheme Procedure} gc-live-object-stats
@ -10708,8 +10692,8 @@ the input is an integer with normal host byte ordering.
@lisp
(inet-ntop AF_INET 2130706433) @result{} "127.0.0.1"
(inet-ntop AF_INET6 (- (expt 2 128) 1)) @result{}
ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff
(inet-ntop AF_INET6 (- (expt 2 128) 1))
@result{} "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"
@end lisp
@end deffn

View file

@ -1,6 +1,6 @@
@c -*-texinfo-*-
@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 See the file guile.texi for copying conditions.
@ -1506,8 +1506,8 @@ which is the name of the procedure incorrectly invoked.
@subsection Continuation Barriers
The non-local flow of control caused by continuations might sometimes
not be wanted. You can use @code{with-continuation-barrier} etc to
errect fences that continuations can not pass.
not be wanted. You can use @code{with-continuation-barrier} to erect
fences that continuations can not pass.
@deffn {Scheme Procedure} with-continuation-barrier proc
@deffnx {C Function} scm_with_continuation_barrier (proc)

View file

@ -184,7 +184,6 @@ in Scheme, which is particularly clear and accessible: see
* Complex:: Complex number operations.
* Arithmetic:: Arithmetic functions.
* Scientific:: Scientific functions.
* Primitive Numerics:: Primitive numeric functions.
* Bitwise Operations:: Logical AND, OR, NOT, and so on.
* Random:: Random number generation.
@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.
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.
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
@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
will be exactly equal to @var{val}.
@end deftypefn
@ -1337,150 +1336,6 @@ Return the hyperbolic arctangent of @var{z}.
@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
@subsubsection Bitwise Operations
@ -1779,16 +1634,66 @@ another manual.
@subsection 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
@var{name} is the name of the character that you want. Printable
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
@acronym{ASCII} character set, as well as the space, may be referred
to by longer names: for example, @code{#\tab}, @code{#\esc},
@code{#\stx}, and so on. The following table describes the
@acronym{ASCII} names for each character.
Some of the code points are 'combining characters' that are not meant
to be printed by themselves but are instead meant to modify the
appearance of the previous character. For combining characters, an
alternate form of the character literal is @code{#\} followed by
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
@item 0 = @code{#\nul}
@ -1801,9 +1706,9 @@ to by longer names: for example, @code{#\tab}, @code{#\esc},
@tab 7 = @code{#\bel}
@item 8 = @code{#\bs}
@tab 9 = @code{#\ht}
@tab 10 = @code{#\nl}
@tab 10 = @code{#\lf}
@tab 11 = @code{#\vt}
@item 12 = @code{#\np}
@item 12 = @code{#\ff}
@tab 13 = @code{#\cr}
@tab 14 = @code{#\so}
@tab 15 = @code{#\si}
@ -1826,85 +1731,112 @@ to by longer names: for example, @code{#\tab}, @code{#\esc},
@item 32 = @code{#\sp}
@end multitable
The ``delete'' character (octal 177) may be referred to with the name
@code{#\del}.
The ``delete'' character (code point U+007F) may be referred to with the
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}
@item Alias @tab Original
@item @code{#\space} @tab @code{#\sp}
@item @code{#\newline} @tab @code{#\nl}
@multitable {@code{#\backspace}} {Preferred}
@item Alternate @tab Standard
@item @code{#\sp} @tab @code{#\space}
@item @code{#\nl} @tab @code{#\newline}
@item @code{#\lf} @tab @code{#\newline}
@item @code{#\tab} @tab @code{#\ht}
@item @code{#\backspace} @tab @code{#\bs}
@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}
@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?
@deffn {Scheme Procedure} char? x
@deffnx {C Function} scm_char_p (x)
Return @code{#t} iff @var{x} is a character, else @code{#f}.
@end deffn
Fundamentally, the character comparison operations below are
numeric comparisons of the character's code points.
@rnindex char=?
@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
@rnindex char<?
@deffn {Scheme Procedure} char<? x y
Return @code{#t} iff @var{x} is less than @var{y} in the @acronym{ASCII} sequence,
else @code{#f}.
Return @code{#t} iff the code point of @var{x} is less than the code
point of @var{y}, else @code{#f}.
@end deffn
@rnindex char<=?
@deffn {Scheme Procedure} char<=? x y
Return @code{#t} iff @var{x} is less than or equal to @var{y} in the
@acronym{ASCII} sequence, else @code{#f}.
Return @code{#t} iff the code point of @var{x} is less than or equal
to the code point of @var{y}, else @code{#f}.
@end deffn
@rnindex char>?
@deffn {Scheme Procedure} char>? x y
Return @code{#t} iff @var{x} is greater than @var{y} in the @acronym{ASCII}
sequence, else @code{#f}.
Return @code{#t} iff the code point of @var{x} is greater than the
code point of @var{y}, else @code{#f}.
@end deffn
@rnindex char>=?
@deffn {Scheme Procedure} char>=? x y
Return @code{#t} iff @var{x} is greater than or equal to @var{y} in the
@acronym{ASCII} sequence, else @code{#f}.
Return @code{#t} iff the code point of @var{x} is greater than or
equal to the code point of @var{y}, else @code{#f}.
@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=?
@deffn {Scheme Procedure} char-ci=? x y
Return @code{#t} iff @var{x} is the same character as @var{y} ignoring
case, else @code{#f}.
Return @code{#t} iff the case-folded code point of @var{x} is the same
as the case-folded code point of @var{y}, else @code{#f}.
@end deffn
@rnindex char-ci<?
@deffn {Scheme Procedure} char-ci<? x y
Return @code{#t} iff @var{x} is less than @var{y} in the @acronym{ASCII} sequence
ignoring case, else @code{#f}.
Return @code{#t} iff the case-folded code point of @var{x} is less
than the case-folded code point of @var{y}, else @code{#f}.
@end deffn
@rnindex char-ci<=?
@deffn {Scheme Procedure} char-ci<=? x y
Return @code{#t} iff @var{x} is less than or equal to @var{y} in the
@acronym{ASCII} sequence ignoring case, else @code{#f}.
Return @code{#t} iff the case-folded code point of @var{x} is less
than or equal to the case-folded code point of @var{y}, else
@code{#f}.
@end deffn
@rnindex char-ci>?
@deffn {Scheme Procedure} char-ci>? x y
Return @code{#t} iff @var{x} is greater than @var{y} in the @acronym{ASCII}
sequence ignoring case, else @code{#f}.
Return @code{#t} iff the case-folded code point of @var{x} is greater
than the case-folded code point of @var{y}, else @code{#f}.
@end deffn
@rnindex char-ci>=?
@deffn {Scheme Procedure} char-ci>=? x y
Return @code{#t} iff @var{x} is greater than or equal to @var{y} in the
@acronym{ASCII} sequence ignoring case, else @code{#f}.
Return @code{#t} iff the case-folded code point of @var{x} is greater
than or equal to the case-folded code point of @var{y}, else
@code{#f}.
@end deffn
@rnindex char-alphabetic?
@ -1946,14 +1878,15 @@ Return @code{#t} iff @var{chr} is either uppercase or lowercase, else
@rnindex char->integer
@deffn {Scheme Procedure} char->integer chr
@deffnx {C Function} scm_char_to_integer (chr)
Return the number corresponding to ordinal position of @var{chr} in the
@acronym{ASCII} sequence.
Return the code point of @var{chr}.
@end deffn
@rnindex integer->char
@deffn {Scheme Procedure} integer->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
@rnindex char-upcase
@ -1981,12 +1914,6 @@ handling them are provided.
Character sets can be created, extended, tested for the membership of a
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
* Character Set Predicates/Comparison::
* 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
specified range contains characters which are not contained in
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.
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
specified range contains characters which are not contained in
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.
The characters are added to @var{base_cs} and @var{base_cs} is
@ -2210,7 +2137,10 @@ returned.
@deffn {Scheme Procedure} ->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
@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
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
@deffnx {C Function} scm_char_set_size (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}.
@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
@deffnx {C Function} scm_char_set_union (rest)
Return the union of all argument character sets.
@ -2371,12 +2324,10 @@ useful, several predefined character set variables exist.
@cindex charset
@cindex locale
Currently, the contents of these character sets are recomputed upon a
successful @code{setlocale} call (@pxref{Locales}) in order to reflect
the characters available in the current locale's codeset. For
instance, @code{char-set:letter} contains 52 characters under an ASCII
locale (e.g., the default @code{C} locale) and 117 characters under an
ISO-8859-1 (``Latin-1'') locale.
These character sets are locale independent and are not recomputed
upon a @code{setlocale} call. They contain characters from the whole
range of Unicode code points. For instance, @code{char-set:letter}
contains about 94,000 characters.
@defvr {Scheme Variable} 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
@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
@defvr {Scheme Variable} char-set:letter
@defvrx {C Variable} scm_char_set_letter
All letters, e.g. the union of @code{char-set:lower-case} and
@code{char-set:upper-case}.
All letters. This includes @code{char-set:lower-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
@defvr {Scheme Variable} char-set:digit
@ -2426,23 +2380,26 @@ All whitespace characters.
@defvr {Scheme Variable} char-set:blank
@defvrx {C Variable} scm_char_set_blank
All horizontal whitespace characters, that is @code{#\space} and
@code{#\tab}.
All horizontal whitespace characters, which notably includes
@code{#\space} and @code{#\tab}.
@end defvr
@defvr {Scheme Variable} 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
@defvr {Scheme Variable} char-set:punctuation
@defvrx {C Variable} scm_char_set_punctuation
The characters @code{!"#%&'()*,-./:;?@@[\\]_@{@}}
All punctuation characters, such as the characters
@code{!"#%&'()*,-./:;?@@[\\]_@{@}}
@end defvr
@defvr {Scheme Variable} char-set:symbol
@defvrx {C Variable} scm_char_set_symbol
The characters @code{$+<=>^`|~}.
All symbol characters, such as the characters @code{$+<=>^`|~}.
@end defvr
@defvr {Scheme Variable} char-set:hex-digit
@ -2460,9 +2417,17 @@ All ASCII characters.
The empty character set.
@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
@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
@node Strings
@ -2490,7 +2455,7 @@ memory.
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
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
memory is delayed until one string is written to.
@ -2580,6 +2545,14 @@ Vertical tab character (ASCII 11).
@item @nicode{\xHH}
Character code given by two hexadecimal digits. For example
@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
@noindent
@ -2910,7 +2883,7 @@ characters.
@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_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
(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.
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
@code{?}. The predicates ending in @code{-ci} ignore the character case
when comparing strings. @xref{Text Collation, the @code{(ice-9
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
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.
@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]]
@deffnx {C Function} scm_string_index (s, char_pred, start, end)
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
@item
equals @var{char_pred}, if it is character,
@item
satisifies the predicate @var{char_pred}, if it is a procedure,
satisfies the predicate @var{char_pred}, if it is a procedure,
@item
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]]
@deffnx {C Function} scm_string_rindex (s, char_pred, start, end)
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
@item
equals @var{char_pred}, if it is character,
@item
satisifies the predicate @var{char_pred}, if it is a procedure,
satisfies the predicate @var{char_pred}, if it is a procedure,
@item
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]]
@deffnx {C Function} scm_string_index_right (s, char_pred, start, end)
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
@item
equals @var{char_pred}, if it is character,
@item
satisifies the predicate @var{char_pred}, if it is a procedure,
satisfies the predicate @var{char_pred}, if it is a procedure,
@item
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]]
@deffnx {C Function} scm_string_skip (s, char_pred, start, end)
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
@item
does not equal @var{char_pred}, if it is character,
@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,
@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]]
@deffnx {C Function} scm_string_skip_right (s, char_pred, start, end)
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
@item
@ -3330,7 +3308,7 @@ Return the count of the number of characters in the string
equals @var{char_pred}, if it is character,
@item
satisifies the predicate @var{char_pred}, if it is a procedure.
satisfies the predicate @var{char_pred}, if it is a procedure.
@item
is in the set @var{char_pred}, if it is a character set.

View file

@ -1708,7 +1708,7 @@ facilities just described.
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,
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
file @file{matrix.scm} defines a procedure @code{mkmatrix}, which is
@ -1718,7 +1718,6 @@ calls @code{mkmatrix}.
@lisp
$ /usr/bin/guile -q
guile> (use-modules (ice-9 debugger)
(ice-9 debugging ice-9-debugger-extensions)
(ice-9 debugging traps))
guile> (load "matrix.scm")
guile> (install-trap (make <procedure-trap>
@ -1758,10 +1757,9 @@ guile>
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 debugging ice-9-debugger-extensions)}, and changing
@code{debug-trap} to @code{gds-debug-trap}. Then the stack and
corresponding source locations are displayed in Emacs instead of on
the Guile command line.
changing @code{debug-trap} to @code{gds-debug-trap}. Then the stack and
corresponding source locations are displayed in Emacs instead of on the
Guile command line.
@node Profiling or Tracing a Procedure's Code

View file

@ -1,6 +1,6 @@
@c -*-texinfo-*-
@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 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.
* Compilation:: How to compile Scheme files and procedures.
* 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.
* Local Evaluation:: Evaluation in a local environment.
* 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
(@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
@subsubsection Case Sensitivity
@ -531,13 +553,20 @@ documentation for @code{%load-hook} later in this section.
@code{SCM}.
@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)
Search @code{%load-path} for the file named @var{filename} and
load it into the top-level environment. If @var{filename} is a
relative pathname and is not found in the list of search paths,
an error is signalled. Preferentially loads a compiled version of the
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
@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
@code{fluid-ref} and @code{fluid-set!} (@pxref{Fluids and Dynamic
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
@defvar %load-hook
@ -590,6 +634,82 @@ a file to load. By default, @code{%load-extensions} is bound to the
list @code{("" ".scm")}.
@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
@subsection Delayed Evaluation

View file

@ -1,6 +1,6 @@
@c -*-texinfo-*-
@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 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))
@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
The @code{(ice-9 i18n)} module provides procedures to manipulate text

View file

@ -47,7 +47,7 @@ are two interesting and powerful examples of this technique.
Ports are garbage collected in the usual way (@pxref{Memory
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
its operations have been successful. Of course if a program has
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
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?
@deffn {Scheme Procedure} input-port? 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}))}.
@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
@subsection Reading
@ -238,7 +307,7 @@ output port if not given.
The output is designed to be machine readable, and can be read back
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.
@end deffn
@ -248,7 +317,7 @@ Send a representation of @var{obj} to @var{port} or to the current
output port if not given.
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
@samp{#\} form.
@end deffn
@ -496,7 +565,7 @@ used. This function is equivalent to:
@end lisp
@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
internals.
@ -815,11 +884,11 @@ Open @var{filename} for output. Equivalent to
Open @var{filename} for input or output, and call @code{(@var{proc}
port)} with the resulting port. Return the value returned by
@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.
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
way if not otherwise referenced.
@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
value returned by @var{thunk}. @var{filename} is opened as per
@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
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*
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
@deffnx {C Function} scm_call_with_output_string (proc)
Calls the one-argument procedure @var{proc} with a newly created output
@ -1409,7 +1485,7 @@ is set.
@node Port Implementation
@subsubsection Port Implementation
@cindex Port implemenation
@cindex Port implementation
This section describes how to implement a new port type in C.

View file

@ -1,6 +1,6 @@
@c -*-texinfo-*-
@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 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
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.
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
@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
@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
with the functions malloc, realloc, and free. Guile has additional
functions for dynamic memory allocation that are integrated into the
garbage collector and the error reporting system.
Memory blocks that are associated with Scheme objects (for example a
smob) should be allocated and freed with @code{scm_gc_malloc} and
@code{scm_gc_free}. The function @code{scm_gc_malloc} will either
return a valid pointer or signal an error. It will also assume that
the new memory can be freed by a garbage collection. The garbage
collector uses this information to decide when to try to actually
collect some garbage. Memory blocks allocated with
@code{scm_gc_malloc} must be freed with @code{scm_gc_free}.
smob) should be allocated with @code{scm_gc_malloc} or
@code{scm_gc_malloc_pointerless}. These two functions will either
return a valid pointer or signal an error. Memory blocks allocated this
way can be freed with @code{scm_gc_free}; however, this is not strictly
needed: memory allocated with @code{scm_gc_malloc} or
@code{scm_gc_malloc_pointerless} is automatically reclaimed when the
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
@code{scm_malloc} instead of @code{malloc}. Like
@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
be freed by a garbage collection. The memory can be freed with
@code{free}.
be freed by a garbage collection. The memory must be explicitly freed
with @code{free}.
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}
and @code{scm_calloc}, to be used in place of @code{calloc} when
appropriate.
The function @code{scm_dynwind_free} can be useful when memory should
be freed when 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}.
The function @code{scm_dynwind_free} can be useful when memory should be
freed with libc's @code{free} when leaving a dynwind context,
@xref{Dynamic Wind}.
@deftypefn {C Function} {void *} scm_malloc (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})
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
@ -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
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
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
memory.
In Guile 2.x, this function has no effect.
@end deftypefn
@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
this, the GC might have a wrong impression of what is going on and run
much less efficiently than it could.
In Guile 2.x, this function has no effect.
@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)
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{n} is the number of objects of that type currently
allocated.
This function is only available if the @code{GUILE_DEBUG_MALLOC}
preprocessor macro was defined when Guile was compiled.
@end deffn

View file

@ -758,7 +758,7 @@ Record definition with @code{define-record-type} (@pxref{SRFI-9}).
Read hash extension @code{#,()} (@pxref{SRFI-10}).
@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}).
@item (srfi srfi-13)

View file

@ -1,6 +1,6 @@
@c -*-texinfo-*-
@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 See the file guile.texi for copying conditions.
@ -113,15 +113,21 @@ string, into a list and return the resulting list with
is returned.
@end deffn
@deffn {Scheme Procedure} search-path path filename [extensions]
@deffnx {C Function} scm_search_path (path, filename, extensions)
@deffn {Scheme Procedure} search-path path filename [extensions [require-exts?]]
@deffnx {C Function} scm_search_path (path, filename, rest)
Search @var{path} for a directory containing a file named
@var{filename}. The file must be readable, and not a directory.
If we find one, return its full filename; otherwise, return
@code{#f}. If @var{filename} is absolute, return it unchanged.
If given, @var{extensions} is a list of strings; for each
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
@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.
@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
@subsection Feature Tracking

View file

@ -1,6 +1,6 @@
@c -*-texinfo-*-
@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 See the file guile.texi for copying conditions.
@ -13,6 +13,7 @@
* Primitive Procedures:: Procedures defined in C.
* Compiled Procedures:: Scheme procedures can be compiled.
* Optional Arguments:: Handling keyword, optional and rest arguments.
* Case-lambda:: One function, multiple arities.
* Procedure Properties:: Procedure properties and meta-information.
* Procedures with Setters:: Procedures with setters.
* Macros:: Lisp style macro definitions.
@ -26,8 +27,6 @@
@subsection Lambda: Basic Procedure Creation
@cindex lambda
@c FIXME::martin: Review me!
A @code{lambda} expression evaluates to a procedure. The environment
which is in effect when a @code{lambda} expression is evaluated is
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
@subsection Compiled Procedures
Procedures that were created when loading a compiled file are
themselves compiled. (In contrast, procedures that are defined by
loading a Scheme source file are interpreted, and often not as fast as
compiled procedures.)
In Guile, procedures can be executed by directly interpreting their
source code. Scheme source code is a set of nested lists, after all,
with each list representing a procedure call.
Loading compiled files is the normal way that compiled procedures come
to being, though procedures can be compiled at runtime as well.
@xref{Read/Load/Eval/Compile}, for more information on runtime
compilation.
Most procedures are compiled, however. This means that Guile has done
some pre-computation on the procedure, to determine what it will need
to do each time the procedure runs. Compiled procedures run faster
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
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.
@end deffn
@deffn {Scheme Procedure} program-external program
@deffnx {C Function} scm_program_external (program)
Returns the set of heap-allocated variables that this program captures
in its closure, as a list. If a closure is code with data, you can get
the code from @code{program-bytecode}, and the data via
@code{program-external}.
@deffn {Scheme Procedure} program-free-variables program
@deffnx {C Function} scm_program_free_variables (program)
Returns the set of free variables that this program captures in its
closure, as a vector. If a closure is code with data, you can get the
code from @code{program-objcode}, and the data via
@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
really clever.
@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
@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
metadata.
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.
@end deffn
@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:extp binding
@deffnx {Scheme Procedure} binding:boxed? binding
@deffnx {Scheme Procedure} binding:index binding
@deffnx {Scheme Procedure} binding:start 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.
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
whether the binding is heap-allocated or not. @xref{VM Concepts}, for
more information.
REPL. @xref{VM Concepts}, for more information.
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
@ -262,6 +243,40 @@ following} an instruction, so that backtraces can find the source
location of a call that is in progress.
@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
Return the properties of a @code{program} as an association list,
keyed by property name (a symbol).
@ -285,42 +300,143 @@ Accessors for specific properties.
@node Optional Arguments
@subsection Optional Arguments
@c FIXME::martin: Review me!
Scheme procedures, as defined in R5RS, can either handle a fixed number
of actual arguments, or a fixed number of actual arguments followed by
arbitrarily many additional arguments. Writing procedures of variable
arity can be useful, but unfortunately, the syntactic means for handling
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
(@pxref{Lambda}).
Guile comes with the module @code{(ice-9 optargs)}, which makes using
optional arguments much more convenient. In addition, this module
provides syntax for handling keywords in argument lists
(@pxref{Keywords}).
Before using any of the procedures or macros defined in this section,
you have to load the module @code{(ice-9 optargs)} with the statement:
@cindex @code{optargs}
@lisp
(use-modules (ice-9 optargs))
@end lisp
For this reason, Guile provides an extension to @code{lambda},
@code{lambda*}, which allows the user to define procedures with
optional and keyword arguments. In addition, Guile's virtual machine
has low-level support for optional and keyword argument dispatch.
Calls to procedures with optional and keyword arguments can be made
cheaply, without allocating a rest list.
@menu
* let-optional Reference:: Locally binding optional arguments.
* let-keywords Reference:: Locally binding keywords arguments.
* lambda* Reference:: Creating advanced argument handling procedures.
* define* Reference:: Defining procedures and macros.
* lambda* and define*:: Creating advanced argument handling procedures.
* ice-9 optargs:: (ice-9 optargs) provides some utilities.
@end menu
@node let-optional Reference
@subsubsection let-optional Reference
@node lambda* and define*
@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
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.
@end deffn
@node let-keywords Reference
@subsubsection let-keywords Reference
@code{let-keywords} and @code{let-keywords*} extract values from
keyword style argument lists, binding local variables to those values
or to defaults.
Similarly, @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{}
@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
ignored (such as @code{#:xyzzy} in the example), when @code{#f} an
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
@node lambda* Reference
@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{(ice-9 optargs)} also provides some more @code{define*} sugar,
which is not so useful with modern Guile coding, but still supported:
@code{define*-public} is the @code{lambda*} version of
@code{define-public}; @code{defmacro*} and @code{defmacro*-public} exist
for defining macros with the improved argument list handling
possibilities. The @code{-public} versions not only define the
@code{define-public}; @code{defmacro*} and @code{defmacro*-public}
exist for defining macros with the improved argument list handling
possibilities. The @code{-public} versions not only define the
procedures/macros, but also export them from the current module.
@deffn {library syntax} define* formals body
@deffnx {library syntax} define*-public formals body
@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*}.
@deffn {library syntax} define*-public formals body
Like a mix of @code{define*} and @code{define-public}.
@end deffn
@deffn {library syntax} defmacro* name formals body
@ -562,29 +517,105 @@ semantics. Here is an example of a macro with an optional argument:
@lisp
(defmacro* transmorgify (a #:optional b)
(a 1))
(a 1))
@end lisp
@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
@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
created and information about how to apply them to actual arguments. In
addition to that, properties and meta-information can be stored with
procedures. The procedures in this section can be used to test whether
a given procedure satisfies a condition; and to access and set a
procedure's property.
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.
The first group of procedures in this meta-interface 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?
@deffn {Scheme Procedure} procedure? obj
@ -594,7 +625,11 @@ Return @code{#t} if @var{obj} is a procedure.
@deffn {Scheme Procedure} closure? 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
@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.
@end deffn
@c FIXME::martin: Is that true?
@cindex procedure properties
Procedure properties are general properties to be attached to
procedures. These can be the name of a procedure or other relevant
Procedure properties are general properties associated with
procedures. These can be the name of a procedure or other relevant
information, such as debug hints.
@deffn {Scheme Procedure} procedure-name proc
@ -615,32 +649,34 @@ Return the name of the procedure @var{proc}
@deffn {Scheme Procedure} 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
@deffn {Scheme Procedure} 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
@deffn {Scheme Procedure} 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
@deffn {Scheme Procedure} procedure-property obj key
@deffnx {C Function} scm_procedure_property (obj, key)
Return the property of @var{obj} with name @var{key}.
@deffn {Scheme Procedure} procedure-property proc key
@deffnx {C Function} scm_procedure_property (proc, key)
Return the property of @var{proc} with name @var{key}.
@end deffn
@deffn {Scheme Procedure} set-procedure-properties! 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
@deffn {Scheme Procedure} set-procedure-property! obj key value
@deffnx {C Function} scm_set_procedure_property_x (obj, key, value)
In @var{obj}'s property list, set the property named @var{key} to
@deffn {Scheme Procedure} set-procedure-property! proc key value
@deffnx {C Function} scm_set_procedure_property_x (proc, key, value)
In @var{proc}'s property list, set the property named @var{key} to
@var{value}.
@end deffn
@ -899,6 +935,9 @@ given by the <transformer-spec>.
@node Internal Macros
@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
flavors are called @dfn{acro} (or @dfn{syntax}), @dfn{macro} and
@dfn{mmacro}.

View file

@ -1,6 +1,6 @@
@c -*-texinfo-*-
@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 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
@subsection Blocking in Guile Mode
A thread must not block outside of a libguile function while it is in
guile mode. The following functions can be used to temporily leave
guile mode or to perform some common blocking operations in a supported
way.
Up to Guile version 1.8, a thread blocked in guile mode would prevent
the garbage collector from running. Thus threads had to explicitly
leave guile mode with @code{scm_without_guile ()} before making a
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)
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}.
@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
@subsection Parallel forms
@cindex parallel forms

View file

@ -1,6 +1,6 @@
@c -*-texinfo-*-
@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 See the file guile.texi for copying conditions.
@ -8,6 +8,8 @@
@node Smobs
@section Smobs
@cindex smob
This chapter contains reference information related to defining and
working with smobs. See @ref{Defining New Types (Smobs)} for a
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}.
@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))
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}.
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
for every @code{SCM} value that is directly referenced by the smob
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}.
@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))
This function sets the smob printing procedure for the smob type

View file

@ -236,12 +236,49 @@ which puts the user in the @code{(foo)} module. That is purpose of the
when compiling the subsequent expression.
For Scheme, an environment may be one of two things:
@itemize
@item @code{#f}, in which case compilation is performed in the context
of the current module; or
@item a module, which specifies the context of the compilation.
@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
@subsection Tree-IL

View file

@ -17,7 +17,7 @@ Guile
@goops{} is the object oriented extension to @guile{}. Its
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
adapted for the Scheme language. While GOOPS is not compatible with any
of these systems, GOOPS contains a compatibility module which allows for

View file

@ -61,6 +61,8 @@ command-line arguments in the same manner as the stock Guile
interpreter. To make that straightforward, Guile provides the
@code{scm_boot_guile} and @code{scm_shell} function.
For more about these functions, see @ref{Initialization}.
@node A Sample Guile Main Program
@subsection A Sample Guile Main Program

View file

@ -1038,7 +1038,7 @@ Reference Manual}).
@sp 1
@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.
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]
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
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}
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}
Don't follow symbolic links, instead report them to @var{proc} as

View file

@ -1,6 +1,6 @@
@c -*-texinfo-*-
@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 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
@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
(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
@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
(dotted decimal notation) string. E.g.,
@ -2288,8 +2292,8 @@ Convert a network address from an integer to a printable string.
@lisp
(inet-ntop AF_INET 2130706433) @result{} "127.0.0.1"
(inet-ntop AF_INET6 (- (expt 2 128) 1)) @result{}
ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff
(inet-ntop AF_INET6 (- (expt 2 128) 1))
@result{} "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"
@end lisp
@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.
@example
(connect sock AF_INET INADDR_LOCALHOST 23)
(connect sock (make-socket-address AF_INET INADDR_LOCALHOST 23))
(connect sock AF_INET INADDR_LOOPBACK 23)
(connect sock (make-socket-address AF_INET INADDR_LOOPBACK 23))
@end example
@end deffn
@ -3107,7 +3111,7 @@ returns the contents of the root index URL.
@example
(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)
(do ((line (read-line s) (read-line s)))
@ -3128,7 +3132,7 @@ client.
(let ((s (socket PF_INET SOCK_STREAM 0)))
(setsockopt s SOL_SOCKET SO_REUSEADDR 1)
;; @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)
(listen s 5)

View file

@ -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
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
The rest of the file should be a Scheme program.

View file

@ -1,6 +1,6 @@
@c -*-texinfo-*-
@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 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-19:: Time/Date library.
* SRFI-26:: Specializing parameters
* SRFI-30:: Nested multi-line block comments
* SRFI-31:: A special form `rec' for recursive evaluation
* SRFI-34:: Exception handling.
* SRFI-35:: Conditions.
@ -134,6 +135,7 @@ The Guile core has the following features,
@example
guile
guile-2 ;; starting from Guile 2.x
r5rs
srfi-0
srfi-4
@ -161,6 +163,23 @@ how to load it with the Guile mechanism.
(use-modules (srfi srfi-8))))
@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
@code{*features*} mechanism (@pxref{Feature Tracking}), feature
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 arity, variable
@c FIXME::martin: Review me!
@findex case-lambda
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.
SRFI-16 defines a variable-arity @code{lambda} form,
@code{case-lambda}. This form is available in the default Guile
environment. @xref{Case-lambda}, for more information.
@node SRFI-17
@subsection SRFI-17 - Generalized set!
@ -2712,6 +2674,13 @@ or similar is typical.
@end example
@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
@subsection SRFI-31 - A special form `rec' for recursive evaluation
@cindex SRFI-31

View file

@ -12,7 +12,7 @@ be required to make them available.
* Ports and descriptors:: Ports, file descriptors and how they
interact.
* 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.
* Processes:: Information and control of Unix processes.
* Terminals:: Terminals and pseudo-terminals.

225
emacs/gds-faq.txt Executable file
View 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:

View file

@ -206,23 +206,28 @@ Emacs to display an error or trap so that the user can debug it."
"-q"
"--debug"
"-c"
code))
(client nil))
code)))
;; Note that this process can be killed automatically on Emacs
;; exit.
(process-kill-without-query proc)
;; Set up a process filter to catch the new client's number.
(set-process-filter proc
(lambda (proc string)
(setq client (string-to-number string))
(if (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.
(while (not client)
(while (not (with-current-buffer (process-buffer proc) gds-client))
(accept-process-output proc))
;; Return the new process's client number.
client))
(with-current-buffer (process-buffer proc) gds-client)))
;;;; Evaluating code.
@ -419,11 +424,13 @@ through the code."
(map (make-sparse-keymap)))
(define-key map [mouse-1] '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)
(list 'keymap map
'mouse-face 'highlight))
(insert "\n")))
(insert "\n")
(add-text-properties (1- (point)) (point)
(list 'keymap map))))
(goto-char (point-min))
(gds-associate-buffer client))
(pop-to-buffer buf)

View file

@ -43,25 +43,24 @@
:group 'gds
:type '(choice (const :tag "nil" nil) directory))
(defun gds-start-server (procname port-or-path protocol-handler &optional bufname)
"Start a GDS server process called PROCNAME, listening on TCP port
or Unix domain socket PORT-OR-PATH. PROTOCOL-HANDLER should be a
function that accepts and processes one protocol form. Optional arg
BUFNAME specifies the name of the buffer that is used for process
output; if not specified the buffer name is the same as the process
name."
(with-current-buffer (get-buffer-create (or bufname procname))
(defun gds-start-server (procname unix-socket-name tcp-port protocol-handler)
"Start a GDS server process called PROCNAME, listening on Unix
domain socket UNIX-SOCKET-NAME and TCP port number TCP-PORT.
PROTOCOL-HANDLER should be a function that accepts and processes
one protocol form."
(with-current-buffer (get-buffer-create procname)
(erase-buffer)
(let* ((code (format "(begin
%s
(use-modules (ice-9 gds-server))
(run-server %S))"
(run-server %S %S))"
(if gds-scheme-directory
(concat "(set! %load-path (cons "
(format "%S" gds-scheme-directory)
" %load-path))")
"")
port-or-path))
unix-socket-name
tcp-port))
(process-connection-type nil) ; use a pipe
(proc (start-process procname
(current-buffer)

166
emacs/gds-test.el Normal file
View 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
View 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
View file

@ -0,0 +1 @@

223
emacs/gds-tutorial.txt Executable file
View 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:

View file

@ -36,10 +36,11 @@
;; The subprocess object for the debug server.
(defvar gds-debug-server nil)
(defvar gds-socket-type-alist '((tcp . 8333)
(unix . "/tmp/.gds_socket"))
"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-unix-socket-name (format "/tmp/.gds-socket-%d" (emacs-pid))
"Name of the Unix domain socket that GDS will listen on.")
(defvar gds-tcp-port 8333
"The TCP port number that GDS will listen on.")
(defun gds-run-debug-server ()
"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))
(setq gds-debug-server
(gds-start-server "gds-debug"
(cdr (assq gds-server-socket-type
gds-socket-type-alist))
gds-unix-socket-name
gds-tcp-port
'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 ()
"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
(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)
(run-hook-with-args 'gds-protocol-hook form)
(or (eq client '*)
(let ((proc (car form)))
(cond ((eq proc 'name)
@ -610,7 +621,7 @@ you would add an element to this alist to transform
:group 'gds)
(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
:type '(choice (const :tag "TCP" tcp)
(const :tag "Unix" unix)))

View file

@ -38,8 +38,8 @@ EXTRA_DIST = README ChangeLog-2008 check.test \
\
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_LIBS = `PATH=$(bindir):$$PATH PKG_CONFIG_PATH=$(libdir)/pkgconfig $(bindir)/guile-config link`
AM_CFLAGS = `PATH=$(bindir)$(PATH_SEPARATOR)$$PATH PKG_CONFIG_PATH=$(libdir)/pkgconfig $(bindir)/guile-config compile`
AM_LIBS = `PATH=$(bindir)$(PATH_SEPARATOR)$$PATH PKG_CONFIG_PATH=$(libdir)/pkgconfig $(bindir)/guile-config link`
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
LD_LIBRARY_PATH="$(libdir):$$LD_LIBRARY_PATH" \
LTDL_LIBRARY_PATH="$(builddir):$$LTDL_LIBRARY_PATH" \
GUILE_LOAD_PATH="$(abs_top_srcdir):$$GUILE_LOAD_PATH" \
PATH="$(bindir):$$PATH" \
LD_LIBRARY_PATH="$(libdir)$(PATH_SEPARATOR)$$LD_LIBRARY_PATH" \
LTDL_LIBRARY_PATH="$(builddir)$(PATH_SEPARATOR)$$LTDL_LIBRARY_PATH" \
GUILE_LOAD_PATH="$(abs_top_srcdir)$(PATH_SEPARATOR)$$GUILE_LOAD_PATH" \
PATH="$(bindir)$(PATH_SEPARATOR)$$PATH" \
GUILE_AUTO_COMPILE=0 \
srcdir="$(srcdir)" \
$(srcdir)/check.test

View file

@ -12,7 +12,7 @@ AC_DEFUN([GUILE_COMPAT],
ac_cv_have_scm_t_bits=no)])
AC_MSG_RESULT($ac_cv_have_scm_t_bits)
if test $ac_cv_have_scm_t_bits = yes; then
AC_DEFINE(HAVE_SCM_T_BITS)
AC_DEFINE([HAVE_SCM_T_BITS])
fi
LIBS="$guile_compat_save_LIBS"
CFLAGS="$guile_compat_save_CFLAGS"])

File diff suppressed because one or more lines are too long

View file

@ -4,7 +4,7 @@ exec ${GUILE-guile} -q -l "$0" \
-c '(apply main (cdr (command-line)))' \
--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
;;; 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 regex)
(ice-9 format)
(ice-9 pretty-print)
(srfi srfi-1)
(srfi srfi-37))
@ -103,23 +104,64 @@ exec ${GUILE-guile} -q -l "$0" \
result)))
(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?)
(let ((name (string-pad-right name 23))
(time (assoc-ref result 'execution-time))
(heap (assoc-ref result 'heap-size))
(ref-heap (assoc-ref reference 'heap-size))
(ref-time (assoc-ref reference 'execution-time)))
(format #t "~a ~1,2f (~,2fx) ~6,3f (~,2fx)~A~%"
(let ((name (string-pad-right name 23))
(time (assoc-ref result 'execution-time))
(heap (assoc-ref result 'heap-size)))
(format #t "~a ~6,2f (~,2fx) ~7,3f (~,2fx)~A~%"
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)
(if (and (not ref?)
(<= heap ref-heap) (<= time ref-time))
" !"
(if (not ref?)
(string-append " "
(score-string time heap))
""))))
(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)
(for-each (lambda (bdwgc)
(let ((name (format #f "BDW-GC, FSD=~a~a"
@ -134,6 +176,12 @@ exec ${GUILE-guile} -q -l "$0" \
(print-line name bdwgc #f)))
bdwgc))
(define (print-raw-result benchmark reference bdwgc)
(pretty-print `(,benchmark
(reference . ,reference)
(bdw-gc . ,bdwgc))))
;;;
;;; Option processing.
@ -170,14 +218,22 @@ exec ${GUILE-guile} -q -l "$0" \
(lambda (opt name arg result)
(alist-cons 'log-port (open-output-file arg)
(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
`((reference-environment . "GUILE=guile")
(benchmark-directory . "./gc-benchmarks")
(log-port . ,(current-output-port))
(profile-options . "")
(input . ())))
(input . ())
(printer . ,pretty-print-result)))
(define (show-help)
(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'.
-l, --log-file=FILE
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
Use DIR as the GC benchmark directory where `gc-profile.scm'
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)
(string-append "GUILE=" bench-dir
"/../meta/guile")))
(prof-opts (assoc-ref args 'profile-options)))
(for-each (lambda (benchmark)
(let ((ref (parse-result (run-reference-guile ref-env
bench-dir
prof-opts
benchmark)))
(bdwgc (map (lambda (fsd incremental?
generational? parallel?)
(let ((opts
(list
(cons 'free-space-divisor fsd)
(cons 'incremental? incremental?)
(cons 'generational? generational?)
(cons 'parallel? parallel?))))
(append opts
(parse-result
(run-bdwgc-guile bdwgc-env
bench-dir
prof-opts
opts
benchmark)))))
'( 3 6 9 3 3)
'(#f #f #f #t #f) ;; incremental
'(#f #f #f #f #t) ;; generational
'(#f #f #f #f #f)))) ;; parallel
;;(format #t "ref=~A~%" ref)
;;(format #t "bdw-gc=~A~%" bdwgc)
(prof-opts (assoc-ref args 'profile-options))
(print (assoc-ref args 'printer)))
(define (run benchmark)
(let ((ref (parse-result (run-reference-guile ref-env
bench-dir
prof-opts
benchmark)))
(bdwgc (map (lambda (fsd incremental?
generational? parallel?)
(let ((opts
(list
(cons 'free-space-divisor fsd)
(cons 'incremental? incremental?)
(cons 'generational? generational?)
(cons 'parallel? parallel?))))
(append opts
(parse-result
(run-bdwgc-guile bdwgc-env
bench-dir
prof-opts
opts
benchmark)))))
'( 3 6 9 3 3)
'(#f #f #f #t #f) ;; incremental
'(#f #f #f #f #t) ;; generational
'(#f #f #f #f #f)))) ;; parallel
`(,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
(lambda ()
(pretty-print-result benchmark ref bdwgc)
(print benchmark ref bdwgc)
(newline)
(force-output)))))
benchmark-files))))
(if (assoc-ref args 'load-results?)
(append-map load-results benchmark-files)
(map run benchmark-files))))))

View file

@ -1,5 +1,8 @@
# -*- GDB-Script -*-
handle SIGPWR noprint nostop
handle SIGXCPU noprint nostop
define newline
call (void)scm_newline (scm_current_error_port ())
end
@ -195,3 +198,7 @@ end
define inst
p scm_instruction_table[$arg0]
end
define gbt
call scm_display_backtrace (scm_make_stack(0x404,0x304), scm_current_error_port (), 0x704, 0x704, 0x704)
end

View file

@ -1,6 +1,6 @@
;;;; 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
;;;; it under the terms of the GNU General Public License as published by
@ -24,11 +24,15 @@
(define-module (ice-9 readline)
:use-module (ice-9 session)
:use-module (ice-9 regex)
:use-module (ice-9 buffered-input)
:no-backtrace
:export (filename-completion-function))
#:use-module (ice-9 session)
#:use-module (ice-9 regex)
#:use-module (ice-9 buffered-input)
#:no-backtrace
#: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))))
(set-current-input-port (readline-port))
(set! repl-reader
(lambda (repl-prompt)
(lambda (repl-prompt . reader)
(let ((outer-new-input-prompt new-input-prompt)
(outer-continuation-prompt continuation-prompt)
(outer-read-hook read-hook))
@ -213,7 +217,9 @@
(set-buffered-input-continuation?! (readline-port) #f)
(set-readline-prompt! repl-prompt "... ")
(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 ()
(set-readline-prompt! outer-new-input-prompt outer-continuation-prompt)
(set-readline-read-hook! outer-read-hook))))))

View file

@ -128,6 +128,7 @@ rl_free_line_state ()
static int promptp;
static SCM input_port;
static SCM output_port;
static SCM before_read;
static int
@ -138,7 +139,7 @@ current_input_getc (FILE *in SCM_UNUSED)
scm_apply (before_read, SCM_EOL, SCM_EOL);
promptp = 0;
}
return scm_getc (input_port);
return scm_get_byte_or_eof (input_port);
}
static int in_readline = 0;
@ -255,7 +256,12 @@ internal_readline (SCM text)
promptp = 1;
s = readline (prompt);
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
ret = SCM_EOF_VAL;
@ -311,6 +317,7 @@ scm_readline_init_ports (SCM inp, SCM outp)
}
input_port = inp;
output_port = outp;
#ifndef __MINGW32__
rl_instream = stream_from_fport (inp, "r", 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_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_readline_opts);
#if HAVE_RL_GET_KEYMAP

View file

@ -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

View file

@ -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.

View file

@ -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.

View file

@ -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.

View file

@ -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"))

View file

@ -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.

View file

@ -1,4 +0,0 @@
(define-module (lang elisp expand)
#:export (expand))
(define (expand x) x)

View file

@ -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))

View file

@ -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)))

View file

@ -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))

View file

@ -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))

View file

@ -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))

View file

@ -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))))

View 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))))

View file

@ -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)))

View file

@ -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)))

View file

@ -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)))))

View file

@ -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)

View file

@ -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))

View file

@ -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