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:
commit
e42573315b
597 changed files with 39198 additions and 66642 deletions
8
.gitignore
vendored
8
.gitignore
vendored
|
@ -72,6 +72,8 @@ gdb-pre-inst-guile
|
|||
cscope.out
|
||||
cscope.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
1
.gnuploadrc
Normal file
|
@ -0,0 +1 @@
|
|||
--user ludo@gnu.org
|
4
.x-sc_GPL_version
Normal file
4
.x-sc_GPL_version
Normal file
|
@ -0,0 +1,4 @@
|
|||
^lib/
|
||||
^gc-benchmarks/
|
||||
^libguile/libgettext.h
|
||||
^libguile/mkstemp.c
|
1
.x-sc_avoid_if_before_free
Normal file
1
.x-sc_avoid_if_before_free
Normal file
|
@ -0,0 +1 @@
|
|||
^lib/
|
1
.x-sc_cast_of_alloca_return_value
Normal file
1
.x-sc_cast_of_alloca_return_value
Normal file
|
@ -0,0 +1 @@
|
|||
^lib/
|
1
.x-sc_cast_of_argument_to_free
Normal file
1
.x-sc_cast_of_argument_to_free
Normal file
|
@ -0,0 +1 @@
|
|||
^libguile/stime.c
|
1
.x-sc_error_message_period
Normal file
1
.x-sc_error_message_period
Normal file
|
@ -0,0 +1 @@
|
|||
^gc-benchmarks/
|
6
.x-sc_error_message_uppercase
Normal file
6
.x-sc_error_message_uppercase
Normal file
|
@ -0,0 +1,6 @@
|
|||
^libguile/
|
||||
^guile-readline/
|
||||
^gc-benchmarks/
|
||||
^emacs/
|
||||
^NEWS
|
||||
^doc/
|
1
.x-sc_error_message_warn_fatal
Normal file
1
.x-sc_error_message_warn_fatal
Normal file
|
@ -0,0 +1 @@
|
|||
^module/ice-9/match.scm
|
1
.x-sc_m4_quote_check
Normal file
1
.x-sc_m4_quote_check
Normal file
|
@ -0,0 +1 @@
|
|||
m4/version-etc.m4
|
3
.x-sc_makefile_check
Normal file
3
.x-sc_makefile_check
Normal file
|
@ -0,0 +1,3 @@
|
|||
lib(guile)?/
|
||||
guile-readline/
|
||||
srfi/
|
29
AUTHORS
29
AUTHORS
|
@ -206,8 +206,34 @@ In the subdirectory doc, changes to:
|
|||
Many changes throughout.
|
||||
|
||||
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
127
GNUmakefile
Normal file
|
@ -0,0 +1,127 @@
|
|||
# Having a separate GNUmakefile lets me `include' the dynamically
|
||||
# generated rules created via cfg.mk (package-local configuration)
|
||||
# as well as maint.mk (generic maintainer rules).
|
||||
# This makefile is used only if you run GNU Make.
|
||||
# It is necessary if you want to build targets usually of interest
|
||||
# only to the maintainer.
|
||||
|
||||
# Copyright (C) 2001, 2003, 2006-2009 Free Software Foundation, Inc.
|
||||
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
# Systems where /bin/sh is not the default shell need this. The $(shell)
|
||||
# command below won't work with e.g. stock DOS/Windows shells.
|
||||
ifeq ($(wildcard /bin/s[h]),/bin/sh)
|
||||
SHELL = /bin/sh
|
||||
else
|
||||
# will be used only with the next shell-test line, then overwritten
|
||||
# by a configured-in value
|
||||
SHELL = sh
|
||||
endif
|
||||
|
||||
# If the user runs GNU make but has not yet run ./configure,
|
||||
# give them a diagnostic.
|
||||
_have-Makefile := $(shell test -f Makefile && echo yes)
|
||||
ifeq ($(_have-Makefile),yes)
|
||||
|
||||
# Make tar archive easier to reproduce.
|
||||
export TAR_OPTIONS = --owner=0 --group=0 --numeric-owner
|
||||
|
||||
# Allow the user to add to this in the Makefile.
|
||||
ALL_RECURSIVE_TARGETS =
|
||||
|
||||
include Makefile
|
||||
|
||||
# Some projects override e.g., _autoreconf here.
|
||||
-include $(srcdir)/cfg.mk
|
||||
include $(srcdir)/maint.mk
|
||||
|
||||
# Allow cfg.mk to override these.
|
||||
_build-aux ?= build-aux
|
||||
_autoreconf ?= autoreconf
|
||||
|
||||
# Ensure that $(VERSION) is up to date for dist-related targets, but not
|
||||
# for others: rerunning autoreconf and recompiling everything isn't cheap.
|
||||
_have-git-version-gen := \
|
||||
$(shell test -f $(srcdir)/$(_build-aux)/git-version-gen && echo yes)
|
||||
ifeq ($(_have-git-version-gen)0,yes$(MAKELEVEL))
|
||||
_is-dist-target ?= $(filter-out %clean, \
|
||||
$(filter maintainer-% dist% alpha beta major,$(MAKECMDGOALS)))
|
||||
_is-install-target ?= $(filter-out %check, $(filter install%,$(MAKECMDGOALS)))
|
||||
ifneq (,$(_is-dist-target)$(_is-install-target))
|
||||
_curr-ver := $(shell cd $(srcdir) \
|
||||
&& $(_build-aux)/git-version-gen .tarball-version)
|
||||
ifneq ($(_curr-ver),$(VERSION))
|
||||
ifeq ($(_curr-ver),UNKNOWN)
|
||||
$(info WARNING: unable to verify if $(VERSION) is the correct version)
|
||||
else
|
||||
ifneq (,$(_is-install-target))
|
||||
# GNU Coding Standards state that 'make install' should not cause
|
||||
# recompilation after 'make all'. But as long as changing the version
|
||||
# string alters config.h, the cost of having 'make all' always have an
|
||||
# up-to-date version is prohibitive. So, as a compromise, we merely
|
||||
# warn when installing a version string that is out of date; the user
|
||||
# should run 'autoreconf' (or something like 'make distcheck') to
|
||||
# fix the version, 'make all' to propagate it, then 'make install'.
|
||||
$(info WARNING: version string $(VERSION) is out of date;)
|
||||
$(info run '$(MAKE) _version' to fix it)
|
||||
else
|
||||
$(info INFO: running autoreconf for new version string: $(_curr-ver))
|
||||
_dummy := $(shell $(MAKE) $(AM_MAKEFLAGS) _version)
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
.PHONY: _version
|
||||
_version:
|
||||
cd $(srcdir) && rm -rf autom4te.cache .version && $(_autoreconf)
|
||||
|
||||
else
|
||||
|
||||
.DEFAULT_GOAL := abort-due-to-no-makefile
|
||||
srcdir = .
|
||||
|
||||
# The package can override .DEFAULT_GOAL to run actions like autoreconf.
|
||||
-include ./cfg.mk
|
||||
include ./maint.mk
|
||||
|
||||
ifeq ($(.DEFAULT_GOAL),abort-due-to-no-makefile)
|
||||
$(MAKECMDGOALS): abort-due-to-no-makefile
|
||||
endif
|
||||
|
||||
abort-due-to-no-makefile:
|
||||
@echo There seems to be no Makefile in this directory. 1>&2
|
||||
@echo "You must run ./configure before running \`make'." 1>&2
|
||||
@exit 1
|
||||
|
||||
endif
|
||||
|
||||
# Tell version 3.79 and up of GNU make to not build goals in this
|
||||
# directory in parallel, in case someone tries to build multiple
|
||||
# targets, and one of them can cause a recursive target to be invoked.
|
||||
|
||||
# Only set this if Automake doesn't provide it.
|
||||
AM_RECURSIVE_TARGETS ?= $(RECURSIVE_TARGETS:-recursive=) \
|
||||
$(RECURSIVE_CLEAN_TARGETS:-recursive=) \
|
||||
dist distcheck tags ctags
|
||||
|
||||
ALL_RECURSIVE_TARGETS += $(AM_RECURSIVE_TARGETS)
|
||||
|
||||
ifneq ($(word 2, $(MAKECMDGOALS)), )
|
||||
ifneq ($(filter $(ALL_RECURSIVE_TARGETS), $(MAKECMDGOALS)), )
|
||||
.NOTPARALLEL:
|
||||
endif
|
||||
endif
|
|
@ -2,15 +2,11 @@
|
|||
|
||||
GUILE_MAJOR_VERSION=1
|
||||
GUILE_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}"
|
||||
|
|
|
@ -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
368
NEWS
|
@ -8,31 +8,157 @@ Please send Guile bug reports to bug-guile@gnu.org.
|
|||
(During the 1.9 series, we will keep an incremental NEWS for the latest
|
||||
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
13
README
|
@ -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
6
THANKS
|
@ -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
|
||||
|
|
64
acinclude.m4
64
acinclude.m4
|
@ -57,7 +57,7 @@ AC_DEFUN([GUILE_HEADER_LIBC_WITH_UNISTD],
|
|||
]
|
||||
)
|
||||
if test "$guile_cv_header_libc_with_unistd" = yes; then
|
||||
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
|
||||
|
|
|
@ -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 "$@" "$<"
|
||||
|
|
|
@ -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 ""
|
||||
|
||||
######################################################################
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 \
|
||||
|
|
|
@ -1,2 +1,6 @@
|
|||
|
||||
(define-module (benchmarks 0-reference)
|
||||
:use-module (benchmark-suite lib))
|
||||
|
||||
(benchmark "reference benchmark for iteration counts" 330000
|
||||
#t)
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
|
||||
(define-module (benchmarks if)
|
||||
:use-module (benchmark-suite lib))
|
||||
|
||||
(with-benchmark-prefix "if-<expr>-then-else"
|
||||
|
||||
(benchmark "executing then" 330000
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
|
||||
(define-module (benchmarks logand)
|
||||
:use-module (benchmark-suite lib))
|
||||
|
||||
(define bignum (1- (expt 2 128)))
|
||||
|
||||
(let* ((i 0))
|
||||
|
|
|
@ -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))))
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
93
benchmark-suite/results/neil-arudy
Normal file
93
benchmark-suite/results/neil-arudy
Normal file
|
@ -0,0 +1,93 @@
|
|||
Benchmarking /home/neil/SW/Guile/git/meta/guile ...
|
||||
with GUILE_LOAD_PATH=/home/neil/SW/Guile/git/benchmark-suite
|
||||
;; running guile version 1.9.3
|
||||
;; calibrating the benchmarking framework...
|
||||
;; framework time per iteration: 5.7220458984375e-7
|
||||
("0-reference.bm: reference benchmark for iteration counts" 330000 user 0.2 benchmark 0.0111724853515625 bench/interp 0.0111724853515625 gc 0.0)
|
||||
("bytevectors.bm: ref/set!: bytevector-u8-ref" 1000000 user 0.73 benchmark 0.15779541015625 bench/interp 0.15779541015625 gc 0.0)
|
||||
("bytevectors.bm: ref/set!: bytevector-u16-ref (foreign)" 1000000 user 0.82 benchmark 0.24779541015625 bench/interp 0.24779541015625 gc 0.0)
|
||||
("bytevectors.bm: ref/set!: bytevector-u16-ref (native)" 1000000 user 0.78 benchmark 0.20779541015625 bench/interp 0.20779541015625 gc 0.0)
|
||||
("bytevectors.bm: ref/set!: bytevector-u16-native-ref" 1000000 user 0.72 benchmark 0.14779541015625 bench/interp 0.14779541015625 gc 0.0)
|
||||
("bytevectors.bm: ref/set!: bytevector-u32-ref (foreign)" 1000000 user 1.61 benchmark 1.03779541015625 bench/interp 1.03779541015625 gc 0.0)
|
||||
("bytevectors.bm: ref/set!: bytevector-u32-ref (native)" 1000000 user 0.8 benchmark 0.22779541015625 bench/interp 0.22779541015625 gc 0.0)
|
||||
("bytevectors.bm: ref/set!: bytevector-u32-native-ref" 1000000 user 0.74 benchmark 0.16779541015625 bench/interp 0.16779541015625 gc 0.0)
|
||||
("bytevectors.bm: ref/set!: bytevector-u64-ref (foreign)" 1000000 user 1.86 benchmark 1.28779541015625 bench/interp 1.28779541015625 gc 0.0)
|
||||
("bytevectors.bm: ref/set!: bytevector-u64-ref (native)" 1000000 user 0.81 benchmark 0.23779541015625 bench/interp 0.23779541015625 gc 0.0)
|
||||
("bytevectors.bm: ref/set!: bytevector-u64-native-ref" 1000000 user 0.73 benchmark 0.15779541015625 bench/interp 0.15779541015625 gc 0.0)
|
||||
("bytevectors.bm: lists: bytevector->u8-list" 2000 user 9.87 benchmark 9.86885559082031 bench/interp 9.86885559082031 gc 0.0)
|
||||
("bytevectors.bm: lists: bytevector->uint-list 16-bit" 2000 user 4.48 benchmark 4.47885559082031 bench/interp 4.47885559082031 gc 0.0)
|
||||
("bytevectors.bm: lists: bytevector->uint-list 64-bit" 2000 user 3.75 benchmark 3.74885559082031 bench/interp 3.74885559082031 gc 0.0)
|
||||
("bytevectors.bm: SRFI-4: u8vector-ref" 1000000 user 1.88 benchmark 1.30779541015625 bench/interp 1.30779541015625 gc 0.0)
|
||||
("bytevectors.bm: SRFI-4: u16vector-ref" 1000000 user 1.9 benchmark 1.32779541015625 bench/interp 1.32779541015625 gc 0.0)
|
||||
("bytevectors.bm: SRFI-4: u32vector-ref" 1000000 user 1.88 benchmark 1.30779541015625 bench/interp 1.30779541015625 gc 0.0)
|
||||
("bytevectors.bm: SRFI-4: u64vector-ref" 1000000 user 1.98 benchmark 1.40779541015625 bench/interp 1.40779541015625 gc 0.0)
|
||||
("chars.bm: chars: char" 1000000 user 0.63 benchmark 0.05779541015625 bench/interp 0.05779541015625 gc 0.0)
|
||||
("chars.bm: chars: octal" 1000000 user 0.64 benchmark 0.06779541015625 bench/interp 0.06779541015625 gc 0.0)
|
||||
("chars.bm: chars: char? eq" 1000000 user 1.19 benchmark 0.61779541015625 bench/interp 0.61779541015625 gc 0.0)
|
||||
("chars.bm: chars: char=?" 1000000 user 1.45 benchmark 0.87779541015625 bench/interp 0.87779541015625 gc 0.0)
|
||||
("chars.bm: chars: char<?" 1000000 user 1.45 benchmark 0.87779541015625 bench/interp 0.87779541015625 gc 0.0)
|
||||
("chars.bm: chars: char-ci=?" 1000000 user 1.45 benchmark 0.87779541015625 bench/interp 0.87779541015625 gc 0.0)
|
||||
("chars.bm: chars: char-ci<? " 1000000 user 1.45 benchmark 0.87779541015625 bench/interp 0.87779541015625 gc 0.0)
|
||||
("chars.bm: chars: char->integer" 1000000 user 1.2 benchmark 0.62779541015625 bench/interp 0.62779541015625 gc 0.0)
|
||||
("chars.bm: chars: char-alphabetic?" 1000000 user 1.36 benchmark 0.78779541015625 bench/interp 0.78779541015625 gc 0.0)
|
||||
("chars.bm: chars: char-numeric?" 1000000 user 1.36 benchmark 0.78779541015625 bench/interp 0.78779541015625 gc 0.0)
|
||||
("continuations.bm: call/cc" 300 user 0.03 benchmark 0.0298283386230469 bench/interp 0.0298283386230469 gc 0.0)
|
||||
("if.bm: if-<expr>-then-else: executing then" 330000 user 0.23 benchmark 0.0411724853515625 bench/interp 0.0411724853515625 gc 0.0)
|
||||
("if.bm: if-<expr>-then-else: executing else" 330000 user 0.23 benchmark 0.0411724853515625 bench/interp 0.0411724853515625 gc 0.0)
|
||||
("if.bm: if-<expr>-then: executing then" 330000 user 0.23 benchmark 0.0411724853515625 bench/interp 0.0411724853515625 gc 0.0)
|
||||
("if.bm: if-<expr>-then: executing else" 330000 user 0.24 benchmark 0.0511724853515625 bench/interp 0.0511724853515625 gc 0.0)
|
||||
("if.bm: if-<iloc>-then-else: executing then" 330000 user 0.25 benchmark 0.0611724853515625 bench/interp 0.0611724853515625 gc 0.0)
|
||||
("if.bm: if-<iloc>-then-else: executing else" 330000 user 0.24 benchmark 0.0511724853515625 bench/interp 0.0511724853515625 gc 0.0)
|
||||
("if.bm: if-<iloc>-then: executing then" 330000 user 0.24 benchmark 0.0511724853515625 bench/interp 0.0511724853515625 gc 0.0)
|
||||
("if.bm: if-<iloc>-then: executing else" 330000 user 0.24 benchmark 0.0511724853515625 bench/interp 0.0511724853515625 gc 0.0)
|
||||
("if.bm: if-<bool>-then-else: executing then" 330000 user 0.23 benchmark 0.0411724853515625 bench/interp 0.0411724853515625 gc 0.0)
|
||||
("if.bm: if-<bool>-then-else: executing else" 330000 user 0.23 benchmark 0.0411724853515625 bench/interp 0.0411724853515625 gc 0.0)
|
||||
("if.bm: if-<bool>-then: executing then" 330000 user 0.24 benchmark 0.0511724853515625 bench/interp 0.0511724853515625 gc 0.0)
|
||||
("if.bm: if-<bool>-then: executing else" 330000 user 0.23 benchmark 0.0411724853515625 bench/interp 0.0411724853515625 gc 0.0)
|
||||
("logand.bm: bignum" 130000 user 0.48 benchmark 0.405613403320312 bench/interp 0.405613403320312 gc 0.0)
|
||||
("read.bm: read: _IONBF" 5 user 12.71 benchmark 12.7099971389771 bench/interp 12.7099971389771 gc 0.0)
|
||||
("read.bm: read: _IOLBF" 10 user 20.32 benchmark 20.3199942779541 bench/interp 20.3199942779541 gc 0.0)
|
||||
("read.bm: read: _IOFBF 4096" 10 user 20.34 benchmark 20.3399942779541 bench/interp 20.3399942779541 gc 0.0)
|
||||
("read.bm: read: _IOFBF 8192" 10 user 20.36 benchmark 20.3599942779541 bench/interp 20.3599942779541 gc 0.0)
|
||||
("read.bm: read: _IOFBF 16384" 10 user 20.34 benchmark 20.3399942779541 bench/interp 20.3399942779541 gc 0.0)
|
||||
("srfi-13.bm: strings: predicates: string?" 1190000 user 2.98 benchmark 2.29907653808594 bench/interp 2.29907653808594 gc 0.0)
|
||||
("srfi-13.bm: strings: predicates: null?" 969000 user 2.56 benchmark 2.00553375244141 bench/interp 2.00553375244141 gc 0.0)
|
||||
("srfi-13.bm: strings: predicates: any" 94000 user 1.89 benchmark 1.83621276855469 bench/interp 1.83621276855469 gc 0.0)
|
||||
("srfi-13.bm: strings: predicates: every" 94000 user 1.53 benchmark 1.47621276855469 bench/interp 1.47621276855469 gc 0.0)
|
||||
("srfi-13.bm: strings: constructors: string" 5000 user 2.02 benchmark 2.01713897705078 bench/interp 2.01713897705078 gc 0.0)
|
||||
("srfi-13.bm: strings: constructors: list->" 4500 user 0.3 benchmark 0.297425079345703 bench/interp 0.297425079345703 gc 0.0)
|
||||
("srfi-13.bm: strings: constructors: reverse-list->" 5000 user 0.58 benchmark 0.577138977050781 bench/interp 0.577138977050781 gc 0.0)
|
||||
("srfi-13.bm: strings: constructors: make" 22000 user 0.52 benchmark 0.507411499023438 bench/interp 0.507411499023438 gc 0.0)
|
||||
("srfi-13.bm: strings: constructors: tabulate" 17000 user 0.57 benchmark 0.560272521972656 bench/interp 0.560272521972656 gc 0.0)
|
||||
("srfi-13.bm: strings: constructors: join" 5500 user 0.46 benchmark 0.456852874755859 bench/interp 0.456852874755859 gc 0.0)
|
||||
("srfi-13.bm: strings: list/string: ->list" 7300 user 2.36 benchmark 2.35582290649414 bench/interp 2.35582290649414 gc 0.0)
|
||||
("srfi-13.bm: strings: list/string: split" 60000 user 1.87 benchmark 1.83566772460938 bench/interp 1.83566772460938 gc 0.0)
|
||||
("srfi-13.bm: strings: selection: ref" 660 user 1.5 benchmark 1.4996223449707 bench/interp 1.4996223449707 gc 0.0)
|
||||
("srfi-13.bm: strings: selection: copy" 1100 user 0.04 benchmark 0.0393705749511719 bench/interp 0.0393705749511719 gc 0.0)
|
||||
("srfi-13.bm: strings: selection: pad" 6800 user 0.17 benchmark 0.166109008789063 bench/interp 0.166109008789063 gc 0.0)
|
||||
("srfi-13.bm: strings: selection: trim trim-right trim-both" 60000 user 2.67 benchmark 2.63566772460937 bench/interp 2.63566772460937 gc 0.0)
|
||||
("srfi-13.bm: strings: modification: set!" 3000 user 1.42 benchmark 1.41828338623047 bench/interp 1.41828338623047 gc 0.0)
|
||||
("srfi-13.bm: strings: modification: sub-move!" 230000 user 1.88 benchmark 1.74839294433594 bench/interp 1.74839294433594 gc 0.0)
|
||||
("srfi-13.bm: strings: modification: fill!" 230000 user 2.31 benchmark 2.17839294433594 bench/interp 2.17839294433594 gc 0.0)
|
||||
("srfi-13.bm: strings: modification: comparison: compare compare-ci" 140000 user 1.93 benchmark 1.84989135742187 bench/interp 1.84989135742187 gc 0.0)
|
||||
("srfi-13.bm: strings: modification: comparison: hash hash-ci" 1000 user 0.27 benchmark 0.269427795410156 bench/interp 0.269427795410156 gc 0.0)
|
||||
("srfi-13.bm: strings: searching: prefix-length suffix-length" 270 user 0.2 benchmark 0.199845504760742 bench/interp 0.199845504760742 gc 0.0)
|
||||
("srfi-13.bm: strings: searching: prefix? suffix?" 270 user 0.2 benchmark 0.199845504760742 bench/interp 0.199845504760742 gc 0.0)
|
||||
("srfi-13.bm: strings: searching: index index-right rindex" 100000 user 3.48 benchmark 3.42277954101562 bench/interp 3.42277954101562 gc 0.0)
|
||||
("srfi-13.bm: strings: searching: skip skip-right?" 100000 user 2.14 benchmark 2.08277954101563 bench/interp 2.08277954101563 gc 0.0)
|
||||
("srfi-13.bm: strings: searching: count" 10000 user 9.35 benchmark 9.34427795410156 bench/interp 9.34427795410156 gc 0.0)
|
||||
("srfi-13.bm: strings: searching: contains contains-ci" 34000 user 2.29 benchmark 2.27054504394531 bench/interp 2.27054504394531 gc 0.0)
|
||||
("srfi-13.bm: strings: searching: upcase downcase upcase! downcase!" 600 user 0.2 benchmark 0.199656677246094 bench/interp 0.199656677246094 gc 0.0)
|
||||
("srfi-13.bm: strings: readers: read token, method 1" 1200 user 1.26 benchmark 1.25931335449219 bench/interp 1.25931335449219 gc 0.0)
|
||||
("srfi-13.bm: strings: readers: read token, method 2" 1200 user 2.03 benchmark 2.02931335449219 bench/interp 2.02931335449219 gc 0.0)
|
||||
("subr.bm: subr invocation: simple subr" 700000 user 0.47 benchmark 0.069456787109375 bench/interp 0.069456787109375 gc 0.0)
|
||||
("subr.bm: subr invocation: generic subr" 700000 user 1.75 benchmark 1.34945678710938 bench/interp 1.34945678710938 gc 0.0)
|
||||
("subr.bm: subr invocation: generic subr with rest arg" 700000 user 1.39 benchmark 0.989456787109375 bench/interp 0.989456787109375 gc 0.0)
|
||||
("subr.bm: subr invocation: generic subr with rest arg and 3+ parameters" 700000 user 1.86 benchmark 1.45945678710938 bench/interp 1.45945678710938 gc 0.0)
|
||||
("subr.bm: subr application: simple subr" 700000 user 0.91 benchmark 0.509456787109375 bench/interp 0.509456787109375 gc 0.0)
|
||||
("subr.bm: subr application: generic subr" 700000 user 1.8 benchmark 1.39945678710938 bench/interp 1.39945678710938 gc 0.0)
|
||||
("subr.bm: subr application: generic subr with rest arg" 700000 user 1.44 benchmark 1.03945678710937 bench/interp 1.03945678710937 gc 0.0)
|
||||
("subr.bm: subr application: generic subr with rest arg and 3+ parameters" 700000 user 1.89 benchmark 1.48945678710937 bench/interp 1.48945678710937 gc 0.0)
|
||||
("uniform-vector-read.bm: uniform-vector-read!: uniform-vector-write" 500 user 0.12 benchmark 0.119713897705078 bench/interp 0.119713897705078 gc 0.0)
|
||||
("uniform-vector-read.bm: uniform-vector-read!: uniform-vector-read!" 500 user 0.02 benchmark 0.0197138977050781 bench/interp 0.0197138977050781 gc 0.0)
|
||||
("uniform-vector-read.bm: uniform-vector-read!: string port" 5000 user 2.49 benchmark 2.48713897705078 bench/interp 2.48713897705078 gc 0.0)
|
500
build-aux/announce-gen
Executable file
500
build-aux/announce-gen
Executable file
|
@ -0,0 +1,500 @@
|
|||
eval '(exit $?0)' && eval 'exec perl -wS "$0" ${1+"$@"}'
|
||||
& eval 'exec perl -wS "$0" $argv:q'
|
||||
if 0;
|
||||
# Generate a release announcement message.
|
||||
|
||||
my $VERSION = '2009-11-20 13:36'; # UTC
|
||||
# The definition above must lie within the first 8 lines in order
|
||||
# for the Emacs time-stamp write hook (at end) to update it.
|
||||
# If you change this file with Emacs, please let the write hook
|
||||
# do its job. Otherwise, update this string manually.
|
||||
|
||||
# Copyright (C) 2002-2009 Free Software Foundation, Inc.
|
||||
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
# Written by Jim Meyering
|
||||
|
||||
use strict;
|
||||
|
||||
use Getopt::Long;
|
||||
use Digest::MD5;
|
||||
use Digest::SHA1;
|
||||
use POSIX qw(strftime);
|
||||
|
||||
(my $ME = $0) =~ s|.*/||;
|
||||
|
||||
my %valid_release_types = map {$_ => 1} qw (alpha beta stable);
|
||||
my @archive_suffixes = ('tar.gz', 'tar.bz2', 'tar.lzma', 'tar.xz');
|
||||
|
||||
sub usage ($)
|
||||
{
|
||||
my ($exit_code) = @_;
|
||||
my $STREAM = ($exit_code == 0 ? *STDOUT : *STDERR);
|
||||
if ($exit_code != 0)
|
||||
{
|
||||
print $STREAM "Try `$ME --help' for more information.\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
my @types = sort keys %valid_release_types;
|
||||
print $STREAM <<EOF;
|
||||
Usage: $ME [OPTIONS]
|
||||
Generate an announcement message.
|
||||
|
||||
OPTIONS:
|
||||
|
||||
These options must be specified:
|
||||
|
||||
--release-type=TYPE TYPE must be one of @types
|
||||
--package-name=PACKAGE_NAME
|
||||
--previous-version=VER
|
||||
--current-version=VER
|
||||
--gpg-key-id=ID The GnuPG ID of the key used to sign the tarballs
|
||||
--url-directory=URL_DIR
|
||||
|
||||
The following are optional:
|
||||
|
||||
--news=NEWS_FILE
|
||||
--bootstrap-tools=TOOL_LIST a comma-separated list of tools, e.g.,
|
||||
autoconf,automake,bison,gnulib
|
||||
--gnulib-version=VERSION report VERSION as the gnulib version, where
|
||||
VERSION is the result of running git describe
|
||||
in the gnulib source directory.
|
||||
required if gnulib is in TOOL_LIST.
|
||||
--no-print-checksums do not emit MD5 or SHA1 checksums
|
||||
--archive-suffix=SUF add SUF to the list of archive suffixes
|
||||
|
||||
--help display this help and exit
|
||||
--version output version information and exit
|
||||
|
||||
EOF
|
||||
}
|
||||
exit $exit_code;
|
||||
}
|
||||
|
||||
|
||||
=item C<%size> = C<sizes (@file)>
|
||||
|
||||
Compute the sizes of the C<@file> and return them as a hash. Return
|
||||
C<undef> if one of the computation failed.
|
||||
|
||||
=cut
|
||||
|
||||
sub sizes (@)
|
||||
{
|
||||
my (@file) = @_;
|
||||
|
||||
my $fail = 0;
|
||||
my %res;
|
||||
foreach my $f (@file)
|
||||
{
|
||||
my $cmd = "du --human $f";
|
||||
my $t = `$cmd`;
|
||||
# FIXME-someday: give a better diagnostic, a la $PROCESS_STATUS
|
||||
$@
|
||||
and (warn "$ME: command failed: `$cmd'\n"), $fail = 1;
|
||||
chomp $t;
|
||||
$t =~ s/^([\d.]+[MkK]).*/${1}B/;
|
||||
$res{$f} = $t;
|
||||
}
|
||||
return $fail ? undef : %res;
|
||||
}
|
||||
|
||||
=item C<print_locations ($title, \@url, \%size, @file)
|
||||
|
||||
Print a section C<$title> dedicated to the list of <@file>, which
|
||||
sizes are stored in C<%size>, and which are available from the C<@url>.
|
||||
|
||||
=cut
|
||||
|
||||
sub print_locations ($\@\%@)
|
||||
{
|
||||
my ($title, $url, $size, @file) = @_;
|
||||
print "Here are the $title:\n";
|
||||
foreach my $url (@{$url})
|
||||
{
|
||||
for my $file (@file)
|
||||
{
|
||||
print " $url/$file";
|
||||
print " (", $$size{$file}, ")"
|
||||
if exists $$size{$file};
|
||||
print "\n";
|
||||
}
|
||||
}
|
||||
print "\n";
|
||||
}
|
||||
|
||||
=item C<print_checksums (@file)
|
||||
|
||||
Print the MD5 and SHA1 signature section for each C<@file>.
|
||||
|
||||
=cut
|
||||
|
||||
sub print_checksums (@)
|
||||
{
|
||||
my (@file) = @_;
|
||||
|
||||
print "Here are the MD5 and SHA1 checksums:\n";
|
||||
print "\n";
|
||||
|
||||
foreach my $meth (qw (md5 sha1))
|
||||
{
|
||||
foreach my $f (@file)
|
||||
{
|
||||
open IN, '<', $f
|
||||
or die "$ME: $f: cannot open for reading: $!\n";
|
||||
binmode IN;
|
||||
my $dig =
|
||||
($meth eq 'md5'
|
||||
? Digest::MD5->new->addfile(*IN)->hexdigest
|
||||
: Digest::SHA1->new->addfile(*IN)->hexdigest);
|
||||
close IN;
|
||||
print "$dig $f\n";
|
||||
}
|
||||
}
|
||||
print "\n";
|
||||
}
|
||||
|
||||
=item C<print_news_deltas ($news_file, $prev_version, $curr_version)
|
||||
|
||||
Print the section of the NEWS file C<$news_file> addressing changes
|
||||
between versions C<$prev_version> and C<$curr_version>.
|
||||
|
||||
=cut
|
||||
|
||||
sub print_news_deltas ($$$)
|
||||
{
|
||||
my ($news_file, $prev_version, $curr_version) = @_;
|
||||
|
||||
print "\n$news_file\n\n";
|
||||
|
||||
# Print all lines from $news_file, starting with the first one
|
||||
# that mentions $curr_version up to but not including
|
||||
# the first occurrence of $prev_version.
|
||||
my $in_items;
|
||||
|
||||
my $re_prefix = qr/(?:\* )?(?:Noteworthy c|Major c|C)(?i:hanges)/;
|
||||
|
||||
open NEWS, '<', $news_file
|
||||
or die "$ME: $news_file: cannot open for reading: $!\n";
|
||||
while (defined (my $line = <NEWS>))
|
||||
{
|
||||
if ( ! $in_items)
|
||||
{
|
||||
# Match lines like these:
|
||||
# * Major changes in release 5.0.1:
|
||||
# * Noteworthy changes in release 6.6 (2006-11-22) [stable]
|
||||
$line =~ /^$re_prefix.*(?:[^\d.]|$)\Q$curr_version\E(?:[^\d.]|$)/o
|
||||
or next;
|
||||
$in_items = 1;
|
||||
print $line;
|
||||
}
|
||||
else
|
||||
{
|
||||
# This regexp must not match version numbers in NEWS items.
|
||||
# For example, they might well say `introduced in 4.5.5',
|
||||
# and we don't want that to match.
|
||||
$line =~ /^$re_prefix.*(?:[^\d.]|$)\Q$prev_version\E(?:[^\d.]|$)/o
|
||||
and last;
|
||||
print $line;
|
||||
}
|
||||
}
|
||||
close NEWS;
|
||||
|
||||
$in_items
|
||||
or die "$ME: $news_file: no matching lines for `$curr_version'\n";
|
||||
}
|
||||
|
||||
sub print_changelog_deltas ($$)
|
||||
{
|
||||
my ($package_name, $prev_version) = @_;
|
||||
|
||||
# Print new ChangeLog entries.
|
||||
|
||||
# First find all CVS-controlled ChangeLog files.
|
||||
use File::Find;
|
||||
my @changelog;
|
||||
find ({wanted => sub {$_ eq 'ChangeLog' && -d 'CVS'
|
||||
and push @changelog, $File::Find::name}},
|
||||
'.');
|
||||
|
||||
# If there are no ChangeLog files, we're done.
|
||||
@changelog
|
||||
or return;
|
||||
my %changelog = map {$_ => 1} @changelog;
|
||||
|
||||
# Reorder the list of files so that if there are ChangeLog
|
||||
# files in the specified directories, they're listed first,
|
||||
# in this order:
|
||||
my @dir = qw ( . src lib m4 config doc );
|
||||
|
||||
# A typical @changelog array might look like this:
|
||||
# ./ChangeLog
|
||||
# ./po/ChangeLog
|
||||
# ./m4/ChangeLog
|
||||
# ./lib/ChangeLog
|
||||
# ./doc/ChangeLog
|
||||
# ./config/ChangeLog
|
||||
my @reordered;
|
||||
foreach my $d (@dir)
|
||||
{
|
||||
my $dot_slash = $d eq '.' ? $d : "./$d";
|
||||
my $target = "$dot_slash/ChangeLog";
|
||||
delete $changelog{$target}
|
||||
and push @reordered, $target;
|
||||
}
|
||||
|
||||
# Append any remaining ChangeLog files.
|
||||
push @reordered, sort keys %changelog;
|
||||
|
||||
# Remove leading `./'.
|
||||
@reordered = map { s!^\./!!; $_ } @reordered;
|
||||
|
||||
print "\nChangeLog entries:\n\n";
|
||||
# print join ("\n", @reordered), "\n";
|
||||
|
||||
$prev_version =~ s/\./_/g;
|
||||
my $prev_cvs_tag = "\U$package_name\E-$prev_version";
|
||||
|
||||
my $cmd = "cvs -n diff -u -r$prev_cvs_tag -rHEAD @reordered";
|
||||
open DIFF, '-|', $cmd
|
||||
or die "$ME: cannot run `$cmd': $!\n";
|
||||
# Print two types of lines, making minor changes:
|
||||
# Lines starting with `+++ ', e.g.,
|
||||
# +++ ChangeLog 22 Feb 2003 16:52:51 -0000 1.247
|
||||
# and those starting with `+'.
|
||||
# Don't print the others.
|
||||
my $prev_printed_line_empty = 1;
|
||||
while (defined (my $line = <DIFF>))
|
||||
{
|
||||
if ($line =~ /^\+\+\+ /)
|
||||
{
|
||||
my $separator = "*"x70 ."\n";
|
||||
$line =~ s///;
|
||||
$line =~ s/\s.*//;
|
||||
$prev_printed_line_empty
|
||||
or print "\n";
|
||||
print $separator, $line, $separator;
|
||||
}
|
||||
elsif ($line =~ /^\+/)
|
||||
{
|
||||
$line =~ s///;
|
||||
print $line;
|
||||
$prev_printed_line_empty = ($line =~ /^$/);
|
||||
}
|
||||
}
|
||||
close DIFF;
|
||||
|
||||
# The exit code should be 1.
|
||||
# Allow in case there are no modified ChangeLog entries.
|
||||
$? == 256 || $? == 128
|
||||
or warn "$ME: warning: `cmd' had unexpected exit code or signal ($?)\n";
|
||||
}
|
||||
|
||||
sub get_tool_versions ($$)
|
||||
{
|
||||
my ($tool_list, $gnulib_version) = @_;
|
||||
@$tool_list
|
||||
or return ();
|
||||
|
||||
my $fail;
|
||||
my @tool_version_pair;
|
||||
foreach my $t (@$tool_list)
|
||||
{
|
||||
if ($t eq 'gnulib')
|
||||
{
|
||||
push @tool_version_pair, ucfirst $t . ' ' . $gnulib_version;
|
||||
next;
|
||||
}
|
||||
# Assume that the last "word" on the first line of
|
||||
# `tool --version` output is the version string.
|
||||
my ($first_line, undef) = split ("\n", `$t --version`);
|
||||
if ($first_line =~ /.* (\d[\w.-]+)$/)
|
||||
{
|
||||
$t = ucfirst $t;
|
||||
push @tool_version_pair, "$t $1";
|
||||
}
|
||||
else
|
||||
{
|
||||
defined $first_line
|
||||
and $first_line = '';
|
||||
warn "$ME: $t: unexpected --version output\n:$first_line";
|
||||
$fail = 1;
|
||||
}
|
||||
}
|
||||
|
||||
$fail
|
||||
and exit 1;
|
||||
|
||||
return @tool_version_pair;
|
||||
}
|
||||
|
||||
{
|
||||
# Neutralize the locale, so that, for instance, "du" does not
|
||||
# issue "1,2" instead of "1.2", what confuses our regexps.
|
||||
$ENV{LC_ALL} = "C";
|
||||
|
||||
my $release_type;
|
||||
my $package_name;
|
||||
my $prev_version;
|
||||
my $curr_version;
|
||||
my $gpg_key_id;
|
||||
my @url_dir_list;
|
||||
my @news_file;
|
||||
my $bootstrap_tools;
|
||||
my $gnulib_version;
|
||||
my $print_checksums_p = 1;
|
||||
|
||||
GetOptions
|
||||
(
|
||||
'release-type=s' => \$release_type,
|
||||
'package-name=s' => \$package_name,
|
||||
'previous-version=s' => \$prev_version,
|
||||
'current-version=s' => \$curr_version,
|
||||
'gpg-key-id=s' => \$gpg_key_id,
|
||||
'url-directory=s' => \@url_dir_list,
|
||||
'news=s' => \@news_file,
|
||||
'bootstrap-tools=s' => \$bootstrap_tools,
|
||||
'gnulib-version=s' => \$gnulib_version,
|
||||
'print-checksums!' => \$print_checksums_p,
|
||||
'archive-suffix=s' => \@archive_suffixes,
|
||||
|
||||
help => sub { usage 0 },
|
||||
version => sub { print "$ME version $VERSION\n"; exit },
|
||||
) or usage 1;
|
||||
|
||||
my $fail = 0;
|
||||
# Ensure that sure each required option is specified.
|
||||
$release_type
|
||||
or (warn "$ME: release type not specified\n"), $fail = 1;
|
||||
$package_name
|
||||
or (warn "$ME: package name not specified\n"), $fail = 1;
|
||||
$prev_version
|
||||
or (warn "$ME: previous version string not specified\n"), $fail = 1;
|
||||
$curr_version
|
||||
or (warn "$ME: current version string not specified\n"), $fail = 1;
|
||||
$gpg_key_id
|
||||
or (warn "$ME: GnuPG key ID not specified\n"), $fail = 1;
|
||||
@url_dir_list
|
||||
or (warn "$ME: URL directory name(s) not specified\n"), $fail = 1;
|
||||
|
||||
my @tool_list = split ',', $bootstrap_tools;
|
||||
|
||||
grep (/^gnulib$/, @tool_list) ^ defined $gnulib_version
|
||||
and (warn "$ME: when specifying gnulib as a tool, you must also specify\n"
|
||||
. "--gnulib-version=V, where V is the result of running git describe\n"
|
||||
. "in the gnulib source directory.\n"), $fail = 1;
|
||||
|
||||
exists $valid_release_types{$release_type}
|
||||
or (warn "$ME: `$release_type': invalid release type\n"), $fail = 1;
|
||||
|
||||
@ARGV
|
||||
and (warn "$ME: too many arguments:\n", join ("\n", @ARGV), "\n"),
|
||||
$fail = 1;
|
||||
$fail
|
||||
and usage 1;
|
||||
|
||||
my $my_distdir = "$package_name-$curr_version";
|
||||
|
||||
my $xd = "$package_name-$prev_version-$curr_version.xdelta";
|
||||
|
||||
my @candidates = map { "$my_distdir.$_" } @archive_suffixes;
|
||||
my @tarballs = grep {-f $_} @candidates;
|
||||
|
||||
@tarballs
|
||||
or die "$ME: none of " . join(', ', @candidates) . " were found\n";
|
||||
my @sizable = @tarballs;
|
||||
-f $xd
|
||||
and push @sizable, $xd;
|
||||
my %size = sizes (@sizable);
|
||||
%size
|
||||
or exit 1;
|
||||
|
||||
# The markup is escaped as <\# so that when this script is sent by
|
||||
# mail (or part of a diff), Gnus is not triggered.
|
||||
print <<EOF;
|
||||
|
||||
Subject: $my_distdir released [$release_type]
|
||||
|
||||
<\#secure method=pgpmime mode=sign>
|
||||
|
||||
FIXME: put comments here
|
||||
|
||||
EOF
|
||||
|
||||
print_locations ("compressed sources", @url_dir_list, %size, @tarballs);
|
||||
-f $xd
|
||||
and print_locations ("xdelta diffs (useful? if so, "
|
||||
. "please tell bug-gnulib\@gnu.org)",
|
||||
@url_dir_list, %size, $xd);
|
||||
my @sig_files = map { "$_.sig" } @tarballs;
|
||||
print_locations ("GPG detached signatures[*]", @url_dir_list, %size,
|
||||
@sig_files);
|
||||
if ($url_dir_list[0] =~ "gnu\.org")
|
||||
{
|
||||
print "To reduce load on the main server, use a mirror listed at:\n";
|
||||
print " http://www.gnu.org/order/ftp.html\n\n";
|
||||
}
|
||||
|
||||
$print_checksums_p
|
||||
and print_checksums (@sizable);
|
||||
|
||||
print <<EOF;
|
||||
[*] You can use either of the above signature files to verify that
|
||||
the corresponding file (without the .sig suffix) is intact. First,
|
||||
be sure to download both the .sig file and the corresponding tarball.
|
||||
Then, run a command like this:
|
||||
|
||||
gpg --verify $tarballs[0].sig
|
||||
|
||||
If that command fails because you don't have the required public key,
|
||||
then run this command to import it:
|
||||
|
||||
gpg --keyserver keys.gnupg.net --recv-keys $gpg_key_id
|
||||
|
||||
and rerun the \`gpg --verify' command.
|
||||
EOF
|
||||
|
||||
my @tool_versions = get_tool_versions (\@tool_list, $gnulib_version);
|
||||
@tool_versions
|
||||
and print "\nThis release was bootstrapped with the following tools:",
|
||||
join ('', map {"\n $_"} @tool_versions), "\n";
|
||||
|
||||
print_news_deltas ($_, $prev_version, $curr_version)
|
||||
foreach @news_file;
|
||||
|
||||
$release_type eq 'stable'
|
||||
or print_changelog_deltas ($package_name, $prev_version);
|
||||
|
||||
exit 0;
|
||||
}
|
||||
|
||||
### Setup "GNU" style for perl-mode and cperl-mode.
|
||||
## Local Variables:
|
||||
## mode: perl
|
||||
## perl-indent-level: 2
|
||||
## perl-continued-statement-offset: 2
|
||||
## perl-continued-brace-offset: 0
|
||||
## perl-brace-offset: 0
|
||||
## perl-brace-imaginary-offset: 0
|
||||
## perl-label-offset: -2
|
||||
## perl-extra-newline-before-brace: t
|
||||
## perl-merge-trailing-else: nil
|
||||
## eval: (add-hook 'write-file-hooks 'time-stamp)
|
||||
## time-stamp-start: "my $VERSION = '"
|
||||
## time-stamp-format: "%:y-%02m-%02d %02H:%02M"
|
||||
## time-stamp-time-zone: "UTC"
|
||||
## time-stamp-end: "'; # UTC"
|
||||
## End:
|
361
build-aux/gendocs.sh
Normal file
361
build-aux/gendocs.sh
Normal file
|
@ -0,0 +1,361 @@
|
|||
#!/bin/sh
|
||||
# gendocs.sh -- generate a GNU manual in many formats. This script is
|
||||
# mentioned in maintain.texi. See the help message below for usage details.
|
||||
|
||||
scriptversion=2009-09-09.22
|
||||
|
||||
# Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009
|
||||
# Free Software Foundation, Inc.
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
# Original author: Mohit Agarwal.
|
||||
# Send bug reports and any other correspondence to bug-texinfo@gnu.org.
|
||||
|
||||
prog=`basename "$0"`
|
||||
srcdir=`pwd`
|
||||
|
||||
scripturl="http://savannah.gnu.org/cgi-bin/viewcvs/~checkout~/texinfo/texinfo/util/gendocs.sh"
|
||||
templateurl="http://savannah.gnu.org/cgi-bin/viewcvs/~checkout~/texinfo/texinfo/util/gendocs_template"
|
||||
|
||||
: ${SETLANG="env LANG= LC_MESSAGES= LC_ALL= LANGUAGE="}
|
||||
: ${MAKEINFO="makeinfo"}
|
||||
: ${TEXI2DVI="texi2dvi -t @finalout"}
|
||||
: ${DVIPS="dvips"}
|
||||
: ${DOCBOOK2HTML="docbook2html"}
|
||||
: ${DOCBOOK2PDF="docbook2pdf"}
|
||||
: ${DOCBOOK2PS="docbook2ps"}
|
||||
: ${DOCBOOK2TXT="docbook2txt"}
|
||||
: ${GENDOCS_TEMPLATE_DIR="."}
|
||||
: ${TEXI2HTML="texi2html"}
|
||||
unset CDPATH
|
||||
unset use_texi2html
|
||||
|
||||
version="gendocs.sh $scriptversion
|
||||
|
||||
Copyright 2009 Free Software Foundation, Inc.
|
||||
There is NO warranty. You may redistribute this software
|
||||
under the terms of the GNU General Public License.
|
||||
For more information about these matters, see the files named COPYING."
|
||||
|
||||
usage="Usage: $prog [OPTION]... PACKAGE MANUAL-TITLE
|
||||
|
||||
Generate various output formats from PACKAGE.texinfo (or .texi or .txi) source.
|
||||
See the GNU Maintainers document for a more extensive discussion:
|
||||
http://www.gnu.org/prep/maintain_toc.html
|
||||
|
||||
Options:
|
||||
-o OUTDIR write files into OUTDIR, instead of manual/.
|
||||
--email ADR use ADR as contact in generated web pages.
|
||||
--docbook convert to DocBook too (xml, txt, html, pdf and ps).
|
||||
--html ARG pass indicated ARG to makeinfo or texi2html for HTML targets.
|
||||
--texi2html use texi2html to generate HTML targets.
|
||||
--help display this help and exit successfully.
|
||||
--version display version information and exit successfully.
|
||||
|
||||
Simple example: $prog --email bug-gnu-emacs@gnu.org emacs \"GNU Emacs Manual\"
|
||||
|
||||
Typical sequence:
|
||||
cd PACKAGESOURCE/doc
|
||||
wget \"$scripturl\"
|
||||
wget \"$templateurl\"
|
||||
$prog --email BUGLIST MANUAL \"GNU MANUAL - One-line description\"
|
||||
|
||||
Output will be in a new subdirectory \"manual\" (by default, use -o OUTDIR
|
||||
to override). Move all the new files into your web CVS tree, as
|
||||
explained in the Web Pages node of maintain.texi.
|
||||
|
||||
Please use the --email ADDRESS option to specify your bug-reporting
|
||||
address in the generated HTML pages.
|
||||
|
||||
MANUAL-TITLE is included as part of the HTML <title> of the overall
|
||||
manual/index.html file. It should include the name of the package being
|
||||
documented. manual/index.html is created by substitution from the file
|
||||
$GENDOCS_TEMPLATE_DIR/gendocs_template. (Feel free to modify the
|
||||
generic template for your own purposes.)
|
||||
|
||||
If you have several manuals, you'll need to run this script several
|
||||
times with different MANUAL values, specifying a different output
|
||||
directory with -o each time. Then write (by hand) an overall index.html
|
||||
with links to them all.
|
||||
|
||||
If a manual's Texinfo sources are spread across several directories,
|
||||
first copy or symlink all Texinfo sources into a single directory.
|
||||
(Part of the script's work is to make a tar.gz of the sources.)
|
||||
|
||||
You can set the environment variables MAKEINFO, TEXI2DVI, and DVIPS to
|
||||
control the programs that get executed, and GENDOCS_TEMPLATE_DIR to
|
||||
control where the gendocs_template file is looked for. (With --docbook,
|
||||
the environment variables DOCBOOK2HTML, DOCBOOK2PDF, DOCBOOK2PS, and
|
||||
DOCBOOK2TXT are also respected.)
|
||||
|
||||
By default, makeinfo is run in the default (English) locale, since
|
||||
that's the language of most Texinfo manuals. If you happen to have a
|
||||
non-English manual and non-English web site, see the SETLANG setting
|
||||
in the source.
|
||||
|
||||
Email bug reports or enhancement requests to bug-texinfo@gnu.org.
|
||||
"
|
||||
|
||||
calcsize()
|
||||
{
|
||||
size=`ls -ksl $1 | awk '{print $1}'`
|
||||
echo $size
|
||||
}
|
||||
|
||||
MANUAL_TITLE=
|
||||
PACKAGE=
|
||||
EMAIL=webmasters@gnu.org # please override with --email
|
||||
htmlarg=
|
||||
outdir=manual
|
||||
|
||||
while test $# -gt 0; do
|
||||
case $1 in
|
||||
--email) shift; EMAIL=$1;;
|
||||
--help) echo "$usage"; exit 0;;
|
||||
--version) echo "$version"; exit 0;;
|
||||
-o) shift; outdir=$1;;
|
||||
--docbook) docbook=yes;;
|
||||
--html) shift; htmlarg=$1;;
|
||||
--texi2html) use_texi2html=1;;
|
||||
-*)
|
||||
echo "$0: Unknown option \`$1'." >&2
|
||||
echo "$0: Try \`--help' for more information." >&2
|
||||
exit 1;;
|
||||
*)
|
||||
if test -z "$PACKAGE"; then
|
||||
PACKAGE=$1
|
||||
elif test -z "$MANUAL_TITLE"; then
|
||||
MANUAL_TITLE=$1
|
||||
else
|
||||
echo "$0: extra non-option argument \`$1'." >&2
|
||||
exit 1
|
||||
fi;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
if test -s "$srcdir/$PACKAGE.texinfo"; then
|
||||
srcfile=$srcdir/$PACKAGE.texinfo
|
||||
elif test -s "$srcdir/$PACKAGE.texi"; then
|
||||
srcfile=$srcdir/$PACKAGE.texi
|
||||
elif test -s "$srcdir/$PACKAGE.txi"; then
|
||||
srcfile=$srcdir/$PACKAGE.txi
|
||||
else
|
||||
echo "$0: cannot find .texinfo or .texi or .txi for $PACKAGE in $srcdir." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if test ! -r $GENDOCS_TEMPLATE_DIR/gendocs_template; then
|
||||
echo "$0: cannot read $GENDOCS_TEMPLATE_DIR/gendocs_template." >&2
|
||||
echo "$0: it is available from $templateurl." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
case $outdir in
|
||||
/*) dotdot_outdir="$outdir";;
|
||||
*) dotdot_outdir="../$outdir";;
|
||||
esac
|
||||
|
||||
echo Generating output formats for $srcfile
|
||||
|
||||
cmd="$SETLANG $MAKEINFO -o $PACKAGE.info \"$srcfile\""
|
||||
echo "Generating info files... ($cmd)"
|
||||
eval "$cmd"
|
||||
mkdir -p $outdir/
|
||||
tar czf $outdir/$PACKAGE.info.tar.gz $PACKAGE.info*
|
||||
info_tgz_size=`calcsize $outdir/$PACKAGE.info.tar.gz`
|
||||
# do not mv the info files, there's no point in having them available
|
||||
# separately on the web.
|
||||
|
||||
cmd="${TEXI2DVI} \"$srcfile\""
|
||||
echo "Generating dvi ... ($cmd)"
|
||||
eval "$cmd"
|
||||
|
||||
# now, before we compress dvi:
|
||||
echo Generating postscript...
|
||||
${DVIPS} $PACKAGE -o
|
||||
gzip -f -9 $PACKAGE.ps
|
||||
ps_gz_size=`calcsize $PACKAGE.ps.gz`
|
||||
mv $PACKAGE.ps.gz $outdir/
|
||||
|
||||
# compress/finish dvi:
|
||||
gzip -f -9 $PACKAGE.dvi
|
||||
dvi_gz_size=`calcsize $PACKAGE.dvi.gz`
|
||||
mv $PACKAGE.dvi.gz $outdir/
|
||||
|
||||
cmd="${TEXI2DVI} --pdf \"$srcfile\""
|
||||
echo "Generating pdf ... ($cmd)"
|
||||
eval "$cmd"
|
||||
pdf_size=`calcsize $PACKAGE.pdf`
|
||||
mv $PACKAGE.pdf $outdir/
|
||||
|
||||
cmd="$SETLANG $MAKEINFO -o $PACKAGE.txt --no-split --no-headers \"$srcfile\""
|
||||
echo "Generating ASCII... ($cmd)"
|
||||
eval "$cmd"
|
||||
ascii_size=`calcsize $PACKAGE.txt`
|
||||
gzip -f -9 -c $PACKAGE.txt >$outdir/$PACKAGE.txt.gz
|
||||
ascii_gz_size=`calcsize $outdir/$PACKAGE.txt.gz`
|
||||
mv $PACKAGE.txt $outdir/
|
||||
|
||||
html_split()
|
||||
{
|
||||
opt="--split=$1 $htmlarg --node-files"
|
||||
cmd="$SETLANG $TEXI2HTML --output $PACKAGE.html $opt \"$srcfile\""
|
||||
echo "Generating html by $1... ($cmd)"
|
||||
eval "$cmd"
|
||||
split_html_dir=$PACKAGE.html
|
||||
(
|
||||
cd ${split_html_dir} || exit 1
|
||||
ln -sf ${PACKAGE}.html index.html
|
||||
tar -czf $dotdot_outdir/${PACKAGE}.html_$1.tar.gz -- *.html
|
||||
)
|
||||
eval html_$1_tgz_size=`calcsize $outdir/${PACKAGE}.html_$1.tar.gz`
|
||||
rm -f $outdir/html_$1/*.html
|
||||
mkdir -p $outdir/html_$1/
|
||||
mv ${split_html_dir}/*.html $outdir/html_$1/
|
||||
rmdir ${split_html_dir}
|
||||
}
|
||||
|
||||
if test -z "$use_texi2html"; then
|
||||
opt="--no-split --html -o $PACKAGE.html $htmlarg"
|
||||
cmd="$SETLANG $MAKEINFO $opt \"$srcfile\""
|
||||
echo "Generating monolithic html... ($cmd)"
|
||||
rm -rf $PACKAGE.html # in case a directory is left over
|
||||
eval "$cmd"
|
||||
html_mono_size=`calcsize $PACKAGE.html`
|
||||
gzip -f -9 -c $PACKAGE.html >$outdir/$PACKAGE.html.gz
|
||||
html_mono_gz_size=`calcsize $outdir/$PACKAGE.html.gz`
|
||||
mv $PACKAGE.html $outdir/
|
||||
|
||||
cmd="$SETLANG $MAKEINFO --html -o $PACKAGE.html $htmlarg \"$srcfile\""
|
||||
echo "Generating html by node... ($cmd)"
|
||||
eval "$cmd"
|
||||
split_html_dir=$PACKAGE.html
|
||||
(
|
||||
cd ${split_html_dir} || exit 1
|
||||
tar -czf $dotdot_outdir/${PACKAGE}.html_node.tar.gz -- *.html
|
||||
)
|
||||
html_node_tgz_size=`calcsize $outdir/${PACKAGE}.html_node.tar.gz`
|
||||
rm -f $outdir/html_node/*.html
|
||||
mkdir -p $outdir/html_node/
|
||||
mv ${split_html_dir}/*.html $outdir/html_node/
|
||||
rmdir ${split_html_dir}
|
||||
else
|
||||
cmd="$SETLANG $TEXI2HTML --output $PACKAGE.html $htmlarg \"$srcfile\""
|
||||
echo "Generating monolithic html... ($cmd)"
|
||||
rm -rf $PACKAGE.html # in case a directory is left over
|
||||
eval "$cmd"
|
||||
html_mono_size=`calcsize $PACKAGE.html`
|
||||
gzip -f -9 -c $PACKAGE.html >$outdir/$PACKAGE.html.gz
|
||||
html_mono_gz_size=`calcsize $outdir/$PACKAGE.html.gz`
|
||||
mv $PACKAGE.html $outdir/
|
||||
|
||||
html_split node
|
||||
html_split chapter
|
||||
html_split section
|
||||
fi
|
||||
|
||||
echo Making .tar.gz for sources...
|
||||
srcfiles=`ls *.texinfo *.texi *.txi *.eps 2>/dev/null`
|
||||
tar cvzfh $outdir/$PACKAGE.texi.tar.gz $srcfiles
|
||||
texi_tgz_size=`calcsize $outdir/$PACKAGE.texi.tar.gz`
|
||||
|
||||
if test -n "$docbook"; then
|
||||
cmd="$SETLANG $MAKEINFO -o - --docbook \"$srcfile\" > ${srcdir}/$PACKAGE-db.xml"
|
||||
echo "Generating docbook XML... $(cmd)"
|
||||
eval "$cmd"
|
||||
docbook_xml_size=`calcsize $PACKAGE-db.xml`
|
||||
gzip -f -9 -c $PACKAGE-db.xml >$outdir/$PACKAGE-db.xml.gz
|
||||
docbook_xml_gz_size=`calcsize $outdir/$PACKAGE-db.xml.gz`
|
||||
mv $PACKAGE-db.xml $outdir/
|
||||
|
||||
cmd="${DOCBOOK2HTML} -o $split_html_db_dir ${outdir}/$PACKAGE-db.xml"
|
||||
echo "Generating docbook HTML... ($cmd)"
|
||||
eval "$cmd"
|
||||
split_html_db_dir=html_node_db
|
||||
(
|
||||
cd ${split_html_db_dir} || exit 1
|
||||
tar -czf $dotdot_outdir/${PACKAGE}.html_node_db.tar.gz -- *.html
|
||||
)
|
||||
html_node_db_tgz_size=`calcsize $outdir/${PACKAGE}.html_node_db.tar.gz`
|
||||
rm -f $outdir/html_node_db/*.html
|
||||
mkdir -p $outdir/html_node_db
|
||||
mv ${split_html_db_dir}/*.html $outdir/html_node_db/
|
||||
rmdir ${split_html_db_dir}
|
||||
|
||||
cmd="${DOCBOOK2TXT} ${outdir}/$PACKAGE-db.xml"
|
||||
echo "Generating docbook ASCII... ($cmd)"
|
||||
eval "$cmd"
|
||||
docbook_ascii_size=`calcsize $PACKAGE-db.txt`
|
||||
mv $PACKAGE-db.txt $outdir/
|
||||
|
||||
cmd="${DOCBOOK2PS} ${outdir}/$PACKAGE-db.xml"
|
||||
echo "Generating docbook PS... $(cmd)"
|
||||
eval "$cmd"
|
||||
gzip -f -9 -c $PACKAGE-db.ps >$outdir/$PACKAGE-db.ps.gz
|
||||
docbook_ps_gz_size=`calcsize $outdir/$PACKAGE-db.ps.gz`
|
||||
mv $PACKAGE-db.ps $outdir/
|
||||
|
||||
cmd="${DOCBOOK2PDF} ${outdir}/$PACKAGE-db.xml"
|
||||
echo "Generating docbook PDF... ($cmd)"
|
||||
eval "$cmd"
|
||||
docbook_pdf_size=`calcsize $PACKAGE-db.pdf`
|
||||
mv $PACKAGE-db.pdf $outdir/
|
||||
fi
|
||||
|
||||
echo "Writing index file..."
|
||||
if test -z "$use_texi2html"; then
|
||||
CONDS="/%%IF *HTML_SECTION%%/,/%%ENDIF *HTML_SECTION%%/d;\
|
||||
/%%IF *HTML_CHAPTER%%/,/%%ENDIF *HTML_CHAPTER%%/d"
|
||||
else
|
||||
CONDS="/%%ENDIF.*%%/d;/%%IF *HTML_SECTION%%/d;/%%IF *HTML_CHAPTER%%/d"
|
||||
fi
|
||||
curdate=`$SETLANG date '+%B %d, %Y'`
|
||||
sed \
|
||||
-e "s!%%TITLE%%!$MANUAL_TITLE!g" \
|
||||
-e "s!%%EMAIL%%!$EMAIL!g" \
|
||||
-e "s!%%PACKAGE%%!$PACKAGE!g" \
|
||||
-e "s!%%DATE%%!$curdate!g" \
|
||||
-e "s!%%HTML_MONO_SIZE%%!$html_mono_size!g" \
|
||||
-e "s!%%HTML_MONO_GZ_SIZE%%!$html_mono_gz_size!g" \
|
||||
-e "s!%%HTML_NODE_TGZ_SIZE%%!$html_node_tgz_size!g" \
|
||||
-e "s!%%HTML_SECTION_TGZ_SIZE%%!$html_section_tgz_size!g" \
|
||||
-e "s!%%HTML_CHAPTER_TGZ_SIZE%%!$html_chapter_tgz_size!g" \
|
||||
-e "s!%%INFO_TGZ_SIZE%%!$info_tgz_size!g" \
|
||||
-e "s!%%DVI_GZ_SIZE%%!$dvi_gz_size!g" \
|
||||
-e "s!%%PDF_SIZE%%!$pdf_size!g" \
|
||||
-e "s!%%PS_GZ_SIZE%%!$ps_gz_size!g" \
|
||||
-e "s!%%ASCII_SIZE%%!$ascii_size!g" \
|
||||
-e "s!%%ASCII_GZ_SIZE%%!$ascii_gz_size!g" \
|
||||
-e "s!%%TEXI_TGZ_SIZE%%!$texi_tgz_size!g" \
|
||||
-e "s!%%DOCBOOK_HTML_NODE_TGZ_SIZE%%!$html_node_db_tgz_size!g" \
|
||||
-e "s!%%DOCBOOK_ASCII_SIZE%%!$docbook_ascii_size!g" \
|
||||
-e "s!%%DOCBOOK_PS_GZ_SIZE%%!$docbook_ps_gz_size!g" \
|
||||
-e "s!%%DOCBOOK_PDF_SIZE%%!$docbook_pdf_size!g" \
|
||||
-e "s!%%DOCBOOK_XML_SIZE%%!$docbook_xml_size!g" \
|
||||
-e "s!%%DOCBOOK_XML_GZ_SIZE%%!$docbook_xml_gz_size!g" \
|
||||
-e "s,%%SCRIPTURL%%,$scripturl,g" \
|
||||
-e "s!%%SCRIPTNAME%%!$prog!g" \
|
||||
-e "$CONDS" \
|
||||
$GENDOCS_TEMPLATE_DIR/gendocs_template >$outdir/index.html
|
||||
|
||||
echo "Done, see $outdir/ subdirectory for new files."
|
||||
|
||||
# Local variables:
|
||||
# eval: (add-hook 'write-file-hooks 'time-stamp)
|
||||
# time-stamp-start: "scriptversion="
|
||||
# time-stamp-format: "%:y-%02m-%02d.%02H"
|
||||
# time-stamp-end: "$"
|
||||
# End:
|
|
@ -1,7 +1,9 @@
|
|||
#!/usr/bin/perl
|
||||
eval '(exit $?0)' && eval 'exec perl -wS "$0" ${1+"$@"}'
|
||||
& eval 'exec perl -wS "$0" $argv:q'
|
||||
if 0;
|
||||
# Convert git log output to ChangeLog format.
|
||||
|
||||
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
115
build-aux/gnu-web-doc-update
Executable file
|
@ -0,0 +1,115 @@
|
|||
#!/bin/sh
|
||||
# Run this after each non-alpha release, to update the web documentation at
|
||||
# http://www.gnu.org/software/$pkg/manual/
|
||||
# This script must be run from the top-level directory,
|
||||
# assumes you're using git for revision control,
|
||||
# and requires a .prev-version file as well as a Makefile,
|
||||
# from which it extracts the version number and package name, respectively.
|
||||
# Also, it assumes all documentation is in the doc/ sub-directory.
|
||||
|
||||
VERSION=2009-07-21.16; # UTC
|
||||
|
||||
# Copyright (C) 2009 Free Software Foundation, Inc.
|
||||
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
# Requirements: everything required to bootstrap your package,
|
||||
# plus these: git, cvs, cvsu, rsync, mktemp
|
||||
|
||||
ME=`basename "$0"`
|
||||
warn() { printf '%s: %s\n' "$ME" "$*" >&2; }
|
||||
die() { warn "$*"; exit 1; }
|
||||
|
||||
help_version()
|
||||
{
|
||||
case $1 in
|
||||
--help) cat <<EOF
|
||||
Usage: $ME
|
||||
|
||||
Run this script (no options or arguments) after each non-alpha release,
|
||||
to update the web documentation at http://www.gnu.org/software/\$pkg/manual/
|
||||
Run it from your project's the top-level directory.
|
||||
|
||||
Options:
|
||||
--help print this help, then exit
|
||||
--version print version number, then exit
|
||||
|
||||
Report bugs and patches to <bug-gnulib@gnu.org>.
|
||||
EOF
|
||||
exit ;;
|
||||
|
||||
--version)
|
||||
year=`echo "$VERSION" | sed 's/[^0-9].*//'`
|
||||
cat <<EOF
|
||||
$ME $VERSION
|
||||
Copyright (C) $year Free Software Foundation, Inc,
|
||||
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
|
||||
This is free software: you are free to change and redistribute it.
|
||||
There is NO WARRANTY, to the extent permitted by law.
|
||||
EOF
|
||||
exit ;;
|
||||
|
||||
*) die "unrecognized option: $1";;
|
||||
esac
|
||||
}
|
||||
|
||||
case $# in
|
||||
0) ;;
|
||||
1) help_version $1 ;;
|
||||
*) die "$ME: too many options" ;;
|
||||
esac
|
||||
|
||||
prev=.prev-version
|
||||
version=$(cat $prev) || die "$ME: no $prev file?"
|
||||
pkg=$(sed -n 's/^PACKAGE = \(.*\)/\1/p' Makefile) || die "$ME: no Makefile?"
|
||||
tmp_branch=web-doc-$version-$$
|
||||
|
||||
cleanup()
|
||||
{
|
||||
__st=$?;
|
||||
rm -rf "$tmp"
|
||||
git checkout master
|
||||
git branch -d $tmp_branch
|
||||
exit $__st
|
||||
}
|
||||
trap cleanup 0
|
||||
trap 'exit $?' 1 2 13 15
|
||||
|
||||
# We must build using sources for which --version reports the
|
||||
# just-released version number, not some string like 7.6.18-20761.
|
||||
# That version string propagates into all documentation.
|
||||
git checkout -b $tmp_branch v$version
|
||||
./bootstrap && ./configure && make && make web-manual
|
||||
|
||||
tmp=$(mktemp -d --tmpdir=. web-doc-update.XXXXXX) || exit 1
|
||||
( cd $tmp \
|
||||
&& cvs -d $USER@cvs.sv.gnu.org:/webcvs/$pkg co $pkg )
|
||||
rsync -avP doc/manual/ $tmp/$pkg/manual
|
||||
|
||||
(
|
||||
cd $tmp/$pkg/manual
|
||||
|
||||
# Add any new files:
|
||||
cvsu --types='?'|sed s/..// | xargs --no-run-if-empty -- cvs add -ko
|
||||
|
||||
cvs ci -m $version
|
||||
)
|
||||
|
||||
# Local variables:
|
||||
# eval: (add-hook 'write-file-hooks 'time-stamp)
|
||||
# time-stamp-start: "VERSION="
|
||||
# time-stamp-format: "%:y-%02m-%02d.%02H"
|
||||
# time-stamp-time-zone: "UTC"
|
||||
# time-stamp-end: "; # UTC"
|
||||
# End:
|
412
build-aux/gnupload
Executable file
412
build-aux/gnupload
Executable file
|
@ -0,0 +1,412 @@
|
|||
#!/bin/sh
|
||||
# Sign files and upload them.
|
||||
|
||||
scriptversion=2009-04-28.21; # UTC
|
||||
|
||||
# Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 3, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
# Originally written by Alexandre Duret-Lutz <adl@gnu.org>.
|
||||
|
||||
set -e
|
||||
|
||||
GPG='gpg --batch --no-tty'
|
||||
conffile=.gnuploadrc
|
||||
to=
|
||||
dry_run=false
|
||||
symlink_files=
|
||||
delete_files=
|
||||
delete_symlinks=
|
||||
collect_var=
|
||||
dbg=
|
||||
|
||||
usage="Usage: $0 [OPTIONS]... [COMMAND] FILES... [[COMMAND] FILES...]
|
||||
|
||||
Sign all FILES, and upload them to selected destinations, according to
|
||||
<http://www.gnu.org/prep/maintain/html_node/Automated-FTP-Uploads.html>.
|
||||
|
||||
Commands:
|
||||
--delete delete FILES from destination
|
||||
--symlink create symbolic links
|
||||
--rmsymlink remove symbolic links
|
||||
-- treat the remaining arguments as files to upload
|
||||
|
||||
Options:
|
||||
--help print this help text and exit
|
||||
--to DEST specify one destination for FILES
|
||||
(multiple --to options are allowed)
|
||||
--user NAME sign with key NAME
|
||||
--symlink-regex[=EXPR] use sed script EXPR to compute symbolic link names
|
||||
--dry-run do nothing, show what would have been done
|
||||
--version output version information and exit
|
||||
|
||||
If --symlink-regex is given without EXPR, then the link target name
|
||||
is created by replacing the version information with \`-latest', e.g.:
|
||||
|
||||
foo-1.3.4.tar.gz -> foo-latest.tar.gz
|
||||
|
||||
Recognized destinations are:
|
||||
alpha.gnu.org:DIRECTORY
|
||||
savannah.gnu.org:DIRECTORY
|
||||
savannah.nongnu.org:DIRECTORY
|
||||
ftp.gnu.org:DIRECTORY
|
||||
build directive files and upload files by FTP
|
||||
download.gnu.org.ua:{alpha|ftp}/DIRECTORY
|
||||
build directive files and upload files by SFTP
|
||||
[user@]host:DIRECTORY upload files with scp
|
||||
|
||||
Options and commands are applied in order. If the file $conffile exists
|
||||
in the current working directory, its contents are prepended to the
|
||||
actual command line options. Use this to keep your defaults. Comments
|
||||
(#) and empty lines in $conffile are allowed.
|
||||
|
||||
Examples:
|
||||
1. Upload automake-1.8.2b.tar.gz and automake-1.8.2b.tar.bz2 to two sites:
|
||||
gnupload --to sources.redhat.com:~ftp/pub/automake \\
|
||||
--to alpha.gnu.org:automake \\
|
||||
automake-1.8.2b.tar.gz automake-1.8.2b.tar.bz2
|
||||
|
||||
2. Same as above, but also create symbolic links to automake-latest.tar.*:
|
||||
gnupload --to sources.redhat.com:~ftp/pub/automake \\
|
||||
--to alpha.gnu.org:automake \\
|
||||
--symlink-regex \\
|
||||
automake-1.8.2b.tar.gz automake-1.8.2b.tar.bz2
|
||||
|
||||
3. Symlink automake-1.8.2b.tar.gz to automake-latest.tar.gz and
|
||||
automake-1.8.2b.tar.bz2 to automake-latest.tar.bz2 on both sites:
|
||||
|
||||
gnupload --to sources.redhat.com:~ftp/pub/automake \\
|
||||
--to alpha.gnu.org:automake \\
|
||||
--symlink automake-1.8.2b.tar.gz automake-latest.tar.gz \\
|
||||
automake-1.8.2b.tar.bz2 automake-latest.tar.bz2
|
||||
|
||||
4. Delete automake-1.8.2a.tar.gz and .bz2, remove symlink
|
||||
automake-latest.tar.gz and upload automake-1.8.2b.tar.gz:
|
||||
|
||||
gnupload --to sources.redhat.com:~ftp/pub/automake \\
|
||||
--to alpha.gnu.org:automake \\
|
||||
--delete automake-1.8.2a.tar.gz automake-1.8.2a.tar.bz2 \\
|
||||
--rmsymlink automake-latest.tar.gz \\
|
||||
-- \\
|
||||
automake-1.8.2b.tar.gz automake-1.8.2b.tar.bz2
|
||||
|
||||
Report bugs to <bug-automake@gnu.org>.
|
||||
Send patches to <automake-patches@gnu.org>."
|
||||
|
||||
# Read local configuration file
|
||||
if test -r "$conffile"; then
|
||||
echo "$0: Reading configuration file $conffile"
|
||||
eval set x "`sed 's/#.*$//;/^$/d' \"$conffile\" | tr '\012\015' ' '` \"\$@\""
|
||||
shift
|
||||
fi
|
||||
|
||||
while test -n "$1"; do
|
||||
case $1 in
|
||||
-*)
|
||||
collect_var=
|
||||
case $1 in
|
||||
--help)
|
||||
echo "$usage"
|
||||
exit $?
|
||||
;;
|
||||
--to)
|
||||
if test -z "$2"; then
|
||||
echo "$0: Missing argument for --to" 1>&2
|
||||
exit 1
|
||||
else
|
||||
to="$to $2"
|
||||
shift
|
||||
fi
|
||||
;;
|
||||
--user)
|
||||
if test -z "$2"; then
|
||||
echo "$0: Missing argument for --user" 1>&2
|
||||
exit 1
|
||||
else
|
||||
GPG="$GPG --local-user $2"
|
||||
shift
|
||||
fi
|
||||
;;
|
||||
--delete)
|
||||
collect_var=delete_files
|
||||
;;
|
||||
--rmsymlink)
|
||||
collect_var=delete_symlinks
|
||||
;;
|
||||
--symlink-regex=*)
|
||||
symlink_expr=`expr "$1" : '[^=]*=\(.*\)'`
|
||||
;;
|
||||
--symlink-regex)
|
||||
symlink_expr='s|-[0-9][0-9\.]*\(-[0-9][0-9]*\)\{0,1\}\.|-latest.|'
|
||||
;;
|
||||
--symlink)
|
||||
collect_var=symlink_files
|
||||
;;
|
||||
--dry-run|-n)
|
||||
dry_run=:
|
||||
;;
|
||||
--version)
|
||||
echo "gnupload $scriptversion"
|
||||
exit $?
|
||||
;;
|
||||
--)
|
||||
shift
|
||||
break
|
||||
;;
|
||||
-*)
|
||||
echo "$0: Unknown option \`$1', try \`$0 --help'" 1>&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
*)
|
||||
if test -z "$collect_var"; then
|
||||
break
|
||||
else
|
||||
eval "$collect_var=\"\$$collect_var $1\""
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
dprint()
|
||||
{
|
||||
echo "Running $*..."
|
||||
}
|
||||
|
||||
if $dry_run; then
|
||||
dbg=dprint
|
||||
fi
|
||||
|
||||
if test -z "$to"; then
|
||||
echo "$0: Missing destination sites" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if test -n "$symlink_files"; then
|
||||
x=`echo "$symlink_files" | sed 's/[^ ]//g;s/ //g'`
|
||||
if test -n "$x"; then
|
||||
echo "$0: Odd number of symlink arguments" >&2
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
if test $# = 0; then
|
||||
if test -z "${symlink_files}${delete_files}${delete_symlinks}"; then
|
||||
echo "$0: No file to upload" 1>&2
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
# Make sure all files exist. We don't want to ask
|
||||
# for the passphrase if the script will fail.
|
||||
for file
|
||||
do
|
||||
if test ! -f $file; then
|
||||
echo "$0: Cannot find \`$file'" 1>&2
|
||||
exit 1
|
||||
elif test -n "$symlink_expr"; then
|
||||
linkname=`echo $file | sed "$symlink_expr"`
|
||||
if test -z "$linkname"; then
|
||||
echo "$0: symlink expression produces empty results" >&2
|
||||
exit 1
|
||||
elif test "$linkname" = $file; then
|
||||
echo "$0: symlink expression does not alter file name" >&2
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
# Make sure passphrase is not exported in the environment.
|
||||
unset passphrase
|
||||
|
||||
# Reset PATH to be sure that echo is a built-in. We will later use
|
||||
# `echo $passphrase' to output the passphrase, so it is important that
|
||||
# it is a built-in (third-party programs tend to appear in `ps'
|
||||
# listings with their arguments...).
|
||||
# Remember this script runs with `set -e', so if echo is not built-in
|
||||
# it will exit now.
|
||||
PATH=/empty echo -n "Enter GPG passphrase: "
|
||||
stty -echo
|
||||
read -r passphrase
|
||||
stty echo
|
||||
echo
|
||||
|
||||
if test $# -ne 0; then
|
||||
for file
|
||||
do
|
||||
echo "Signing $file..."
|
||||
rm -f $file.sig
|
||||
echo "$passphrase" | $dbg $GPG --passphrase-fd 0 -ba -o $file.sig $file
|
||||
done
|
||||
fi
|
||||
|
||||
|
||||
# mkdirective DESTDIR BASE FILE STMT
|
||||
# Arguments: See upload, below
|
||||
mkdirective ()
|
||||
{
|
||||
stmt="$4"
|
||||
if test -n "$3"; then
|
||||
stmt="
|
||||
filename: $3$stmt"
|
||||
fi
|
||||
|
||||
cat >${2}.directive<<EOF
|
||||
version: 1.1
|
||||
directory: $1
|
||||
comment: gnupload v. $scriptversion$stmt
|
||||
EOF
|
||||
if $dry_run; then
|
||||
echo "File ${2}.directive:"
|
||||
cat ${2}.directive
|
||||
echo "File ${2}.directive:" | sed 's/./-/g'
|
||||
fi
|
||||
}
|
||||
|
||||
mksymlink ()
|
||||
{
|
||||
while test $# -ne 0
|
||||
do
|
||||
echo "symlink: $1 $2"
|
||||
shift
|
||||
shift
|
||||
done
|
||||
}
|
||||
|
||||
# upload DEST DESTDIR BASE FILE STMT FILES
|
||||
# Arguments:
|
||||
# DEST Destination site;
|
||||
# DESTDIR Destination directory;
|
||||
# BASE Base name for the directive file;
|
||||
# FILE Name of the file to distribute (may be empty);
|
||||
# STMT Additional statements for the directive file;
|
||||
# FILES List of files to upload.
|
||||
upload ()
|
||||
{
|
||||
dest=$1
|
||||
destdir=$2
|
||||
base=$3
|
||||
file=$4
|
||||
stmt=$5
|
||||
files=$6
|
||||
|
||||
rm -f $base.directive $base.directive.asc
|
||||
case $dest in
|
||||
alpha.gnu.org:*)
|
||||
mkdirective "$destdir" "$base" "$file" "$stmt"
|
||||
echo "$passphrase" | $dbg $GPG --passphrase-fd 0 --clearsign $base.directive
|
||||
$dbg ncftpput ftp-upload.gnu.org /incoming/alpha $files $base.directive.asc
|
||||
;;
|
||||
ftp.gnu.org:*)
|
||||
mkdirective "$destdir" "$base" "$file" "$stmt"
|
||||
echo "$passphrase" | $dbg $GPG --passphrase-fd 0 --clearsign $base.directive
|
||||
$dbg ncftpput ftp-upload.gnu.org /incoming/ftp $files $base.directive.asc
|
||||
;;
|
||||
savannah.gnu.org:*)
|
||||
if test -z "$files"; then
|
||||
echo "$0: warning: standalone directives not applicable for $dest" >&2
|
||||
fi
|
||||
$dbg ncftpput savannah.gnu.org /incoming/savannah/$destdir $files
|
||||
;;
|
||||
savannah.nongnu.org:*)
|
||||
if test -z "$files"; then
|
||||
echo "$0: warning: standalone directives not applicable for $dest" >&2
|
||||
fi
|
||||
$dbg ncftpput savannah.nongnu.org /incoming/savannah/$destdir $files
|
||||
;;
|
||||
download.gnu.org.ua:alpha/*|download.gnu.org.ua:ftp/*)
|
||||
destdir_p1=`echo "$destdir" | sed 's,^[^/]*/,,'`
|
||||
destdir_topdir=`echo "$destdir" | sed 's,/.*,,'`
|
||||
mkdirective "$destdir_p1" "$base" "$file" "$stmt"
|
||||
echo "$passphrase" | $dbg $GPG --passphrase-fd 0 --clearsign $base.directive
|
||||
for f in $files $base.directive.asc
|
||||
do
|
||||
echo put $f
|
||||
done | $dbg sftp -b - puszcza.gnu.org.ua:/incoming/$destdir_topdir
|
||||
;;
|
||||
/*)
|
||||
dest_host=`echo "$dest" | sed 's,:.*,,'`
|
||||
mkdirective "$destdir" "$base" "$file" "$stmt"
|
||||
echo "$passphrase" | $dbg $GPG --passphrase-fd 0 --clearsign $base.directive
|
||||
$dbg cp $files $base.directive.asc $dest_host
|
||||
;;
|
||||
*)
|
||||
if test -z "$files"; then
|
||||
echo "$0: warning: standalone directives not applicable for $dest" >&2
|
||||
fi
|
||||
$dbg scp $files $dest
|
||||
;;
|
||||
esac
|
||||
rm -f $base.directive $base.directive.asc
|
||||
}
|
||||
|
||||
#####
|
||||
# Process any standalone directives
|
||||
stmt=
|
||||
if test -n "$symlink_files"; then
|
||||
stmt="$stmt
|
||||
`mksymlink $symlink_files`"
|
||||
fi
|
||||
|
||||
for file in $delete_files
|
||||
do
|
||||
stmt="$stmt
|
||||
archive: $file"
|
||||
done
|
||||
|
||||
for file in $delete_symlinks
|
||||
do
|
||||
stmt="$stmt
|
||||
rmsymlink: $file"
|
||||
done
|
||||
|
||||
if test -n "$stmt"; then
|
||||
for dest in $to
|
||||
do
|
||||
destdir=`echo $dest | sed 's/[^:]*://'`
|
||||
upload "$dest" "$destdir" "`hostname`-$$" "" "$stmt"
|
||||
done
|
||||
fi
|
||||
|
||||
# Process actual uploads
|
||||
for dest in $to
|
||||
do
|
||||
for file
|
||||
do
|
||||
echo "Uploading $file to $dest..."
|
||||
stmt=
|
||||
files="$file $file.sig"
|
||||
destdir=`echo $dest | sed 's/[^:]*://'`
|
||||
if test -n "$symlink_expr"; then
|
||||
linkname=`echo $file | sed "$symlink_expr"`
|
||||
stmt="$stmt
|
||||
symlink: $file $linkname
|
||||
symlink: $file.sig $linkname.sig"
|
||||
fi
|
||||
upload "$dest" "$destdir" "$file" "$file" "$stmt" "$files"
|
||||
done
|
||||
done
|
||||
|
||||
exit 0
|
||||
|
||||
# Local variables:
|
||||
# eval: (add-hook 'write-file-hooks 'time-stamp)
|
||||
# time-stamp-start: "scriptversion="
|
||||
# time-stamp-format: "%:y-%02m-%02d.%02H"
|
||||
# time-stamp-time-zone: "UTC"
|
||||
# time-stamp-end: "; # UTC"
|
||||
# End:
|
209
build-aux/useless-if-before-free
Executable file
209
build-aux/useless-if-before-free
Executable file
|
@ -0,0 +1,209 @@
|
|||
eval '(exit $?0)' && eval 'exec perl -wST "$0" ${1+"$@"}'
|
||||
& eval 'exec perl -wST "$0" $argv:q'
|
||||
if 0;
|
||||
# Detect instances of "if (p) free (p);".
|
||||
# Likewise for "if (p != NULL) free (p);". And with braces.
|
||||
# Also detect "if (NULL != p) free (p);".
|
||||
# And with 0 in place of NULL.
|
||||
|
||||
my $VERSION = '2009-04-16 15:57'; # UTC
|
||||
# The definition above must lie within the first 8 lines in order
|
||||
# for the Emacs time-stamp write hook (at end) to update it.
|
||||
# If you change this file with Emacs, please let the write hook
|
||||
# do its job. Otherwise, update this string manually.
|
||||
|
||||
# Copyright (C) 2008, 2009 Free Software Foundation, Inc.
|
||||
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
# Written by Jim Meyering
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use Getopt::Long;
|
||||
|
||||
(my $ME = $0) =~ s|.*/||;
|
||||
|
||||
# use File::Coda; # http://meyering.net/code/Coda/
|
||||
END {
|
||||
defined fileno STDOUT or return;
|
||||
close STDOUT and return;
|
||||
warn "$ME: failed to close standard output: $!\n";
|
||||
$? ||= 1;
|
||||
}
|
||||
|
||||
sub usage ($)
|
||||
{
|
||||
my ($exit_code) = @_;
|
||||
my $STREAM = ($exit_code == 0 ? *STDOUT : *STDERR);
|
||||
if ($exit_code != 0)
|
||||
{
|
||||
print $STREAM "Try `$ME --help' for more information.\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
print $STREAM <<EOF;
|
||||
Usage: $ME [OPTIONS] FILE...
|
||||
|
||||
Detect any instance in FILE of a useless "if" test before a free call, e.g.,
|
||||
"if (p) free (p);". Any such test may be safely removed without affecting
|
||||
the semantics of the C code in FILE. Use --name=FOO --name=BAR to also
|
||||
detect free-like functions named FOO and BAR.
|
||||
|
||||
OPTIONS:
|
||||
|
||||
--list print only the name of each matching FILE (\0-terminated)
|
||||
--name=N add name N to the list of \`free\'-like functions to detect;
|
||||
may be repeated
|
||||
|
||||
--help display this help and exit
|
||||
--version output version information and exit
|
||||
|
||||
Exit status:
|
||||
|
||||
0 one or more matches
|
||||
1 no match
|
||||
2 an error
|
||||
|
||||
EXAMPLE:
|
||||
|
||||
For example, this command prints all removable "if" tests before "free"
|
||||
and "kfree" calls in the linux kernel sources:
|
||||
|
||||
git ls-files -z |xargs -0 $ME --name=kfree
|
||||
|
||||
EOF
|
||||
}
|
||||
exit $exit_code;
|
||||
}
|
||||
|
||||
sub is_NULL ($)
|
||||
{
|
||||
my ($expr) = @_;
|
||||
return ($expr eq 'NULL' || $expr eq '0');
|
||||
}
|
||||
|
||||
{
|
||||
sub EXIT_MATCH {0}
|
||||
sub EXIT_NO_MATCH {1}
|
||||
sub EXIT_ERROR {2}
|
||||
my $err = EXIT_NO_MATCH;
|
||||
|
||||
my $list;
|
||||
my @name = qw(free);
|
||||
GetOptions
|
||||
(
|
||||
help => sub { usage 0 },
|
||||
version => sub { print "$ME version $VERSION\n"; exit },
|
||||
list => \$list,
|
||||
'name=s@' => \@name,
|
||||
) or usage 1;
|
||||
|
||||
# Make sure we have the right number of non-option arguments.
|
||||
# Always tell the user why we fail.
|
||||
@ARGV < 1
|
||||
and (warn "$ME: missing FILE argument\n"), usage EXIT_ERROR;
|
||||
|
||||
my $or = join '|', @name;
|
||||
my $regexp = qr/(?:$or)/;
|
||||
|
||||
# Set the input record separator.
|
||||
# Note: this makes it impractical to print line numbers.
|
||||
$/ = '"';
|
||||
|
||||
my $found_match = 0;
|
||||
FILE:
|
||||
foreach my $file (@ARGV)
|
||||
{
|
||||
open FH, '<', $file
|
||||
or (warn "$ME: can't open `$file' for reading: $!\n"),
|
||||
$err = EXIT_ERROR, next;
|
||||
while (defined (my $line = <FH>))
|
||||
{
|
||||
while ($line =~
|
||||
/\b(if\s*\(\s*([^)]+?)(?:\s*!=\s*([^)]+?))?\s*\)
|
||||
# 1 2 3
|
||||
(?: \s*$regexp\s*\((?:\s*\([^)]+\))?\s*([^)]+)\)|
|
||||
\s*\{\s*$regexp\s*\((?:\s*\([^)]+\))?\s*([^)]+)\)\s*;\s*\}))/sxg)
|
||||
{
|
||||
my $all = $1;
|
||||
my ($lhs, $rhs) = ($2, $3);
|
||||
my ($free_opnd, $braced_free_opnd) = ($4, $5);
|
||||
my $non_NULL;
|
||||
if (!defined $rhs) { $non_NULL = $lhs }
|
||||
elsif (is_NULL $rhs) { $non_NULL = $lhs }
|
||||
elsif (is_NULL $lhs) { $non_NULL = $rhs }
|
||||
else { next }
|
||||
|
||||
# Compare the non-NULL part of the "if" expression and the
|
||||
# free'd expression, without regard to white space.
|
||||
$non_NULL =~ tr/ \t//d;
|
||||
my $e2 = defined $free_opnd ? $free_opnd : $braced_free_opnd;
|
||||
$e2 =~ tr/ \t//d;
|
||||
if ($non_NULL eq $e2)
|
||||
{
|
||||
$found_match = 1;
|
||||
$list
|
||||
and (print "$file\0"), next FILE;
|
||||
print "$file: $all\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
continue
|
||||
{
|
||||
close FH;
|
||||
}
|
||||
|
||||
$found_match && $err == EXIT_NO_MATCH
|
||||
and $err = EXIT_MATCH;
|
||||
|
||||
exit $err;
|
||||
}
|
||||
|
||||
my $foo = <<'EOF';
|
||||
# The above is to *find* them.
|
||||
# This adjusts them, removing the unnecessary "if (p)" part.
|
||||
|
||||
# FIXME: do something like this as an option (doesn't do braces):
|
||||
free=xfree
|
||||
git grep -l -z "$free *(" \
|
||||
| xargs -0 useless-if-before-free -l --name="$free" \
|
||||
| xargs -0 perl -0x3b -pi -e \
|
||||
's/\bif\s*\(\s*(\S+?)(?:\s*!=\s*(?:0|NULL))?\s*\)\s+('"$free"'\s*\((?:\s*\([^)]+\))?\s*\1\s*\))/$2/s'
|
||||
|
||||
# Use the following to remove redundant uses of kfree inside braces.
|
||||
# Note that -0777 puts perl in slurp-whole-file mode;
|
||||
# but we have plenty of memory, these days...
|
||||
free=kfree
|
||||
git grep -l -z "$free *(" \
|
||||
| xargs -0 useless-if-before-free -l --name="$free" \
|
||||
| xargs -0 perl -0777 -pi -e \
|
||||
's/\bif\s*\(\s*(\S+?)(?:\s*!=\s*(?:0|NULL))?\s*\)\s*\{\s*('"$free"'\s*\((?:\s*\([^)]+\))?\s*\1\s*\);)\s*\}[^\n]*$/$2/gms'
|
||||
|
||||
Be careful that the result of the above transformation is valid.
|
||||
If the matched string is followed by "else", then obviously, it won't be.
|
||||
|
||||
When modifying files, refuse to process anything other than a regular file.
|
||||
EOF
|
||||
|
||||
## Local Variables:
|
||||
## mode: perl
|
||||
## indent-tabs-mode: nil
|
||||
## eval: (add-hook 'write-file-hooks 'time-stamp)
|
||||
## time-stamp-start: "my $VERSION = '"
|
||||
## time-stamp-format: "%:y-%02m-%02d %02H:%02M"
|
||||
## time-stamp-time-zone: "UTC"
|
||||
## time-stamp-end: "'; # UTC"
|
||||
## End:
|
116
build-aux/vc-list-files
Executable file
116
build-aux/vc-list-files
Executable file
|
@ -0,0 +1,116 @@
|
|||
#!/bin/sh
|
||||
# List version-controlled file names.
|
||||
|
||||
# Print a version string.
|
||||
scriptversion=2009-07-21.16; # UTC
|
||||
|
||||
# Copyright (C) 2006-2009 Free Software Foundation, Inc.
|
||||
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
# List the specified version-controlled files.
|
||||
# With no argument, list them all. With a single DIRECTORY argument,
|
||||
# list the version-controlled files in that directory.
|
||||
|
||||
# If there's an argument, it must be a single, "."-relative directory name.
|
||||
# cvsu is part of the cvsutils package: http://www.red-bean.com/cvsutils/
|
||||
|
||||
postprocess=
|
||||
case $1 in
|
||||
--help) cat <<EOF
|
||||
Usage: $0 [-C SRCDIR] [DIR]
|
||||
|
||||
Output a list of version-controlled files in DIR (default .), relative to
|
||||
SRCDIR (default .). SRCDIR must be the top directory of a checkout.
|
||||
|
||||
Options:
|
||||
--help print this help, then exit
|
||||
--version print version number, then exit
|
||||
-C SRCDIR change directory to SRCDIR before generating list
|
||||
|
||||
Report bugs and patches to <bug-gnulib@gnu.org>.
|
||||
EOF
|
||||
exit ;;
|
||||
|
||||
--version)
|
||||
year=`echo "$scriptversion" | sed 's/[^0-9].*//'`
|
||||
cat <<EOF
|
||||
vc-list-files $scriptversion
|
||||
Copyright (C) $year Free Software Foundation, Inc,
|
||||
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
|
||||
This is free software: you are free to change and redistribute it.
|
||||
There is NO WARRANTY, to the extent permitted by law.
|
||||
EOF
|
||||
exit ;;
|
||||
|
||||
-C)
|
||||
test "$2" = . || postprocess="| sed 's|^|$2/|'"
|
||||
cd "$2" || exit 1
|
||||
shift; shift ;;
|
||||
esac
|
||||
|
||||
dir=
|
||||
case $# in
|
||||
0) ;;
|
||||
1) dir=$1 ;;
|
||||
*) echo "$0: too many arguments" 1>&2
|
||||
echo "Usage: $0 [-C srcdir] [DIR]" 1>&2; exit 1;;
|
||||
esac
|
||||
|
||||
test "x$dir" = x && dir=.
|
||||
|
||||
if test -d .git; then
|
||||
test "x$dir" = x. \
|
||||
&& dir= sed_esc= \
|
||||
|| { dir="$dir/"; sed_esc=`echo "$dir"|env sed 's,\([\\/]\),\\\\\1,g'`; }
|
||||
# Ignore git symlinks - either they point into the tree, in which case
|
||||
# we don't need to visit the target twice, or they point somewhere
|
||||
# else (often into a submodule), in which case the content does not
|
||||
# belong to this package.
|
||||
eval exec git ls-tree -r 'HEAD:"$dir"' \
|
||||
\| sed -n '"s/^100[^ ]*./$sed_esc/p"' $postprocess
|
||||
elif test -d .hg; then
|
||||
eval exec hg locate '"$dir/*"' $postprocess
|
||||
elif test -d .bzr; then
|
||||
test "$postprocess" = '' && postprocess="| sed 's|^\./||'"
|
||||
eval exec bzr ls --versioned '"$dir"' $postprocess
|
||||
elif test -d CVS; then
|
||||
test "$postprocess" = '' && postprocess="| sed 's|^\./||'"
|
||||
if test -x build-aux/cvsu; then
|
||||
eval build-aux/cvsu --find --types=AFGM '"$dir"' $postprocess
|
||||
elif (cvsu --help) >/dev/null 2>&1; then
|
||||
eval cvsu --find --types=AFGM '"$dir"' $postprocess
|
||||
else
|
||||
eval awk -F/ \''{ \
|
||||
if (!$1 && $3 !~ /^-/) { \
|
||||
f=FILENAME; \
|
||||
if (f ~ /CVS\/Entries$/) \
|
||||
f = substr(f, 1, length(f)-11); \
|
||||
print f $2; \
|
||||
}}'\'' \
|
||||
`find "$dir" -name Entries -print` /dev/null' $postprocess
|
||||
fi
|
||||
else
|
||||
echo "$0: Failed to determine type of version control used in `pwd`" 1>&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Local variables:
|
||||
# eval: (add-hook 'write-file-hooks 'time-stamp)
|
||||
# time-stamp-start: "scriptversion="
|
||||
# time-stamp-format: "%:y-%02m-%02d.%02H"
|
||||
# time-stamp-time-zone: "UTC"
|
||||
# time-stamp-end: "; # UTC"
|
||||
# End:
|
1
cfg.mk
Normal file
1
cfg.mk
Normal file
|
@ -0,0 +1 @@
|
|||
old_NEWS_hash = d41d8cd98f00b204e9800998ecf8427e
|
164
configure.ac
164
configure.ac
|
@ -32,8 +32,7 @@ dnl "echo -n" since -n is not portable (see autoconf manual "Limitations of
|
|||
dnl Builtins"), in particular on solaris it results in a literal "-n" in
|
||||
dnl 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
96
doc/gendocs_template
Normal file
|
@ -0,0 +1,96 @@
|
|||
<!--#include virtual="/server/header.html" -->
|
||||
<title>%%TITLE%% - GNU Project - Free Software Foundation (FSF)</title>
|
||||
<!--#include virtual="/server/banner.html" -->
|
||||
<h2>%%TITLE%%</h2>
|
||||
|
||||
<!-- This document is in XML, and xhtml 1.0 -->
|
||||
<!-- Please make sure to properly nest your tags -->
|
||||
<!-- and ensure that your final document validates -->
|
||||
<!-- consistent with W3C xhtml 1.0 and CSS standards -->
|
||||
<!-- See validator.w3.org -->
|
||||
|
||||
<address>Free Software Foundation</address>
|
||||
<address>last updated %%DATE%%</address>
|
||||
|
||||
<p>This manual (%%PACKAGE%%) is available in the following formats:</p>
|
||||
|
||||
<ul>
|
||||
<li><a href="%%PACKAGE%%.html">HTML
|
||||
(%%HTML_MONO_SIZE%%K bytes)</a> - entirely on one web page.</li>
|
||||
<li><a href="html_node/index.html">HTML</a> - with one web page per
|
||||
node.</li>
|
||||
%%IF HTML_SECTION%%
|
||||
<li><a href="html_section/index.html">HTML</a> - with one web page per
|
||||
section.</li>
|
||||
%%ENDIF HTML_SECTION%%
|
||||
%%IF HTML_CHAPTER%%
|
||||
<li><a href="html_chapter/index.html">HTML</a> - with one web page per
|
||||
chapter.</li>
|
||||
%%ENDIF HTML_CHAPTER%%
|
||||
<li><a href="%%PACKAGE%%.html.gz">HTML compressed
|
||||
(%%HTML_MONO_GZ_SIZE%%K gzipped characters)</a> - entirely on
|
||||
one web page.</li>
|
||||
<li><a href="%%PACKAGE%%.html_node.tar.gz">HTML compressed
|
||||
(%%HTML_NODE_TGZ_SIZE%%K gzipped tar file)</a> -
|
||||
with one web page per node.</li>
|
||||
%%IF HTML_SECTION%%
|
||||
<li><a href="%%PACKAGE%%.html_section.tar.gz">HTML compressed
|
||||
(%%HTML_SECTION_TGZ_SIZE%%K gzipped tar file)</a> -
|
||||
with one web page per section.</li>
|
||||
%%ENDIF HTML_SECTION%%
|
||||
%%IF HTML_CHAPTER%%
|
||||
<li><a href="%%PACKAGE%%.html_chapter.tar.gz">HTML compressed
|
||||
(%%HTML_CHAPTER_TGZ_SIZE%%K gzipped tar file)</a> -
|
||||
with one web page per chapter.</li>
|
||||
%%ENDIF HTML_CHAPTER%%
|
||||
<li><a href="%%PACKAGE%%.info.tar.gz">Info document
|
||||
(%%INFO_TGZ_SIZE%%K bytes gzipped tar file)</a>.</li>
|
||||
<li><a href="%%PACKAGE%%.txt">ASCII text
|
||||
(%%ASCII_SIZE%%K bytes)</a>.</li>
|
||||
<li><a href="%%PACKAGE%%.txt.gz">ASCII text compressed
|
||||
(%%ASCII_GZ_SIZE%%K bytes gzipped)</a>.</li>
|
||||
<li><a href="%%PACKAGE%%.dvi.gz">TeX dvi file
|
||||
(%%DVI_GZ_SIZE%%K bytes gzipped)</a>.</li>
|
||||
<li><a href="%%PACKAGE%%.ps.gz">PostScript file
|
||||
(%%PS_GZ_SIZE%%K bytes gzipped)</a>.</li>
|
||||
<li><a href="%%PACKAGE%%.pdf">PDF file
|
||||
(%%PDF_SIZE%%K bytes)</a>.</li>
|
||||
<li><a href="%%PACKAGE%%.texi.tar.gz">Texinfo source
|
||||
(%%TEXI_TGZ_SIZE%%K bytes gzipped tar file).</a></li>
|
||||
</ul>
|
||||
|
||||
<p>You can <a href="http://shop.fsf.org/">buy printed copies of
|
||||
some manuals</a> (among other items) from the Free Software Foundation;
|
||||
this helps support FSF activities.</p>
|
||||
|
||||
<p>(This page generated by the <a href="%%SCRIPTURL%%">%%SCRIPTNAME%%
|
||||
script</a>.)</p>
|
||||
|
||||
<!-- If needed, change the copyright block at the bottom. In general, -->
|
||||
<!-- all pages on the GNU web server should have the section about -->
|
||||
<!-- verbatim copying. Please do NOT remove this without talking -->
|
||||
<!-- with the webmasters first. -->
|
||||
<!-- Please make sure the copyright date is consistent with the document -->
|
||||
<!-- and that it is like this "2001, 2002" not this "2001-2002." -->
|
||||
</div><!-- for id="content", starts in the include above -->
|
||||
<!--#include virtual="/server/footer.html" -->
|
||||
<div id="footer">
|
||||
|
||||
<p>
|
||||
Please send FSF & GNU inquiries to
|
||||
<a href="mailto:gnu@gnu.org"><gnu@gnu.org></a>.
|
||||
There are also <a href="/contact/">other ways to contact</a>
|
||||
the FSF.<br />
|
||||
Please send broken links and other corrections or suggestions to
|
||||
<a href="mailto:%%EMAIL%%"><%%EMAIL%%></a>.
|
||||
</p>
|
||||
|
||||
<p>Copyright © 2009 Free Software Foundation, Inc.</p>
|
||||
|
||||
<p>Verbatim copying and distribution of this entire article is
|
||||
permitted in any medium, provided this notice is preserved.</p>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
|
@ -1750,22 +1750,6 @@ current interfaces. If a file cannot be opened with the access
|
|||
requested, @code{open-file} throws an exception.
|
||||
@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
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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}.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
225
emacs/gds-faq.txt
Executable file
|
@ -0,0 +1,225 @@
|
|||
|
||||
* Installation
|
||||
|
||||
** How do I install guile-debugging?
|
||||
|
||||
After unpacking the .tar.gz file, run the usual sequence of commands:
|
||||
|
||||
$ ./configure
|
||||
$ make
|
||||
$ sudo make install
|
||||
|
||||
Then you need to make sure that the directory where guile-debugging's
|
||||
Scheme files were installed is included in your Guile's load path.
|
||||
(The sequence above will usually install guile-debugging under
|
||||
/usr/local, and /usr/local is not in Guile's load path by default,
|
||||
unless Guile itself was installed under /usr/local.) You can discover
|
||||
your Guile's default load path by typing
|
||||
|
||||
$ guile -q -c '(begin (write %load-path) (newline))'
|
||||
|
||||
There are two ways to add guile-debugging's installation directory to
|
||||
Guile's load path, if it isn't already there.
|
||||
|
||||
1. Edit or create the `init.scm' file, which Guile reads on startup,
|
||||
so that it includes a line like this:
|
||||
|
||||
(set! %load-path (cons "/usr/local/share/guile" %load-path))
|
||||
|
||||
but with "/usr/local" replaced by the prefix that you installed
|
||||
guile-debugging under, if not /usr/local.
|
||||
|
||||
The init.scm file must be installed (if it does not already exist
|
||||
there) in one of the directories in Guile's default load-path.
|
||||
|
||||
2. Add this line to your .emacs file:
|
||||
|
||||
(setq gds-scheme-directory "/usr/local/share/guile")
|
||||
|
||||
before the `require' or `load' line that loads GDS, but with
|
||||
"/usr/local" replaced by the prefix that you installed
|
||||
guile-debugging under, if not /usr/local.
|
||||
|
||||
Finally, if you want guile-debugging's GDS interface to be loaded
|
||||
automatically whenever you run Emacs, add this line to your .emacs:
|
||||
|
||||
(require 'gds)
|
||||
|
||||
* Troubleshooting
|
||||
|
||||
** "error in process filter" when starting Emacs (or loading GDS)
|
||||
|
||||
This is caused by an internal error in GDS's Scheme code, for which a
|
||||
backtrace will have appeared in the gds-debug buffer, so please switch
|
||||
to the gds-debug buffer and see what it says there.
|
||||
|
||||
The most common cause is a load path problem: Guile cannot find GDS's
|
||||
Scheme code because it is not in the known load path. In this case
|
||||
you should see the error message "no code for module" somewhere in the
|
||||
backtrace. If you see this, please try the remedies described in `How
|
||||
do I install guile-debugging?' above, then restart Emacs and see if
|
||||
the problem has been cured.
|
||||
|
||||
If you don't see "no code for module", or if the described remedies
|
||||
don't fix the problem, please send the contents of the gds-debug
|
||||
buffer to me at <neil@ossau.uklinux.net>, so I can debug the problem.
|
||||
|
||||
If you don't see a backtrace at all in the gds-debug buffer, try the
|
||||
next item ...
|
||||
|
||||
** "error in process filter" at some other time
|
||||
|
||||
This is caused by an internal error somewhere in GDS's Emacs Lisp
|
||||
code. If possible, please
|
||||
|
||||
- switch on the `debug-on-error' option (M-x set-variable RET
|
||||
debug-on-error RET t RET)
|
||||
|
||||
- do whatever you were doing so that the same error happens again
|
||||
|
||||
- send the Emacs Lisp stack trace which pops up to me at
|
||||
<neil@ossau.uklinux.net>.
|
||||
|
||||
If that doesn't work, please just mail me with as much detail as
|
||||
possible of what you were doing when the error occurred.
|
||||
|
||||
* GDS Features
|
||||
|
||||
** How do I inspect variable values?
|
||||
|
||||
Type `e' followed by the name of the variable, then <RET>. This
|
||||
works whenever GDS is displaying a stack for an error at at a
|
||||
breakpoint. (You can actually `e' to evaluate any expression in the
|
||||
local environment of the selected stack frame; inspecting variables is
|
||||
the special case of this where the expression is only a variable name.)
|
||||
|
||||
If GDS is displaying the associated source code in the window above or
|
||||
below the stack, you can see the values of any variables in the
|
||||
highlighted code just by hovering your mouse over them.
|
||||
|
||||
** How do I change a variable's value?
|
||||
|
||||
Type `e' and then `(set! VARNAME NEWVAL)', where VARNAME is the name
|
||||
of the variable you want to set and NEWVAL is an expression which
|
||||
Guile can evaluate to get the new value. This works whenever GDS is
|
||||
displaying a stack for an error at at a breakpoint. The setting will
|
||||
take effect in the local environment of the selected stack frame.
|
||||
|
||||
** How do I change the expression that Guile is about to evaluate?
|
||||
|
||||
Type `t' followed by the expression that you want Guile to evaluate
|
||||
instead, then <RET>.
|
||||
|
||||
Then type one of the commands that tells Guile to continue execution.
|
||||
|
||||
(Tweaking expressions, as described here, is only supported by the
|
||||
latest CVS version of Guile. The GDS stack display tells you when
|
||||
tweaking is possible by adding "(tweakable)" to the first line of the
|
||||
stack window.)
|
||||
|
||||
** How do I return a value from the current stack frame different to what the evaluator has calculated?
|
||||
|
||||
You have to be at the normal exit of the relevant frame first, so if
|
||||
GDS is not already showing you the normally calculated return value,
|
||||
type `o' to finish the evaluation of the selected frame.
|
||||
|
||||
Then type `t' followed by the value you want to return, and <RET>.
|
||||
The value that you type can be any expression, but note that it will
|
||||
not be evaluated before being returned; for example if you type `(+ 2
|
||||
3)', the return value will be a three-element list, not 5.
|
||||
|
||||
Finally type one of the commands that tells Guile to continue
|
||||
execution.
|
||||
|
||||
(Tweaking return values, as described here, is only supported by the
|
||||
latest CVS version of Guile. The GDS stack display tells you when
|
||||
tweaking is possible by adding "(tweakable)" to the first line of the
|
||||
stack window.)
|
||||
|
||||
** How do I step over a line of code?
|
||||
|
||||
Scheme isn't organized by lines, so it doesn't really make sense to
|
||||
think of stepping over lines. Instead please see the next entry on
|
||||
stepping over expressions.
|
||||
|
||||
** How do I step over an expression?
|
||||
|
||||
It depends what you mean by "step over". If you mean that you want
|
||||
Guile to evaluate that expression normally, but then show you its
|
||||
return value, type `o', which does exactly that.
|
||||
|
||||
If you mean that you want to skip the evaluation of that expression
|
||||
(for example because it has side effects that you don't want to
|
||||
happen), use `t' to change the expression to something else which
|
||||
Guile will evaluate instead.
|
||||
|
||||
There has to be a substitute expression so Guile can calculate a value
|
||||
to return to the calling frame. If you know at a particular point
|
||||
that the return value is not important, you can type `t #f <RET>' or
|
||||
`t 0 <RET>'.
|
||||
|
||||
See `How do I change the expression that Guile is about to evaluate?'
|
||||
above for more on using `t'.
|
||||
|
||||
** How do I move up and down the call stack?
|
||||
|
||||
Type `u' to move up and `d' to move down. "Up" in GDS means to a more
|
||||
"inner" frame, and "down" means to a more "outer" frame.
|
||||
|
||||
** How do I run until the next breakpoint?
|
||||
|
||||
Type `g' (for "go").
|
||||
|
||||
** How do I run until the end of the selected stack frame?
|
||||
|
||||
Type `o'.
|
||||
|
||||
** How do I set a breakpoint?
|
||||
|
||||
First identify the code that you want to set the breakpoint in, and
|
||||
what kind of breakpoint you want. To set a breakpoint on entry to a
|
||||
top level procedure, move the cursor to anywhere in the procedure
|
||||
definition, and make sure that the region/mark is inactive. To set a
|
||||
breakpoint on a particular expression (or sequence of expressions) set
|
||||
point and mark so that the region covers the opening parentheses of
|
||||
all the target expressions.
|
||||
|
||||
Then type ...
|
||||
|
||||
`C-c C-b d' for a `debug' breakpoint, which means that GDS will
|
||||
display the stack when the breakpoint is hit
|
||||
|
||||
`C-c C-b t' for a `trace' breakpoint, which means that the start and
|
||||
end of the relevant procedure or expression(s) will be traced to the
|
||||
*GDS Trace* buffer
|
||||
|
||||
`C-c C-b T' for a `trace-subtree' breakpoint, which means that every
|
||||
evaluation step involved in the evaluation of the relevant procedure
|
||||
or expression(s) will be traced to the *GDS Trace* buffer.
|
||||
|
||||
You can also type `C-x <SPC>', which does the same as one of the
|
||||
above, depending on the value of `gds-default-breakpoint-type'.
|
||||
|
||||
** How do I clear a breakpoint?
|
||||
|
||||
Select a region containing the breakpoints that you want to clear, and
|
||||
type `C-c C-b <DEL>'.
|
||||
|
||||
** How do I trace calls to a particular procedure or evaluations of a particular expression?
|
||||
|
||||
In GDS this means setting a breakpoint whose type is `trace' or
|
||||
`trace-subtree'. See `How do I set a breakpoint?' above.
|
||||
|
||||
* Development
|
||||
|
||||
** How can I follow or contribute to guile-debugging's development?
|
||||
|
||||
guile-debugging is hosted at http://gna.org, so please see the project
|
||||
page there. Feel free to raise bugs, tasks containing patches or
|
||||
feature requests, and so on. You can also write directly to me by
|
||||
email: <neil@ossau.uklinux.net>.
|
||||
|
||||
|
||||
Local Variables:
|
||||
mode: outline
|
||||
End:
|
|
@ -206,23 +206,28 @@ Emacs to display an error or trap so that the user can debug it."
|
|||
"-q"
|
||||
"--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)
|
||||
|
|
|
@ -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
166
emacs/gds-test.el
Normal file
|
@ -0,0 +1,166 @@
|
|||
|
||||
;; Test utility code.
|
||||
(defun gds-test-execute-keys (keys &optional keys2)
|
||||
(execute-kbd-macro (apply 'vector (listify-key-sequence keys))))
|
||||
|
||||
(defvar gds-test-expecting nil)
|
||||
|
||||
(defun gds-test-protocol-hook (form)
|
||||
(message "[protocol: %s]" (car form))
|
||||
(if (eq (car form) gds-test-expecting)
|
||||
(setq gds-test-expecting nil)))
|
||||
|
||||
(defun gds-test-expect-protocol (proc &optional timeout)
|
||||
(message "[expect: %s]" proc)
|
||||
(setq gds-test-expecting proc)
|
||||
(while gds-test-expecting
|
||||
(or (accept-process-output gds-debug-server (or timeout 5))
|
||||
(error "Timed out after %ds waiting for %s" (or timeout 5) proc))))
|
||||
|
||||
(defun gds-test-check-buffer (name &rest strings)
|
||||
(let ((buf (or (get-buffer name) (error "No %s buffer" name))))
|
||||
(save-excursion
|
||||
(set-buffer buf)
|
||||
(goto-char (point-min))
|
||||
(while strings
|
||||
(search-forward (car strings))
|
||||
(setq strings (cdr strings))))))
|
||||
|
||||
(defun TEST (desc)
|
||||
(message "TEST: %s" desc))
|
||||
|
||||
;; Make sure we take GDS elisp code from this code tree.
|
||||
(setq load-path (cons (concat default-directory "emacs/") load-path))
|
||||
|
||||
;; Protect the tests so we can do some cleanups in case of error.
|
||||
(unwind-protect
|
||||
(progn
|
||||
|
||||
;; Visit the tutorial.
|
||||
(find-file "gds-tutorial.txt")
|
||||
|
||||
(TEST "Load up GDS.")
|
||||
(search-forward "(require 'gds)")
|
||||
(setq load-path (cons (concat default-directory "emacs/") load-path))
|
||||
(gds-test-execute-keys "\C-x\C-e")
|
||||
|
||||
;; Install our testing hook.
|
||||
(add-hook 'gds-protocol-hook 'gds-test-protocol-hook)
|
||||
|
||||
(TEST "Help.")
|
||||
(search-forward "(list-ref")
|
||||
(backward-char 2)
|
||||
(gds-test-execute-keys "\C-hg\C-m")
|
||||
(gds-test-expect-protocol 'eval-results 10)
|
||||
(gds-test-check-buffer "*Guile Help*"
|
||||
"help list-ref"
|
||||
"is a primitive procedure in the (guile) module")
|
||||
|
||||
(TEST "Completion.")
|
||||
(re-search-forward "^with-output-to-s")
|
||||
(gds-test-execute-keys "\e\C-i")
|
||||
(beginning-of-line)
|
||||
(or (looking-at "with-output-to-string")
|
||||
(error "Expected completion `with-output-to-string' failed"))
|
||||
|
||||
(TEST "Eval defun.")
|
||||
(search-forward "(display z)")
|
||||
(gds-test-execute-keys "\e\C-x")
|
||||
(gds-test-expect-protocol 'eval-results)
|
||||
(gds-test-check-buffer "*Guile Evaluation*"
|
||||
"(let ((x 1) (y 2))"
|
||||
"Arctangent is: 0.46"
|
||||
"=> 0.46")
|
||||
|
||||
(TEST "Multiple values.")
|
||||
(search-forward "(values 'a ")
|
||||
(gds-test-execute-keys "\e\C-x")
|
||||
(gds-test-expect-protocol 'eval-results)
|
||||
(gds-test-check-buffer "*Guile Evaluation*"
|
||||
"(values 'a"
|
||||
"hello world"
|
||||
"=> a"
|
||||
"=> b"
|
||||
"=> c")
|
||||
|
||||
(TEST "Eval region with multiple expressions.")
|
||||
(search-forward "(display \"Arctangent is: \")")
|
||||
(beginning-of-line)
|
||||
(push-mark nil nil t)
|
||||
(forward-line 3)
|
||||
(gds-test-execute-keys "\C-c\C-r")
|
||||
(gds-test-expect-protocol 'eval-results)
|
||||
(gds-test-check-buffer "*Guile Evaluation*"
|
||||
"(display \"Arctangent is"
|
||||
"Arctangent is:"
|
||||
"=> no (or unspecified) value"
|
||||
"ERROR: Unbound variable: z"
|
||||
"=> error-in-evaluation"
|
||||
"Evaluating expression 3"
|
||||
"=> no (or unspecified) value")
|
||||
|
||||
(TEST "Eval syntactically unbalanced region.")
|
||||
(search-forward "(let ((z (atan x y)))")
|
||||
(beginning-of-line)
|
||||
(push-mark nil nil t)
|
||||
(forward-line 4)
|
||||
(gds-test-execute-keys "\C-c\C-r")
|
||||
(gds-test-expect-protocol 'eval-results)
|
||||
(gds-test-check-buffer "*Guile Evaluation*"
|
||||
"(let ((z (atan"
|
||||
"Reading expressions to evaluate"
|
||||
"ERROR"
|
||||
"end of file"
|
||||
"=> error-in-read")
|
||||
|
||||
(TEST "Stepping through an evaluation.")
|
||||
(search-forward "(for-each (lambda (x)")
|
||||
(forward-line 1)
|
||||
(push-mark nil nil t)
|
||||
(forward-line 1)
|
||||
(gds-test-execute-keys "\C-u\e\C-x")
|
||||
(gds-test-expect-protocol 'stack)
|
||||
(gds-test-execute-keys " ")
|
||||
(gds-test-expect-protocol 'stack)
|
||||
(gds-test-execute-keys "o")
|
||||
(gds-test-expect-protocol 'stack)
|
||||
(gds-test-execute-keys "o")
|
||||
(gds-test-expect-protocol 'stack)
|
||||
(gds-test-execute-keys "o")
|
||||
(gds-test-expect-protocol 'stack)
|
||||
(gds-test-execute-keys "o")
|
||||
(gds-test-expect-protocol 'stack)
|
||||
(gds-test-execute-keys "o")
|
||||
(gds-test-expect-protocol 'stack)
|
||||
(gds-test-execute-keys "o")
|
||||
(gds-test-expect-protocol 'stack)
|
||||
(gds-test-execute-keys "o")
|
||||
(gds-test-expect-protocol 'stack)
|
||||
(gds-test-execute-keys "o")
|
||||
(gds-test-expect-protocol 'stack)
|
||||
(gds-test-execute-keys "o")
|
||||
(gds-test-expect-protocol 'stack)
|
||||
(gds-test-execute-keys "o")
|
||||
(gds-test-expect-protocol 'stack)
|
||||
(gds-test-execute-keys "g")
|
||||
(gds-test-expect-protocol 'eval-results)
|
||||
(gds-test-check-buffer "*Guile Evaluation*"
|
||||
"(for-each (lambda"
|
||||
"Evaluating in current module"
|
||||
"3 cubed is 27"
|
||||
"=> no (or unspecified) value")
|
||||
|
||||
;; Done.
|
||||
(message "====================================")
|
||||
(message "gds-test.el completed without errors")
|
||||
(message "====================================")
|
||||
|
||||
)
|
||||
|
||||
(switch-to-buffer "gds-debug")
|
||||
(write-region (point-min) (point-max) "gds-test.debug")
|
||||
|
||||
(switch-to-buffer "*GDS Transcript*")
|
||||
(write-region (point-min) (point-max) "gds-test.transcript")
|
||||
|
||||
)
|
2
emacs/gds-test.sh
Executable file
2
emacs/gds-test.sh
Executable file
|
@ -0,0 +1,2 @@
|
|||
#!/bin/sh
|
||||
GUILE_LOAD_PATH=$(pwd) emacs --batch --no-site-file -q -l gds-test.el < gds-test.stdin
|
1
emacs/gds-test.stdin
Normal file
1
emacs/gds-test.stdin
Normal file
|
@ -0,0 +1 @@
|
|||
|
223
emacs/gds-tutorial.txt
Executable file
223
emacs/gds-tutorial.txt
Executable file
|
@ -0,0 +1,223 @@
|
|||
|
||||
;; Welcome to the GDS tutorial!
|
||||
|
||||
;; This tutorial teaches the use of GDS by leading you through a set
|
||||
;; of examples where you actually use GDS, in Emacs, along the way.
|
||||
;; To get maximum benefit, therefore, you should be reading this
|
||||
;; tutorial in Emacs.
|
||||
|
||||
;; ** GDS setup
|
||||
|
||||
;; The first thing to do, if you haven't already, is to load the GDS
|
||||
;; library into Emacs. The Emacs Lisp expression for this is:
|
||||
|
||||
(require 'gds)
|
||||
|
||||
;; So, if you don't already have this in your .emacs, either add it
|
||||
;; and then restart Emacs, or evaluate it just for this Emacs session
|
||||
;; by moving the cursor to just after the closing parenthesis and
|
||||
;; typing `C-x C-e'.
|
||||
|
||||
;; (Note that if you _have_ already loaded GDS, and you type `C-x C-e'
|
||||
;; after this expression, you will see a *Guile Evaluation* window
|
||||
;; telling you that the evaluation failed because `require' is
|
||||
;; unbound. Don't worry; this is not a problem, and the rest of the
|
||||
;; tutorial should still work just fine.)
|
||||
|
||||
;; ** Help
|
||||
|
||||
;; GDS makes it easy to access the Guile help system when working on a
|
||||
;; Scheme program in Emacs. For example, suppose that you are writing
|
||||
;; code that uses list-ref, and need to remind yourself about
|
||||
;; list-ref's arguments ...
|
||||
|
||||
(define (penultimate l)
|
||||
(list-ref
|
||||
|
||||
;; Just place the cursor on the word "list-ref" and type `C-h g RET'.
|
||||
;; Try it now!
|
||||
|
||||
;; If GDS is working correctly, a window should have popped up above
|
||||
;; or below showing the Guile help for list-ref.
|
||||
|
||||
;; You can also do an "apropos" search through Guile's help. If you
|
||||
;; couldn't remember the name list-ref, for example, you could search
|
||||
;; for anything matching "list" by typing `C-h C-g' and entering
|
||||
;; "list" at the minibuffer prompt. Try doing this now: you should
|
||||
;; see a longish list of Guile definitions whose names include "list".
|
||||
;; As usual in Emacs, you can use `M-PageUp' and `M-PageDown' to
|
||||
;; conveniently scroll the other window without having to select it.
|
||||
|
||||
;; The functions called by `C-h g' and `C-h C-g' are gds-help-symbol
|
||||
;; and gds-apropos. They both look up the symbol or word at point by
|
||||
;; default, but that default can be overidden by typing something else
|
||||
;; at the minibuffer prompt.
|
||||
|
||||
;; ** Completion
|
||||
|
||||
;; As you are typing Scheme code, you can ask GDS to complete the
|
||||
;; symbol before point for you, by typing `ESC TAB'. GDS selects
|
||||
;; possible completions by matching the text so far against all
|
||||
;; definitions in the Guile environment. (This may be contrasted with
|
||||
;; the "dabbrev" completion performed by `M-/', which selects possible
|
||||
;; completions from the contents of Emacs buffers. So, if you are
|
||||
;; trying to complete "with-ou", to get "with-output-to-string", for
|
||||
;; example, `ESC TAB' will always work, because with-output-to-string
|
||||
;; is always defined in Guile's default environment, whereas `M-/'
|
||||
;; will only work if one of Emacs's buffers happens to contain the
|
||||
;; full name "with-output-to-string".)
|
||||
|
||||
;; To illustrate the idea, here are some partial names that you can
|
||||
;; try completing. For each one, move the cursor to the end of the
|
||||
;; line and type `ESC TAB' to try to complete it.
|
||||
|
||||
list-
|
||||
with-ou
|
||||
with-output-to-s
|
||||
mkst
|
||||
|
||||
;; (If you are not familiar with any of the completed definitions,
|
||||
;; feel free to use `C-h g' to find out about them!)
|
||||
|
||||
;; ** Evaluation
|
||||
|
||||
;; GDS provides several ways for you to evaluate Scheme code from
|
||||
;; within Emacs.
|
||||
|
||||
;; Just like in Emacs Lisp, a single expression in a buffer can be
|
||||
;; evaluated using `C-x C-e' or `C-M-x'. For `C-x C-e', the
|
||||
;; expression is that which ends immediately before point (so that it
|
||||
;; is useful for evaluating something just after you have typed it).
|
||||
;; For `C-M-x', the expression is the "top level defun" around point;
|
||||
;; this means the balanced chunk of code around point whose opening
|
||||
;; parenthesis is in column 0.
|
||||
|
||||
;; Take this code fragment as an example:
|
||||
|
||||
(let ((x 1) (y 2))
|
||||
(let ((z (atan x y)))
|
||||
(display "Arctangent is: ")
|
||||
(display z)
|
||||
(newline)
|
||||
z))
|
||||
|
||||
;; If you move the cursor to the end of the (display z) line and type
|
||||
;; `C-x C-e', the code evaluated is just "(display z)", which normally
|
||||
;; produces an error, because z is not defined in the usual Guile
|
||||
;; environment. If, however, you type `C-M-x' with the cursor in the
|
||||
;; same place, the code evaluated is the whole "(let ((x 1) (y 2))
|
||||
;; ...)" kaboodle, because that is the most recent expression before
|
||||
;; point that starts in column 0.
|
||||
|
||||
;; Try these now. The Guile Evaluation window should pop up again,
|
||||
;; and show you:
|
||||
;; - the expression that was evaluated (probably abbreviated)
|
||||
;; - the module that it was evaluated in
|
||||
;; - anything that the code wrote to its standard output
|
||||
;; - the return value(s) of the evaluation.
|
||||
;; Following the convention of the Emacs Lisp and Guile manuals,
|
||||
;; return values are indicated by the symbol "=>".
|
||||
|
||||
;; To see what happens when an expression has multiple return values,
|
||||
;; try evaluating this one:
|
||||
|
||||
(values 'a (begin (display "hello world\n") 'b) 'c)
|
||||
|
||||
;; You can also evaluate a region of a buffer using `C-c C-r'. If the
|
||||
;; code in the region consists of multiple expressions, GDS evaluates
|
||||
;; them sequentially. For example, try selecting the following three
|
||||
;; lines and typing `C-c C-r'.
|
||||
|
||||
(display "Arctangent is: ")
|
||||
(display z)
|
||||
(newline)
|
||||
|
||||
;; If the code in the region evaluated isn't syntactically balanced,
|
||||
;; GDS will indicate a read error, for example for this code:
|
||||
|
||||
(let ((z (atan x y)))
|
||||
(display "Arctangent is: ")
|
||||
(display z)
|
||||
(newline)
|
||||
|
||||
;; Finally, if you want to evaluate something quickly that is not in a
|
||||
;; buffer, you can use `C-c C-e' and type the code to evaluate at the
|
||||
;; minibuffer prompt. The results are popped up in the same way as
|
||||
;; for code from a buffer.
|
||||
|
||||
;; ** Breakpoints
|
||||
|
||||
;; Before evaluating Scheme code from an Emacs buffer, you may want to
|
||||
;; set some breakpoints in it. With GDS you can set breakpoints in
|
||||
;; Scheme code by typing `C-x SPC'.
|
||||
;;
|
||||
;; To see how this works, select the second line of the following code
|
||||
;; (the `(format ...)' line) and type `C-x SPC'.
|
||||
|
||||
(for-each (lambda (x)
|
||||
(format #t "~A cubed is ~A\n" x (* x x x)))
|
||||
(iota 6))
|
||||
|
||||
;; The two opening parentheses in that line should now be highlighted
|
||||
;; in red, to show that breakpoints have been set at the start of the
|
||||
;; `(format ...)' and `(* x x x)' expressions. Then evaluate the
|
||||
;; whole for-each expression by typing `C-M-x' ...
|
||||
;;
|
||||
;; In the upper half of your Emacs, a buffer appears showing you the
|
||||
;; Scheme stack.
|
||||
;;
|
||||
;; In the lower half, the `(format ...)' expression is highlighted.
|
||||
;;
|
||||
;; What has happened is that Guile started evaluating the for-each
|
||||
;; code, but then hit the breakpoint that you set on the start of the
|
||||
;; format expression. Guile therefore pauses the evaluation at that
|
||||
;; point and passes the stack (which encapsulates everything that is
|
||||
;; interesting about the state of Guile at that point) to GDS. You
|
||||
;; can then explore the stack and decide how to tell Guile to
|
||||
;; continue.
|
||||
;;
|
||||
;; - If you move your mouse over any of the identifiers in the
|
||||
;; highlighted code, a help echo (or tooltip) will appear to tell
|
||||
;; you that identifier's current value. (Note though that this only
|
||||
;; works when the stack buffer is selected. So if you have switched
|
||||
;; to this buffer in order to scroll down and read these lines, you
|
||||
;; will need to switch back to the stack buffer before trying this
|
||||
;; out.)
|
||||
;;
|
||||
;; - In the stack buffer, the "=>" on the left shows you that the top
|
||||
;; frame is currently selected. You can move up and down the stack
|
||||
;; by pressing the up and down arrows (or `u' and `d'). As you do
|
||||
;; this, GDS will change the highlight in the lower window to show
|
||||
;; the code that corresponds to the selected stack frame.
|
||||
;;
|
||||
;; - You can evaluate an arbitrary expression in the local environment
|
||||
;; of the selected stack frame by typing `e' followed by the
|
||||
;; expression.
|
||||
;;
|
||||
;; - You can show various bits of information about the selected frame
|
||||
;; by typing `I', `A' and `S'. Feel free to try these now, to see
|
||||
;; what they do.
|
||||
;;
|
||||
;; You also have control over the continuing evaluation of this code.
|
||||
;; Here are some of the things you can do - please try them as you
|
||||
;; read.
|
||||
;;
|
||||
;; - `g' tells Guile to continue execution normally. In this case
|
||||
;; that means that evaluation will continue until it hits the next
|
||||
;; breakpoint, which is on the `(* x x x)' expression.
|
||||
;;
|
||||
;; - `SPC' tells Guile to continue until the next significant event in
|
||||
;; the same source file as the selected frame. A "significant
|
||||
;; event" means either beginning to evaluate an expression in the
|
||||
;; relevant file, or completing such an evaluation, in which case
|
||||
;; GDS tells you the value that it is returning. Pressing `SPC'
|
||||
;; repeatedly is a nice way to step through all the details of the
|
||||
;; code in a given file, but stepping over calls that involve code
|
||||
;; from other files.
|
||||
;;
|
||||
;; - `o' tells Guile to continue execution until the selected stack
|
||||
;; frame completes, and then to show its return value.
|
||||
|
||||
;; Local Variables:
|
||||
;; mode: scheme
|
||||
;; End:
|
27
emacs/gds.el
27
emacs/gds.el
|
@ -36,10 +36,11 @@
|
|||
;; The subprocess object for the debug server.
|
||||
(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)))
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
@ -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))))))
|
||||
|
|
7
gdbinit
7
gdbinit
|
@ -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
|
||||
|
|
|
@ -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))))))
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -1,69 +0,0 @@
|
|||
## Process this file with automake to produce Makefile.in.
|
||||
##
|
||||
## Copyright (C) 2000, 2006, 2009 Free Software Foundation, Inc.
|
||||
##
|
||||
## This file is part of GUILE.
|
||||
##
|
||||
## GUILE is free software; you can redistribute it and/or modify it
|
||||
## under the terms of the GNU Lesser General Public License as
|
||||
## published by the Free Software Foundation; either version 3, or
|
||||
## (at your option) any later version.
|
||||
##
|
||||
## GUILE is distributed in the hope that it will be useful, but
|
||||
## WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
## GNU Lesser General Public License for more details.
|
||||
##
|
||||
## You should have received a copy of the GNU Lesser General Public
|
||||
## License along with GUILE; see the file COPYING.LESSER. If not,
|
||||
## write to the Free Software Foundation, Inc., 51 Franklin Street,
|
||||
## Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
AUTOMAKE_OPTIONS = gnu
|
||||
|
||||
# These should be installed and distributed.
|
||||
|
||||
elisp_sources = \
|
||||
elisp/base.scm \
|
||||
elisp/example.el \
|
||||
elisp/interface.scm \
|
||||
elisp/transform.scm \
|
||||
elisp/expand.scm \
|
||||
elisp/variables.scm \
|
||||
\
|
||||
elisp/primitives/buffers.scm \
|
||||
elisp/primitives/char-table.scm \
|
||||
elisp/primitives/features.scm \
|
||||
elisp/primitives/fns.scm \
|
||||
elisp/primitives/format.scm \
|
||||
elisp/primitives/guile.scm \
|
||||
elisp/primitives/keymaps.scm \
|
||||
elisp/primitives/lists.scm \
|
||||
elisp/primitives/load.scm \
|
||||
elisp/primitives/match.scm \
|
||||
elisp/primitives/numbers.scm \
|
||||
elisp/primitives/pure.scm \
|
||||
elisp/primitives/read.scm \
|
||||
elisp/primitives/signal.scm \
|
||||
elisp/primitives/strings.scm \
|
||||
elisp/primitives/symprop.scm \
|
||||
elisp/primitives/syntax.scm \
|
||||
elisp/primitives/system.scm \
|
||||
elisp/primitives/time.scm \
|
||||
\
|
||||
elisp/internals/evaluation.scm \
|
||||
elisp/internals/format.scm \
|
||||
elisp/internals/fset.scm \
|
||||
elisp/internals/lambda.scm \
|
||||
elisp/internals/load.scm \
|
||||
elisp/internals/null.scm \
|
||||
elisp/internals/set.scm \
|
||||
elisp/internals/signal.scm \
|
||||
elisp/internals/time.scm \
|
||||
elisp/internals/trace.scm
|
||||
|
||||
subpkgdatadir = $(pkgdatadir)/$(GUILE_EFFECTIVE_VERSION)/lang
|
||||
nobase_subpkgdata_DATA = $(elisp_sources)
|
||||
TAGS_FILES = $(nobase_subpkgdata_DATA)
|
||||
|
||||
EXTRA_DIST = $(elisp_sources) elisp/ChangeLog-2008
|
|
@ -1,401 +0,0 @@
|
|||
2008-04-14 Neil Jerram <neil@ossau.uklinux.net>
|
||||
|
||||
* primitives/symprop.scm (get): Use lambda->nil.
|
||||
|
||||
* primitives/strings.scm (aset): New primitive.
|
||||
|
||||
* internals/load.scm (load): Use in-vicinity (instead of
|
||||
string-append) to add a slash if needed.
|
||||
|
||||
2004-02-08 Mikael Djurfeldt <djurfeldt@nada.kth.se>
|
||||
|
||||
* primitives/Makefile.am (TAGS_FILES), internals/Makefile.am
|
||||
(TAGS_FILES), Makefile.am (TAGS_FILES): Use this variable instead
|
||||
of ETAGS_ARGS so that TAGS can be built using separate build
|
||||
directory.
|
||||
|
||||
2003-11-01 Neil Jerram <neil@ossau.uklinux.net>
|
||||
|
||||
* internals/format.scm (format), internals/signal.scm (error),
|
||||
internals/load.scm (load): Export using #:replace to avoid
|
||||
duplicate binding warnings.
|
||||
|
||||
2003-01-05 Marius Vollmer <mvo@zagadka.ping.de>
|
||||
|
||||
* primitives/Makefile.am (elisp_sources): Added char-table.scm.
|
||||
|
||||
2002-12-28 Neil Jerram <neil@ossau.uklinux.net>
|
||||
|
||||
* base.scm (lang): Use char-table module.
|
||||
|
||||
* primitives/char-table.scm (lang): New (stub definitions).
|
||||
|
||||
2002-12-08 Rob Browning <rlb@defaultvalue.org>
|
||||
|
||||
* Makefile.am (subpkgdatadir): VERSION -> GUILE_EFFECTIVE_VERSION.
|
||||
|
||||
* primitives/Makefile.am (subpkgdatadir): VERSION ->
|
||||
GUILE_EFFECTIVE_VERSION.
|
||||
|
||||
* internals/Makefile.am (subpkgdatadir): VERSION ->
|
||||
GUILE_EFFECTIVE_VERSION.
|
||||
|
||||
2002-02-13 Neil Jerram <neil@ossau.uklinux.net>
|
||||
|
||||
* base.scm (load-emacs): Add optional parameters for specifying an
|
||||
alternative load path, and for debugging this. (Thanks to
|
||||
Thien-Thi Nguyen!)
|
||||
|
||||
* primitives/syntax.scm (setq): Use `set'.
|
||||
|
||||
* internals/set.scm (set): Fixed to support variables that are
|
||||
imported from other modules.
|
||||
|
||||
2002-02-12 Neil Jerram <neil@ossau.uklinux.net>
|
||||
|
||||
* transform.scm (scheme): Use set-current-module to ensure
|
||||
expected behaviour of resolve-module.
|
||||
|
||||
2002-02-08 Neil Jerram <neil@ossau.uklinux.net>
|
||||
|
||||
* STATUS: New file.
|
||||
|
||||
* README: Updated.
|
||||
|
||||
* interface.scm (translate-elisp): New exported procedure.
|
||||
(elisp-function): Symbol var is `obj', not `symbol'.
|
||||
|
||||
* internals/lambda.scm, primitives/fns.scm: Fix confusion between
|
||||
interactive-spec and interactive-specification.
|
||||
|
||||
* internals/lambda.scm (transform-lambda), primitives/syntax.scm
|
||||
(defmacro): Bind unspecified optional and rest arguments to #nil,
|
||||
not #f.
|
||||
|
||||
* internals/null.scm (->nil, lambda->nil): New, exported.
|
||||
(null): Use ->nil.
|
||||
|
||||
* primitives/features.scm (featurep), primitives/fns.scm
|
||||
(fboundp, subrp): Use ->nil.
|
||||
|
||||
* internals/lists.scm (cons, setcdr, memq, member, assq, assoc):
|
||||
Simplified.
|
||||
(car, cdr): Return #nil rather than #f.
|
||||
|
||||
* primitives/load.scm (current-load-list), primitives/pure.scm
|
||||
(purify-flag): Set to #nil, not #f.
|
||||
|
||||
* primitives/match.scm (string-match): Return #nil rather than #f.
|
||||
|
||||
* primitives/numbers.scm (integerp, numberp),
|
||||
primitives/strings.scm (string-lessp, stringp): Use lambda->nil.
|
||||
|
||||
* primitives/symprop.scm (boundp): Use ->nil.
|
||||
(symbolp, local-variable-if-set-p): Return #nil rather than #f.
|
||||
|
||||
* primitives/syntax.scm (prog1, prog2): Mangle variable names
|
||||
further to lessen possibility of conflicts.
|
||||
(if, and, or, cond): Return #nil rather than #f.
|
||||
(cond): Return #t rather than t (which is undefined).
|
||||
(let, let*): Bind uninitialized variables to #nil, not #f.
|
||||
|
||||
* transform.scm: Resolve inconsistency in usage of `map', and add
|
||||
an explanatory note. Also cleaned up use of subsidiary
|
||||
transformation functions. Also use cons-source wherever possible.
|
||||
(transform-datum, transform-quote): New.
|
||||
(transform-quasiquote): Renamed from `transform-inside-qq'.
|
||||
(transform-application): Apply `transform-quote' to application
|
||||
args.
|
||||
(cars->nil): Removed.
|
||||
|
||||
* internals/null.scm (null), primitives/lists.scm (cons, car, cdr,
|
||||
setcdr, memq, member, assq, assoc, nth): Update to take into
|
||||
account new libguile support for Elisp nil value.
|
||||
|
||||
2002-02-06 Neil Jerram <neil@ossau.uklinux.net>
|
||||
|
||||
* example.el (time): New macro, for performance measurement.
|
||||
Accompanying comment compares results for Guile and Emacs.
|
||||
|
||||
* transform.scm (scheme): New macro.
|
||||
(transformer): New implementation of `scheme' escape that doesn't
|
||||
rely on (lang elisp base) importing Guile bindings.
|
||||
|
||||
* base.scm: No longer import anything from (guile).
|
||||
(load-emacs): Add scheme form to ensure that keywords
|
||||
read option is set correctly.
|
||||
|
||||
* primitives/syntax.scm (defmacro, let, let*): Unquote uses of
|
||||
`@bind' in transformed code.
|
||||
(if): Unquote uses of `nil-cond' in transformed code.
|
||||
|
||||
* internals/lambda.scm (transform-lambda): Unquote use of `@bind'
|
||||
in transformed code.
|
||||
|
||||
* transform.scm (transformer-macro): Don't quote `list' in
|
||||
transformed code.
|
||||
(transform-application): Don't quote `@fop' in transformed code.
|
||||
(transformer): No need to treat `@bind' and `@fop' as special
|
||||
cases in input to the transformer.
|
||||
|
||||
2002-02-04 Neil Jerram <neil@ossau.uklinux.net>
|
||||
|
||||
* primitives/syntax.scm (parse-formals, transform-lambda,
|
||||
interactive-spec, set-not-subr!, transform-lambda/interactive):
|
||||
Move into internals/lambda.scm so that these can also be used
|
||||
by...
|
||||
|
||||
* internals/fset.scm (elisp-apply): Use `eval' and
|
||||
`transform-lambda/interactive' to turn a quoted lambda expression
|
||||
into a Scheme procedure.
|
||||
|
||||
* transform.scm (m-quasiquote): Don't quote `quasiquote' in
|
||||
transformed code.
|
||||
(transformer): Transform '() to #nil.
|
||||
|
||||
2002-02-03 Neil Jerram <neil@ossau.uklinux.net>
|
||||
|
||||
* internals/Makefile.am (elisp_sources): Add lambda.scm.
|
||||
|
||||
* internals/lambda.scm (lang): New file.
|
||||
|
||||
2002-02-01 Neil Jerram <neil@ossau.uklinux.net>
|
||||
|
||||
* transform.scm (transformer), primitives/syntax.scm (let*):
|
||||
Unquote uses of `begin' in transformed code.
|
||||
|
||||
2002-01-29 Neil Jerram <neil@ossau.uklinux.net>
|
||||
|
||||
* transform.scm (transform-1, transform-2, transform-3,
|
||||
transform-list): Removed (unused).
|
||||
|
||||
* transform.scm, primitives/syntax.scm: Add commas everywhere
|
||||
before use of (guile) primitives in generated code, so that (lang
|
||||
elisp base) doesn't have to import bindings from (guile).
|
||||
|
||||
* base.scm: Move use-modules expressions inside the define-module,
|
||||
and add #:pure so that we don't import bindings from (guile).
|
||||
|
||||
2002-01-25 Neil Jerram <neil@ossau.uklinux.net>
|
||||
|
||||
* transform.scm (transform-application): Preserve source
|
||||
properties of original elisp expression by using cons-source.
|
||||
|
||||
* transform.scm: Don't handle special forms specially in the
|
||||
translator. Instead, define them as macros in ...
|
||||
|
||||
* primitives/syntax.scm: New file; special form definitions.
|
||||
|
||||
* primitives/fns.scm (run-hooks): Rewritten correctly.
|
||||
|
||||
* primitives/symprop.scm (symbol-value): Use `value'.
|
||||
|
||||
* internals/set.scm (value): New function.
|
||||
|
||||
* primitives/fns.scm: Use (lang elisp internals null), as null is
|
||||
no longer a primitive. Change generated #f values to %nil.
|
||||
|
||||
* internals/null.scm (null): Handle nil symbol.
|
||||
|
||||
* primitives/lists.scm (memq, member, assq, assoc): Handle all
|
||||
possible nil values.
|
||||
|
||||
* transform.scm (transformer): Translate `nil' and `t' to #nil and
|
||||
#t.
|
||||
|
||||
* base.scm: Remove setting of 'language read-option.
|
||||
|
||||
2001-11-03 Neil Jerram <neil@ossau.uklinux.net>
|
||||
|
||||
* README (Resources): Fill in missing URLs.
|
||||
|
||||
2001-11-02 Neil Jerram <neil@ossau.uklinux.net>
|
||||
|
||||
* Makefile.am (elisp_sources): Added base.scm, example.el,
|
||||
interface.scm; removed emacs.scm.
|
||||
|
||||
* README: Updated accordingly.
|
||||
|
||||
* internals/load.scm (load): Avoid using `load-path' if the
|
||||
supplied file name begins with a slash.
|
||||
|
||||
* internals/fset.scm: Support export of defuns, defmacros and
|
||||
defvars to a module specified by the fluid `elisp-export-module'.
|
||||
This allows us to automate the importing of Elisp definitions into
|
||||
Scheme.
|
||||
|
||||
* example.el: New file: example code for `load-elisp-file'.
|
||||
|
||||
* interface.scm: New file - mechanisms to exchange definitions
|
||||
between Scheme and Elisp.
|
||||
|
||||
Following changes try to make the Elisp evaluation module less
|
||||
Emacs-dependent; in other words, so that it isn't necessary to try
|
||||
to load the whole Emacs environment before evaluating basic
|
||||
non-Emacs-specific Elisp code.
|
||||
|
||||
* variables.scm, internals/evaluation.scm: Changed (lang elisp
|
||||
emacs) to (lang elisp base).
|
||||
|
||||
* emacs.scm (lang): Removed.
|
||||
|
||||
* base.scm (lang): New file (non-emacs-specific replacement for
|
||||
emacs.scm).
|
||||
|
||||
2001-10-28 Neil Jerram <neil@ossau.uklinux.net>
|
||||
|
||||
* primitives/symprop.scm (symbol-name): New primitive.
|
||||
|
||||
* primitives/strings.scm (stringp): New primitive.
|
||||
|
||||
* primitives/pure.scm (purify-flag): New variable.
|
||||
|
||||
* primitives/numbers.scm (numberp): New primitive.
|
||||
|
||||
* internals/fset.scm (fset): Set procedure and macro name
|
||||
properties usefully to match Elisp symbol names. Also bind Elisp
|
||||
function definition variables to similarly named symbols in the
|
||||
(lang elisp variables) module.
|
||||
|
||||
* transform.scm (transformer, m-unwind-protect): Added support for
|
||||
`unwind-protect'.
|
||||
(m-quasiquote): Use 'quasiquote rather than 'quote.
|
||||
(transform-lambda, m-defmacro): When no rest arguments, set the
|
||||
rest parameter to '() rather than #f. It shouldn't make any
|
||||
difference, but it feels more right.
|
||||
|
||||
* README: Enlarged description of current status.
|
||||
|
||||
* Makefile.am (elisp_sources): Added variables.scm.
|
||||
|
||||
* variables.scm: New file.
|
||||
|
||||
2001-10-26 Neil Jerram <neil@ossau.uklinux.net>
|
||||
|
||||
* buffers.scm, calling.scm: Removed. These should have
|
||||
disappeared during the reorganization described below, but I
|
||||
missed them by mistake.
|
||||
|
||||
* primitives/symprop.scm (set, boundp, symbol-value): Changed to
|
||||
use (module-xx the-elisp-module ...) rather than (local-xx ...).
|
||||
(symbolp): Accept either symbols or keywords.
|
||||
(set-default, default-boundp, default-value,
|
||||
local-variable-if-set-p): New.
|
||||
|
||||
* primitives/match.scm (string-match, match-data): Store last
|
||||
match data in Emacs rather than Guile form, to simplify
|
||||
implementation of ...
|
||||
(set-match-data, store-match-data): New.
|
||||
|
||||
* primitives/load.scm (autoload, current-load-list): New. (But
|
||||
autoload is just stubbed, not properly implemented.)
|
||||
|
||||
* primitives/lists.scm (nth, listp, consp, nconc): New.
|
||||
|
||||
* primitives/fns.scm (byte-code-function-p, run-hooks): New.
|
||||
|
||||
* transform.scm (transform-application, transformer-macro): New
|
||||
scheme for transforming procedure arguments while leaving macro
|
||||
args untransformed. (See also associated change in libguile.)
|
||||
(m-defconst): Simplified, now uses m-setq.
|
||||
|
||||
* Makefile.am: Changed so that it only deals with files directly
|
||||
in this directory; otherwise files don't install cleanly.
|
||||
|
||||
* internals/Makefile.am, primitives/Makefile.am,
|
||||
internals/.cvsignore, primitives/.cvsignore: New files.
|
||||
|
||||
2001-10-26 Neil Jerram <neil@ossau.uklinux.net>
|
||||
|
||||
* transform.scm (transformer): New handling for (1) quasiquoting
|
||||
syntax like "(` ...)" as well as the more normal "` ..."; (2)
|
||||
`function'; (3) interactive specification in lambda body.
|
||||
Simplied handling for `setq'.
|
||||
(transform-inside-qq): Fixed to handle improper as well as proper
|
||||
lists.
|
||||
(transform-lambda/interactive): New; wraps transform-lambda to
|
||||
handle setting of various procedure properties.
|
||||
(transform-lambda, m-defmacro): Changed `args' and `num-args' to
|
||||
`%--args' and `%--num-args' in the hope of avoiding lexical
|
||||
vs. dynamic name clashes.
|
||||
(m-and): Use #f instead of '() where a condition fails.
|
||||
|
||||
Plus big hierarchy reorganization, in which most of the previous
|
||||
occupants of lang/elisp moved to lang/elisp/primitives, with some
|
||||
internal processing being split out into lang/elisp/internals.
|
||||
The upshot looks like this:
|
||||
|
||||
* internals/trace.scm, internals/set.scm, internals/load.scm,
|
||||
internals/fset.scm, internals/signal.scm, internals/time.scm,
|
||||
internals/format.scm, internals/null.scm,
|
||||
internals/evaluation.scm, primitives/buffers.scm,
|
||||
primitives/features.scm, primitives/format.scm,
|
||||
primitives/time.scm, primitives/guile.scm, primitives/keymaps.scm,
|
||||
primitives/lists.scm, primitives/load.scm, primitives/match.scm,
|
||||
primitives/numbers.scm, primitives/pure.scm, primitives/read.scm,
|
||||
primitives/signal.scm, primitives/strings.scm,
|
||||
primitives/symprop.scm, primitives/system.scm, primitives/fns.scm:
|
||||
New files.
|
||||
|
||||
* features.scm, format.scm, fset.scm, guile.scm, keymaps.scm,
|
||||
lists.scm, load.scm, match.scm, numbers.scm, pure.scm, read.scm,
|
||||
signal.scm, strings.scm, symprop.scm, system.scm, time.scm,
|
||||
trace.scm: Removed files.
|
||||
|
||||
2001-10-23 Neil Jerram <neil@ossau.uklinux.net>
|
||||
|
||||
* match.scm (string-match): New implementation using new
|
||||
`make-emacs-regexp' primitive; old workaround implementation
|
||||
renamed to `string-match-workaround'.
|
||||
|
||||
2001-10-21 Neil Jerram <neil@ossau.uklinux.net>
|
||||
|
||||
* transform.scm (m-defun, m-defmacro, m-let, m-defvar,
|
||||
m-defconst): Use more selective tracing mechanism (provided by new
|
||||
file trace.scm).
|
||||
|
||||
* symprop.scm (get, boundp), transform.scm (transform-lambda,
|
||||
m-defmacro): Remove unnecessary uses of nil-ify and t-ify.
|
||||
|
||||
* match.scm (string-match): Workaround Guile/libc regex
|
||||
parenthesis bug.
|
||||
|
||||
* emacs.scm: Move elisp primitive definitions into more specific
|
||||
files, so that emacs.scm contains only overall code.
|
||||
|
||||
* Makefile.am: Added new files.
|
||||
|
||||
* numbers.scm, trace.scm, time.scm, pure.scm, system.scm,
|
||||
read.scm, calling.scm, guile.scm: New files.
|
||||
|
||||
2001-10-20 Neil Jerram <neil@ossau.uklinux.net>
|
||||
|
||||
* Makefile.am (elisp_sources): Added match.scm and strings.scm.
|
||||
|
||||
* match.scm, strings.scm: New files.
|
||||
|
||||
2001-10-19 Neil Jerram <neil@ossau.uklinux.net>
|
||||
|
||||
* transform.scm: Replace uses of `nil' by `#f' or `'()'.
|
||||
|
||||
* Makefile.am (elisp_sources): Added lists.scm.
|
||||
|
||||
* load.scm (the-elisp-module): Corrected (lang elisp emacs) module
|
||||
name.
|
||||
|
||||
* lists.scm (lang): New file containing list-related primitives.
|
||||
|
||||
* emacs.scm: Corrected module name.
|
||||
|
||||
2001-10-19 Neil Jerram <neil@ossau.uklinux.net>
|
||||
|
||||
Initial implementation of an Emacs Lisp translator, based on
|
||||
transformer code originally written by Mikael Djurfeldt.
|
||||
|
||||
* Makefile.am, .cvsignore: New.
|
||||
|
||||
* ChangeLog, README, buffers.scm, emacs.scm, features.scm,
|
||||
format.scm, fset.scm, keymaps.scm, load.scm, signal.scm,
|
||||
symprop.scm, transform.scm: New files.
|
||||
|
||||
|
|
@ -1,303 +0,0 @@
|
|||
-*- outline -*-
|
||||
|
||||
This directory holds the Scheme side of a translator for Emacs Lisp.
|
||||
|
||||
* Usage
|
||||
|
||||
To load up the base Elisp environment:
|
||||
|
||||
(use-modules (lang elisp base))
|
||||
|
||||
Then you can switch into this module
|
||||
|
||||
(define-module (lang elisp base))
|
||||
|
||||
and start typing away in Elisp, or evaluate an individual Elisp
|
||||
expression from Scheme:
|
||||
|
||||
(eval EXP (resolve-module '(lang elisp base)))
|
||||
|
||||
A more convenient, higher-level interface is provided by (lang elisp
|
||||
interface):
|
||||
|
||||
(use-modules (lang elisp interface))
|
||||
|
||||
With this interface, you can evaluate an Elisp expression
|
||||
|
||||
(eval-elisp EXP)
|
||||
|
||||
load an Elisp file with no effect on the Scheme world
|
||||
|
||||
(load-elisp-file "/home/neil/Guile/cvs/guile-core/lang/elisp/example.el")
|
||||
|
||||
load an Elisp file, automatically importing top level definitions into
|
||||
Scheme
|
||||
|
||||
(use-elisp-file "/home/neil/Guile/cvs/guile-core/lang/elisp/example.el")
|
||||
|
||||
export Scheme objects to Elisp
|
||||
|
||||
(export-to-elisp + - * my-func 'my-var)
|
||||
|
||||
and try to bootstrap a complete Emacs environment:
|
||||
|
||||
(load-emacs)
|
||||
|
||||
* Status
|
||||
|
||||
Please see the STATUS file for the full position.
|
||||
|
||||
** Trying to load a complete Emacs environment.
|
||||
|
||||
To try this, type `(use-modules (lang elisp interface))' and then
|
||||
`(load-emacs)'. The following output shows how far I get when I try
|
||||
this.
|
||||
|
||||
guile> (use-modules (lang elisp interface))
|
||||
guile> (load-emacs)
|
||||
Calling loadup.el to clothe the bare Emacs...
|
||||
Loading /usr/share/emacs/20.7/lisp/loadup.el...
|
||||
Using load-path ("/usr/share/emacs/20.7/lisp/" "/usr/share/emacs/20.7/lisp/emacs-lisp/")
|
||||
Loading /usr/share/emacs/20.7/lisp/byte-run.el...
|
||||
Loading /usr/share/emacs/20.7/lisp/byte-run.el...done
|
||||
Loading /usr/share/emacs/20.7/lisp/subr.el...
|
||||
Loading /usr/share/emacs/20.7/lisp/subr.el...done
|
||||
Loading /usr/share/emacs/20.7/lisp/version.el...
|
||||
Loading /usr/share/emacs/20.7/lisp/version.el...done
|
||||
Loading /usr/share/emacs/20.7/lisp/map-ynp.el...
|
||||
Loading /usr/share/emacs/20.7/lisp/map-ynp.el...done
|
||||
Loading /usr/share/emacs/20.7/lisp/widget.el...
|
||||
Loading /usr/share/emacs/20.7/lisp/emacs-lisp/cl.el...
|
||||
Loading /usr/share/emacs/20.7/lisp/emacs-lisp/cl.el...done
|
||||
Loading /usr/share/emacs/20.7/lisp/widget.el...done
|
||||
Loading /usr/share/emacs/20.7/lisp/custom.el...
|
||||
Loading /usr/share/emacs/20.7/lisp/custom.el...done
|
||||
Loading /usr/share/emacs/20.7/lisp/cus-start.el...
|
||||
Note, built-in variable `abbrev-all-caps' not bound
|
||||
... [many other variable not bound messages] ...
|
||||
Loading /usr/share/emacs/20.7/lisp/cus-start.el...done
|
||||
Loading /usr/share/emacs/20.7/lisp/international/mule.el...
|
||||
<unnamed port>: In procedure make-char-table in expression (@fop make-char-table (# #)):
|
||||
<unnamed port>: Symbol's function definition is void
|
||||
ABORT: (misc-error)
|
||||
|
||||
Type "(backtrace)" to get more information or "(debug)" to enter the debugger.
|
||||
guile>
|
||||
|
||||
That's 3279 lines ("wc -l") of Elisp code already, which isn't bad!
|
||||
|
||||
I think that progress beyond this point basically means implementing
|
||||
multilingual and multibyte strings properly for Guile. Which is a
|
||||
_lot_ of work and requires IMO a very clear plan for Guile's role with
|
||||
respect to Emacs.
|
||||
|
||||
* Design
|
||||
|
||||
When thinking about how to implement an Elisp translator for Guile, it
|
||||
is important to realize that the great power of Emacs does not arise
|
||||
from Elisp (seen as a language in syntactic terms) alone, but from the
|
||||
combination of this language with the collection of primitives
|
||||
provided by the Emacs C source code. Therefore, to be of practical
|
||||
use, an Elisp translator needs to be more than just a transformer that
|
||||
translates sexps to Scheme expressions.
|
||||
|
||||
The finished translator should consist of several parts...
|
||||
|
||||
** Syntax transformation
|
||||
|
||||
Although syntax transformation isn't all we need, we do still need it!
|
||||
|
||||
This part is implemented by the (lang elisp transform) module; it is
|
||||
close to complete and seems to work pretty reliably.
|
||||
|
||||
Note that transformed expressions use the `@fop' and `@bind' macros
|
||||
provided by...
|
||||
|
||||
** C support for transformed expressions
|
||||
|
||||
For performance and historical reasons (and perhaps necessity - I
|
||||
haven't thought about it enough yet), some of the transformation
|
||||
support is written in C.
|
||||
|
||||
*** @fop
|
||||
|
||||
The `@fop' macro is used to dispatch Elisp applications. Its first
|
||||
argument is a symbol, and this symbol's function slot is examined to
|
||||
find a procedure or macro to apply to the remaining arguments. `@fop'
|
||||
also handles aliasing (`defalias'): in this case the function slot
|
||||
contains another symbol.
|
||||
|
||||
Once `@fop' has found the appropriate procedure or macro to apply, it
|
||||
returns an application expression in which that procedure or macro
|
||||
replaces the `@fop' and the original symbol. Hence no Elisp-specific
|
||||
evaluator support is required to perform the application.
|
||||
|
||||
*** @bind
|
||||
|
||||
Currently, Elisp variables are the same as Scheme variables, so
|
||||
variable references are effectively untransformed.
|
||||
|
||||
The `@bind' macro does Elisp-style dynamic variable binding.
|
||||
Basically, it locates the named top level variables, `set!'s them to
|
||||
new values, evaluates its body, and then uses `set!' again to restore
|
||||
the original values.
|
||||
|
||||
Because of the body evaluation, `@bind' requires evaluator support.
|
||||
In fact, the `@bind' macro code does little more than replace itself
|
||||
with the memoized SCM_IM_BIND. Most of the work is done by the
|
||||
evaluator when it hits SCM_IM_BIND.
|
||||
|
||||
One theoretical problem with `@bind' is that any local Scheme variable
|
||||
in the same scope and with the same name as an Elisp variable will
|
||||
shadow the Elisp variable. But in practice it's difficult to set up
|
||||
such a situation; an exception is the translator code itself, so there
|
||||
we mangle the relevant Scheme variable names a bit to avoid the
|
||||
problem.
|
||||
|
||||
Other possible problems with this approach are that it might not be
|
||||
possible to implement buffer local variables properly, and that
|
||||
`@bind' might become too inefficient when we implement full support
|
||||
for undefining Scheme variables. So we might in future have to
|
||||
transform Elisp variable references after all.
|
||||
|
||||
*** Truth value stuff
|
||||
|
||||
Following extensive discussions on the Guile mailing list between
|
||||
September 2001 and January 2002, we decided to go with Jim Blandy's
|
||||
proposal. See devel/translation/lisp-and-scheme.text for details.
|
||||
|
||||
- The Elisp nil value is a new immediate SCM_MAKIFLAG, eq?-distinct
|
||||
from both #f and '() (and of course any other Scheme value). It can
|
||||
be accessed via the (guile) binding `%nil', and prints as `#nil'.
|
||||
|
||||
- All Elisp primitives treat #nil, #f and '() as identical.
|
||||
|
||||
- Scheme truth-testing primitives have been modified so that they
|
||||
treat #nil the same as #f.
|
||||
|
||||
- Scheme list-manipulating primitives have been modified so that they
|
||||
treat #nil the same as '().
|
||||
|
||||
- The Elisp t value is the same as #t.
|
||||
|
||||
** Emacs editing primitives
|
||||
|
||||
Buffers, keymaps, text properties, windows, frames etc. etc.
|
||||
|
||||
Basically, everything that is implemented as a primitive in the Emacs
|
||||
C code needs to be implemented either in Scheme or in C for Guile.
|
||||
|
||||
The Scheme files in the primitives subdirectory implement some of
|
||||
these primitives in Scheme. Not because that is the right decision,
|
||||
but because this is a proof of concept and it's quicker to write badly
|
||||
performing code in Scheme.
|
||||
|
||||
Ultimately, most of these primitive definitions should really come
|
||||
from the Emacs C code itself, translated or preprocessed in a way that
|
||||
makes it compile with Guile. I think this is pretty close to the work
|
||||
that Ken Raeburn has been doing on the Emacs codebase.
|
||||
|
||||
** Reading and printing support
|
||||
|
||||
Elisp is close enough to Scheme that it's convenient to coopt the
|
||||
existing Guile reader rather than to write a new one from scratch, but
|
||||
there are a few syntactic differences that will require changes in
|
||||
reading and printing. None of the following changes has yet been
|
||||
implemented.
|
||||
|
||||
- Character syntax is `?a' rather than `#\a'. (Not done. More
|
||||
precisely, `?a' in Elisp isn't character syntax but an alternative
|
||||
integer syntax. Note that we could support most of the `?a' syntax
|
||||
simply by doing
|
||||
|
||||
(define ?a (char->integer #\a)
|
||||
(define ?b (char->integer #\b)
|
||||
|
||||
and so on.)
|
||||
|
||||
- Vector syntax is `[1 2 3]' rather than `#(1 2 3)'.
|
||||
|
||||
- When in an Elisp environment, #nil and #t should print as `nil' and
|
||||
`t'.
|
||||
|
||||
** The Elisp evaluation module (lang elisp base)
|
||||
|
||||
Fundamentally, Guile's module system can't be used to package Elisp
|
||||
code in the same way it is used for Scheme code, because Elisp
|
||||
function definitions are stored as symbol properties (in the symbol's
|
||||
"function slot") and so are global. On the other hand, it is useful
|
||||
(necessary?) to associate some particular module with Elisp evaluation
|
||||
because
|
||||
|
||||
- Elisp variables are currently implemented as Scheme variables and so
|
||||
need to live in some module
|
||||
|
||||
- a syntax transformer is a property of a module.
|
||||
|
||||
Therefore we have the (lang elisp base) module, which acts as the
|
||||
repository for all Elisp variables and the site of all Elisp
|
||||
evaluation.
|
||||
|
||||
The initial environment provided by this module is intended to be a
|
||||
non-Emacs-dependent subset of Elisp. To get the idea, imagine someone
|
||||
who wants to write an extension function for, say Gnucash, and simply
|
||||
prefers to write in Elisp rather than in Scheme. He/she therefore
|
||||
doesn't buffers, keymaps and so on, just the basic language syntax and
|
||||
core data functions like +, *, concat, length etc., plus specific
|
||||
functions made available by Gnucash.
|
||||
|
||||
(lang elisp base) achieves this by
|
||||
|
||||
- importing Scheme definitions for some Emacs primitives from the
|
||||
files in the primitives subdirectory
|
||||
|
||||
- then switching into Elisp syntax.
|
||||
|
||||
After this point, `(eval XXX (resolve-module '(lang elisp base)))'
|
||||
will evaluate XXX as an Elisp expression in the (lang elisp base)
|
||||
module. (`eval-elisp' in (lang elisp interface) is a more convenient
|
||||
wrapper for this.)
|
||||
|
||||
** Full Emacs environment
|
||||
|
||||
The difference between the initial (lang elisp base) environment and a
|
||||
fully loaded Emacs equivalent is
|
||||
|
||||
- more primitives: buffers, char-tables and many others
|
||||
|
||||
- the bootstrap Elisp code that an undumped Emacs loads during
|
||||
installation by calling `(load "loadup.el")'.
|
||||
|
||||
We don't have all the missing primitives, but we can already get
|
||||
through some of loadup.el. The Elisp function `load-emacs' (defined
|
||||
in (lang elisp base) initiates the loading of loadup.el; (lang elisp
|
||||
interface) exports `load-emacs' to Scheme.
|
||||
|
||||
`load-emacs' loads so much Elisp code that it's an excellent way to
|
||||
test the translator. In current practice, it runs for a while and
|
||||
then fails when it gets to an undefined primitive or a bug in the
|
||||
translator. Eventually, it should go all the way. (And then we can
|
||||
worry about adding unexec support to Guile!) For the output that
|
||||
currently results from calling `(load-emacs)', see above in the Status
|
||||
section.
|
||||
|
||||
* Resources
|
||||
|
||||
** Ken Raeburn's Guile Emacs page
|
||||
|
||||
http://www.mit.edu/~raeburn/guilemacs/
|
||||
|
||||
** Keisuke Nishida's Gemacs project
|
||||
|
||||
http://gemacs.sourceforge.net
|
||||
|
||||
** Jim Blandy's nil/#f/() notes
|
||||
|
||||
http://sanpietro.red-bean.com/guile/guile/old/3114.html
|
||||
|
||||
Also now stored as guile-core/devel/translation/lisp-and-scheme.text
|
||||
in Guile CVS.
|
||||
|
||||
** Mikael Djurfeldt's notes on translation
|
||||
|
||||
See file guile-core/devel/translation/langtools.text in Guile CVS.
|
|
@ -1,35 +0,0 @@
|
|||
-*-text-*-
|
||||
|
||||
I've now finished my currently planned work on the Emacs Lisp
|
||||
translator in guile-core CVS.
|
||||
|
||||
It works well enough for experimentation and playing around with --
|
||||
see the README file for details of what it _can_ do -- but has two
|
||||
serious restrictions:
|
||||
|
||||
- Most Emacs Lisp primitives are not yet implemented. In particular,
|
||||
there are no buffer-related primitives.
|
||||
|
||||
- Performance compares badly with Emacs. Using a handful of
|
||||
completely unscientific tests, I found that Guile was between 2 and
|
||||
20 times slower than Emacs. (See the comment in
|
||||
lang/elisp/example.el for details of tests and results.)
|
||||
|
||||
Interestingly, both these restrictions point in the same direction:
|
||||
the way forward is to define the primitives by compiling a
|
||||
preprocessed version of the Emacs source code, not by trying to
|
||||
implement them in Scheme. (Which, of course, is what Ken Raeburn's
|
||||
project is already trying to do.)
|
||||
|
||||
Given this conclusion, I expect that most of the translator's Scheme
|
||||
code will eventually become obsolete, replaced by bits of Emacs C
|
||||
code. Until then, though, it should have a role:
|
||||
|
||||
- as a guide to the Guile Emacs project on how to interface to the
|
||||
Elisp support in libguile (notably, usage of `@fop' and `@bind')
|
||||
|
||||
- as a proof of concept and fun thing to experiment with
|
||||
|
||||
- as a working translator that could help us develop our picture of
|
||||
how we want to integrate translator usage in general with the rest
|
||||
of Guile.
|
|
@ -1,48 +0,0 @@
|
|||
(define-module (lang elisp base)
|
||||
|
||||
;; Be pure. Nothing in this module requires symbols that map to the
|
||||
;; standard Guile builtins, and it creates a problem if this module
|
||||
;; has access to them, as @bind can dynamically change their values.
|
||||
;; Transformer output always uses the values of builtin procedures
|
||||
;; and macros directly.
|
||||
#:pure
|
||||
|
||||
;; {Elisp Primitives}
|
||||
;;
|
||||
;; In other words, Scheme definitions of elisp primitives. This
|
||||
;; should (ultimately) include everything that Emacs defines in C.
|
||||
#:use-module (lang elisp primitives buffers)
|
||||
#:use-module (lang elisp primitives char-table)
|
||||
#:use-module (lang elisp primitives features)
|
||||
#:use-module (lang elisp primitives format)
|
||||
#:use-module (lang elisp primitives fns)
|
||||
#:use-module (lang elisp primitives guile)
|
||||
#:use-module (lang elisp primitives keymaps)
|
||||
#:use-module (lang elisp primitives lists)
|
||||
#:use-module (lang elisp primitives load)
|
||||
#:use-module (lang elisp primitives match)
|
||||
#:use-module (lang elisp primitives numbers)
|
||||
#:use-module (lang elisp primitives pure)
|
||||
#:use-module (lang elisp primitives read)
|
||||
#:use-module (lang elisp primitives signal)
|
||||
#:use-module (lang elisp primitives strings)
|
||||
#:use-module (lang elisp primitives symprop)
|
||||
#:use-module (lang elisp primitives syntax)
|
||||
#:use-module (lang elisp primitives system)
|
||||
#:use-module (lang elisp primitives time)
|
||||
|
||||
;; Now switch into Emacs Lisp syntax.
|
||||
#:use-syntax (lang elisp transform))
|
||||
|
||||
;;; Everything below here is written in Elisp.
|
||||
|
||||
(defun load-emacs (&optional new-load-path debug)
|
||||
(if debug (message "load-path: %s" load-path))
|
||||
(cond (new-load-path
|
||||
(message "Setting load-path to: %s" new-load-path)
|
||||
(setq load-path new-load-path)))
|
||||
(if debug (message "load-path: %s" load-path))
|
||||
(scheme (read-set! keywords 'prefix))
|
||||
(message "Calling loadup.el to clothe the bare Emacs...")
|
||||
(load "loadup.el")
|
||||
(message "Guile Emacs now fully clothed"))
|
|
@ -1,39 +0,0 @@
|
|||
|
||||
(defun html-page (title &rest contents)
|
||||
(concat "<HTML>\n"
|
||||
"<HEAD>\n"
|
||||
"<TITLE>" title "</TITLE>\n"
|
||||
"</HEAD>\n"
|
||||
"<BODY>\n"
|
||||
(apply 'concat contents)
|
||||
"</BODY>\n"
|
||||
"</HTML>\n"))
|
||||
|
||||
(defmacro time (repeat-count &rest body)
|
||||
`(let ((count ,repeat-count)
|
||||
(beg (current-time))
|
||||
end)
|
||||
(while (> count 0)
|
||||
(setq count (- count 1))
|
||||
,@body)
|
||||
(setq end (current-time))
|
||||
(+ (* 1000000.0 (+ (* 65536.0 (- (car end) (car beg)))
|
||||
(- (cadr end) (cadr beg))))
|
||||
(* 1.0 (- (caddr end) (caddr beg))))))
|
||||
|
||||
;Non-scientific performance measurements (Guile measurements are with
|
||||
;`guile -q --no-debug'):
|
||||
;
|
||||
;(time 100000 (+ 3 4))
|
||||
; => 225,071 (Emacs) 4,000,000 (Guile)
|
||||
;(time 100000 (lambda () 1))
|
||||
; => 2,410,456 (Emacs) 4,000,000 (Guile)
|
||||
;(time 100000 (apply 'concat (mapcar (lambda (s) (concat s "." s)) '("a" "b" "c" "d"))))
|
||||
; => 10,185,792 (Emacs) 136,000,000 (Guile)
|
||||
;(defun sc (s) (concat s "." s))
|
||||
;(time 100000 (apply 'concat (mapcar 'sc '("a" "b" "c" "d"))))
|
||||
; => 7,870,055 (Emacs) 26,700,000 (Guile)
|
||||
;
|
||||
;Sadly, it looks like the translator's performance sucks quite badly
|
||||
;when compared with Emacs. But the translator is still very new, so
|
||||
;there's probably plenty of room of improvement.
|
|
@ -1,4 +0,0 @@
|
|||
(define-module (lang elisp expand)
|
||||
#:export (expand))
|
||||
|
||||
(define (expand x) x)
|
|
@ -1,140 +0,0 @@
|
|||
(define-module (lang elisp interface)
|
||||
#:use-syntax (lang elisp expand)
|
||||
#:use-module (lang elisp internals evaluation)
|
||||
#:use-module (lang elisp internals fset)
|
||||
#:use-module ((lang elisp internals load) #:select ((load . elisp:load)))
|
||||
#:use-module ((lang elisp transform) #:select (transformer))
|
||||
#:export (eval-elisp
|
||||
translate-elisp
|
||||
elisp-function
|
||||
elisp-variable
|
||||
load-elisp-file
|
||||
load-elisp-library
|
||||
use-elisp-file
|
||||
use-elisp-library
|
||||
export-to-elisp
|
||||
load-emacs))
|
||||
|
||||
;;; This file holds my ideas for the mechanisms that would be useful
|
||||
;;; to exchange definitions between Scheme and Elisp.
|
||||
|
||||
(define (eval-elisp x)
|
||||
"Evaluate the Elisp expression @var{x}."
|
||||
(save-module-excursion
|
||||
(lambda ()
|
||||
(set-current-module the-elisp-module)
|
||||
(primitive-eval x))))
|
||||
|
||||
(define (translate-elisp x)
|
||||
"Translate the Elisp expression @var{x} to equivalent Scheme code."
|
||||
(transformer x))
|
||||
|
||||
(define (elisp-function sym)
|
||||
"Return the procedure or macro that implements @var{sym} in Elisp.
|
||||
If @var{sym} has no Elisp function definition, return @code{#f}."
|
||||
(fref sym))
|
||||
|
||||
(define (elisp-variable sym)
|
||||
"Return the variable that implements @var{sym} in Elisp.
|
||||
If @var{sym} has no Elisp variable definition, return @code{#f}."
|
||||
(module-variable the-elisp-module sym))
|
||||
|
||||
(define (load-elisp-file file-name)
|
||||
"Load @var{file-name} into the Elisp environment.
|
||||
@var{file-name} is assumed to name a file containing Elisp code."
|
||||
;; This is the same as Elisp's `load-file', so use that if it is
|
||||
;; available, otherwise duplicate the definition of `load-file' from
|
||||
;; files.el.
|
||||
(let ((load-file (elisp-function 'load-file)))
|
||||
(if load-file
|
||||
(load-file file-name)
|
||||
(elisp:load file-name #f #f #t))))
|
||||
|
||||
(define (load-elisp-library library)
|
||||
"Load library @var{library} into the Elisp environment.
|
||||
@var{library} should name an Elisp code library that can be found in
|
||||
one of the directories of @code{load-path}."
|
||||
;; This is the same as Elisp's `load-file', so use that if it is
|
||||
;; available, otherwise duplicate the definition of `load-file' from
|
||||
;; files.el.
|
||||
(let ((load-library (elisp-function 'load-library)))
|
||||
(if load-library
|
||||
(load-library library)
|
||||
(elisp:load library))))
|
||||
|
||||
(define export-module-name
|
||||
(let ((counter 0))
|
||||
(lambda ()
|
||||
(set! counter (+ counter 1))
|
||||
(list 'lang 'elisp
|
||||
(string->symbol (string-append "imports:"
|
||||
(number->string counter)))))))
|
||||
|
||||
(define use-elisp-file
|
||||
(procedure->memoizing-macro
|
||||
(lambda (exp env)
|
||||
"Load Elisp code file @var{file-name} and import its definitions
|
||||
into the current Scheme module. If any @var{imports} are specified,
|
||||
they are interpreted as selection and renaming specifiers as per
|
||||
@code{use-modules}."
|
||||
(let ((file-name (cadr exp))
|
||||
(env (cddr exp)))
|
||||
(let ((export-module-name (export-module-name)))
|
||||
`(begin
|
||||
(fluid-set! ,elisp-export-module (resolve-module ',export-module-name))
|
||||
(beautify-user-module! (resolve-module ',export-module-name))
|
||||
(load-elisp-file ,file-name)
|
||||
(use-modules (,export-module-name ,@imports))
|
||||
(fluid-set! ,elisp-export-module #f)))))))
|
||||
|
||||
(define use-elisp-library
|
||||
(procedure->memoizing-macro
|
||||
(lambda (exp env)
|
||||
"Load Elisp library @var{library} and import its definitions into
|
||||
the current Scheme module. If any @var{imports} are specified, they
|
||||
are interpreted as selection and renaming specifiers as per
|
||||
@code{use-modules}."
|
||||
(let ((library (cadr exp))
|
||||
(env (cddr exp)))
|
||||
(let ((export-module-name (export-module-name)))
|
||||
`(begin
|
||||
(fluid-set! ,elisp-export-module (resolve-module ',export-module-name))
|
||||
(beautify-user-module! (resolve-module ',export-module-name))
|
||||
(load-elisp-library ,library)
|
||||
(use-modules (,export-module-name ,@imports))
|
||||
(fluid-set! ,elisp-export-module #f)))))))
|
||||
|
||||
(define (export-to-elisp . defs)
|
||||
"Export procedures and variables specified by @var{defs} to Elisp.
|
||||
Each @var{def} is either an object, in which case that object must be
|
||||
a named procedure or macro and is exported to Elisp under its Scheme
|
||||
name; or a symbol, in which case the variable named by that symbol is
|
||||
exported under its Scheme name; or a pair @var{(obj . name)}, in which
|
||||
case @var{obj} must be a procedure, macro or symbol as already
|
||||
described and @var{name} specifies the name under which that object is
|
||||
exported to Elisp."
|
||||
(for-each (lambda (def)
|
||||
(let ((obj (if (pair? def) (car def) def))
|
||||
(name (if (pair? def) (cdr def) #f)))
|
||||
(cond ((procedure? obj)
|
||||
(or name
|
||||
(set! name (procedure-name obj)))
|
||||
(if name
|
||||
(fset name obj)
|
||||
(error "No procedure name specified or deducible:" obj)))
|
||||
((macro? obj)
|
||||
(or name
|
||||
(set! name (macro-name obj)))
|
||||
(if name
|
||||
(fset name obj)
|
||||
(error "No macro name specified or deducible:" obj)))
|
||||
((symbol? obj)
|
||||
(or name
|
||||
(set! name obj))
|
||||
(module-add! the-elisp-module name
|
||||
(module-ref (current-module) obj)))
|
||||
(else
|
||||
(error "Can't export this kind of object to Elisp:" obj)))))
|
||||
defs))
|
||||
|
||||
(define load-emacs (elisp-function 'load-emacs))
|
|
@ -1,13 +0,0 @@
|
|||
(define-module (lang elisp internals evaluation)
|
||||
#:export (the-elisp-module))
|
||||
|
||||
;;;; {Elisp Evaluation}
|
||||
|
||||
;;;; All elisp evaluation happens within the same module - namely
|
||||
;;;; (lang elisp base). This is necessary both because elisp itself
|
||||
;;;; has no concept of different modules - reflected for example in
|
||||
;;;; its single argument `eval' function - and because Guile's current
|
||||
;;;; implementation of elisp stores elisp function definitions in
|
||||
;;;; slots in global symbol objects.
|
||||
|
||||
(define the-elisp-module (resolve-module '(lang elisp base)))
|
|
@ -1,62 +0,0 @@
|
|||
(define-module (lang elisp internals format)
|
||||
#:pure
|
||||
#:use-module (ice-9 r5rs)
|
||||
#:use-module ((ice-9 format) #:select ((format . scheme:format)))
|
||||
#:use-module (lang elisp internals fset)
|
||||
#:use-module (lang elisp internals signal)
|
||||
#:replace (format)
|
||||
#:export (message))
|
||||
|
||||
(define (format control-string . args)
|
||||
|
||||
(define (cons-string str ls)
|
||||
(let loop ((sl (string->list str))
|
||||
(ls ls))
|
||||
(if (null? sl)
|
||||
ls
|
||||
(loop (cdr sl) (cons (car sl) ls)))))
|
||||
|
||||
(let loop ((input (string->list control-string))
|
||||
(args args)
|
||||
(output '())
|
||||
(mid-control #f))
|
||||
(if (null? input)
|
||||
(if mid-control
|
||||
(error "Format string ends in middle of format specifier")
|
||||
(list->string (reverse output)))
|
||||
(if mid-control
|
||||
(case (car input)
|
||||
((#\%)
|
||||
(loop (cdr input)
|
||||
args
|
||||
(cons #\% output)
|
||||
#f))
|
||||
(else
|
||||
(loop (cdr input)
|
||||
(cdr args)
|
||||
(cons-string (case (car input)
|
||||
((#\s) (scheme:format #f "~A" (car args)))
|
||||
((#\d) (number->string (car args)))
|
||||
((#\o) (number->string (car args) 8))
|
||||
((#\x) (number->string (car args) 16))
|
||||
((#\e) (number->string (car args))) ;FIXME
|
||||
((#\f) (number->string (car args))) ;FIXME
|
||||
((#\g) (number->string (car args))) ;FIXME
|
||||
((#\c) (let ((a (car args)))
|
||||
(if (char? a)
|
||||
(string a)
|
||||
(string (integer->char a)))))
|
||||
((#\S) (scheme:format #f "~S" (car args)))
|
||||
(else
|
||||
(error "Invalid format operation %%%c" (car input))))
|
||||
output)
|
||||
#f)))
|
||||
(case (car input)
|
||||
((#\%)
|
||||
(loop (cdr input) args output #t))
|
||||
(else
|
||||
(loop (cdr input) args (cons (car input) output) #f)))))))
|
||||
|
||||
(define (message control-string . args)
|
||||
(display (apply format control-string args))
|
||||
(newline))
|
|
@ -1,113 +0,0 @@
|
|||
(define-module (lang elisp internals fset)
|
||||
#:use-module (lang elisp internals evaluation)
|
||||
#:use-module (lang elisp internals lambda)
|
||||
#:use-module (lang elisp internals signal)
|
||||
#:export (fset
|
||||
fref
|
||||
fref/error-if-void
|
||||
elisp-apply
|
||||
interactive-specification
|
||||
not-subr?
|
||||
elisp-export-module))
|
||||
|
||||
(define the-variables-module (resolve-module '(lang elisp variables)))
|
||||
|
||||
;; By default, Guile GC's unreachable symbols. So we need to make
|
||||
;; sure they stay reachable!
|
||||
(define syms '())
|
||||
|
||||
;; elisp-export-module, if non-#f, holds a module to which definitions
|
||||
;; should be exported under their normal symbol names. This is used
|
||||
;; when importing Elisp definitions into Scheme.
|
||||
(define elisp-export-module (make-fluid))
|
||||
|
||||
;; Store the procedure, macro or alias symbol PROC in SYM's function
|
||||
;; slot.
|
||||
(define (fset sym proc)
|
||||
(or (memq sym syms)
|
||||
(set! syms (cons sym syms)))
|
||||
(let ((vcell (symbol-fref sym))
|
||||
(vsym #f)
|
||||
(export-module (fluid-ref elisp-export-module)))
|
||||
;; Playing around with variables and name properties... For the
|
||||
;; reasoning behind this, see the commentary in (lang elisp
|
||||
;; variables).
|
||||
(cond ((procedure? proc)
|
||||
;; A procedure created from Elisp will already have a name
|
||||
;; property attached, with value of the form
|
||||
;; <elisp-defun:NAME> or <elisp-lambda>. Any other
|
||||
;; procedure coming through here must be an Elisp primitive
|
||||
;; definition, so we give it a name of the form
|
||||
;; <elisp-subr:NAME>.
|
||||
(or (procedure-name proc)
|
||||
(set-procedure-property! proc
|
||||
'name
|
||||
(symbol-append '<elisp-subr: sym '>)))
|
||||
(set! vsym (procedure-name proc)))
|
||||
((macro? proc)
|
||||
;; Macros coming through here must be defmacros, as all
|
||||
;; primitive special forms are handled directly by the
|
||||
;; transformer.
|
||||
(set-procedure-property! (macro-transformer proc)
|
||||
'name
|
||||
(symbol-append '<elisp-defmacro: sym '>))
|
||||
(set! vsym (procedure-name (macro-transformer proc))))
|
||||
(else
|
||||
;; An alias symbol.
|
||||
(set! vsym (symbol-append '<elisp-defalias: sym '>))))
|
||||
;; This is the important bit!
|
||||
(if (variable? vcell)
|
||||
(variable-set! vcell proc)
|
||||
(begin
|
||||
(set! vcell (make-variable proc))
|
||||
(symbol-fset! sym vcell)
|
||||
;; Playing with names and variables again - see above.
|
||||
(module-add! the-variables-module vsym vcell)
|
||||
(module-export! the-variables-module (list vsym))))
|
||||
;; Export variable to the export module, if non-#f.
|
||||
(if (and export-module
|
||||
(or (procedure? proc)
|
||||
(macro? proc)))
|
||||
(begin
|
||||
(module-add! export-module sym vcell)
|
||||
(module-export! export-module (list sym))))))
|
||||
|
||||
;; Retrieve the procedure or macro stored in SYM's function slot.
|
||||
;; Note the asymmetry w.r.t. fset: if fref finds an alias symbol, it
|
||||
;; recursively calls fref on that symbol. Returns #f if SYM's
|
||||
;; function slot doesn't contain a valid definition.
|
||||
(define (fref sym)
|
||||
(let ((var (symbol-fref sym)))
|
||||
(if (and var (variable? var))
|
||||
(let ((proc (variable-ref var)))
|
||||
(cond ((symbol? proc)
|
||||
(fref proc))
|
||||
(else
|
||||
proc)))
|
||||
#f)))
|
||||
|
||||
;; Same as fref, but signals an Elisp error if SYM's function
|
||||
;; definition is void.
|
||||
(define (fref/error-if-void sym)
|
||||
(or (fref sym)
|
||||
(signal 'void-function (list sym))))
|
||||
|
||||
;; Maps a procedure to its (interactive ...) spec.
|
||||
(define interactive-specification (make-object-property))
|
||||
|
||||
;; Maps a procedure to #t if it is NOT a built-in.
|
||||
(define not-subr? (make-object-property))
|
||||
|
||||
(define (elisp-apply function . args)
|
||||
(apply apply
|
||||
(cond ((symbol? function)
|
||||
(fref/error-if-void function))
|
||||
((procedure? function)
|
||||
function)
|
||||
((and (pair? function)
|
||||
(eq? (car function) 'lambda))
|
||||
(eval (transform-lambda/interactive function '<elisp-lambda>)
|
||||
the-root-module))
|
||||
(else
|
||||
(signal 'invalid-function (list function))))
|
||||
args))
|
|
@ -1,109 +0,0 @@
|
|||
(define-module (lang elisp internals lambda)
|
||||
#:use-syntax (lang elisp expand)
|
||||
#:use-module (lang elisp internals fset)
|
||||
#:use-module (lang elisp transform)
|
||||
#:export (parse-formals
|
||||
transform-lambda/interactive
|
||||
interactive-spec))
|
||||
|
||||
;;; Parses a list of elisp formals, e.g. (x y &optional b &rest r) and
|
||||
;;; returns three values: (i) list of symbols for required arguments,
|
||||
;;; (ii) list of symbols for optional arguments, (iii) rest symbol, or
|
||||
;;; #f if there is no rest argument.
|
||||
(define (parse-formals formals)
|
||||
(letrec ((do-required
|
||||
(lambda (required formals)
|
||||
(if (null? formals)
|
||||
(values (reverse required) '() #f)
|
||||
(let ((next-sym (car formals)))
|
||||
(cond ((not (symbol? next-sym))
|
||||
(error "Bad formals (non-symbol in required list)"))
|
||||
((eq? next-sym '&optional)
|
||||
(do-optional required '() (cdr formals)))
|
||||
((eq? next-sym '&rest)
|
||||
(do-rest required '() (cdr formals)))
|
||||
(else
|
||||
(do-required (cons next-sym required)
|
||||
(cdr formals))))))))
|
||||
(do-optional
|
||||
(lambda (required optional formals)
|
||||
(if (null? formals)
|
||||
(values (reverse required) (reverse optional) #f)
|
||||
(let ((next-sym (car formals)))
|
||||
(cond ((not (symbol? next-sym))
|
||||
(error "Bad formals (non-symbol in optional list)"))
|
||||
((eq? next-sym '&rest)
|
||||
(do-rest required optional (cdr formals)))
|
||||
(else
|
||||
(do-optional required
|
||||
(cons next-sym optional)
|
||||
(cdr formals))))))))
|
||||
(do-rest
|
||||
(lambda (required optional formals)
|
||||
(if (= (length formals) 1)
|
||||
(let ((next-sym (car formals)))
|
||||
(if (symbol? next-sym)
|
||||
(values (reverse required) (reverse optional) next-sym)
|
||||
(error "Bad formals (non-symbol rest formal)")))
|
||||
(error "Bad formals (more than one rest formal)")))))
|
||||
|
||||
(do-required '() (cond ((list? formals)
|
||||
formals)
|
||||
((symbol? formals)
|
||||
(list '&rest formals))
|
||||
(else
|
||||
(error "Bad formals (not a list or a single symbol)"))))))
|
||||
|
||||
(define (transform-lambda exp)
|
||||
(call-with-values (lambda () (parse-formals (cadr exp)))
|
||||
(lambda (required optional rest)
|
||||
(let ((num-required (length required))
|
||||
(num-optional (length optional)))
|
||||
`(,lambda %--args
|
||||
(,let ((%--num-args (,length %--args)))
|
||||
(,cond ((,< %--num-args ,num-required)
|
||||
(,error "Wrong number of args (not enough required args)"))
|
||||
,@(if rest
|
||||
'()
|
||||
`(((,> %--num-args ,(+ num-required num-optional))
|
||||
(,error "Wrong number of args (too many args)"))))
|
||||
(else
|
||||
(, @bind ,(append (map (lambda (i)
|
||||
(list (list-ref required i)
|
||||
`(,list-ref %--args ,i)))
|
||||
(iota num-required))
|
||||
(map (lambda (i)
|
||||
(let ((i+nr (+ i num-required)))
|
||||
(list (list-ref optional i)
|
||||
`(,if (,> %--num-args ,i+nr)
|
||||
(,list-ref %--args ,i+nr)
|
||||
,%nil))))
|
||||
(iota num-optional))
|
||||
(if rest
|
||||
(list (list rest
|
||||
`(,if (,> %--num-args
|
||||
,(+ num-required
|
||||
num-optional))
|
||||
(,list-tail %--args
|
||||
,(+ num-required
|
||||
num-optional))
|
||||
,%nil)))
|
||||
'()))
|
||||
,@(map transformer (cddr exp)))))))))))
|
||||
|
||||
(define (set-not-subr! proc boolean)
|
||||
(set! (not-subr? proc) boolean))
|
||||
|
||||
(define (transform-lambda/interactive exp name)
|
||||
(fluid-set! interactive-spec #f)
|
||||
(let* ((x (transform-lambda exp))
|
||||
(is (fluid-ref interactive-spec)))
|
||||
`(,let ((%--lambda ,x))
|
||||
(,set-procedure-property! %--lambda (,quote name) (,quote ,name))
|
||||
(,set-not-subr! %--lambda #t)
|
||||
,@(if is
|
||||
`((,set! (,interactive-specification %--lambda) (,quote ,is)))
|
||||
'())
|
||||
%--lambda)))
|
||||
|
||||
(define interactive-spec (make-fluid))
|
|
@ -1,44 +0,0 @@
|
|||
(define-module (lang elisp internals load)
|
||||
#:use-module (ice-9 optargs)
|
||||
#:use-module (lang elisp internals signal)
|
||||
#:use-module (lang elisp internals format)
|
||||
#:use-module (lang elisp internals evaluation)
|
||||
#:replace (load)
|
||||
#:export (load-path))
|
||||
|
||||
(define load-path '("/usr/share/emacs/20.7/lisp/"
|
||||
"/usr/share/emacs/20.7/lisp/emacs-lisp/"))
|
||||
|
||||
(define* (load file #:optional noerror nomessage nosuffix must-suffix)
|
||||
(define (load1 filename)
|
||||
(let ((pathname (let loop ((dirs (if (char=? (string-ref filename 0) #\/)
|
||||
'("")
|
||||
load-path)))
|
||||
(cond ((null? dirs) #f)
|
||||
((file-exists? (in-vicinity (car dirs) filename))
|
||||
(in-vicinity (car dirs) filename))
|
||||
(else (loop (cdr dirs)))))))
|
||||
(if pathname
|
||||
(begin
|
||||
(or nomessage
|
||||
(message "Loading %s..." pathname))
|
||||
(with-input-from-file pathname
|
||||
(lambda ()
|
||||
(let loop ((form (read)))
|
||||
(or (eof-object? form)
|
||||
(begin
|
||||
;; Note that `eval' already incorporates use
|
||||
;; of the specified module's transformer.
|
||||
(eval form the-elisp-module)
|
||||
(loop (read)))))))
|
||||
(or nomessage
|
||||
(message "Loading %s...done" pathname))
|
||||
#t)
|
||||
#f)))
|
||||
(or (and (not nosuffix)
|
||||
(load1 (string-append file ".el")))
|
||||
(and (not must-suffix)
|
||||
(load1 file))
|
||||
noerror
|
||||
(signal 'file-error
|
||||
(list "Cannot open load file" file))))
|
|
@ -1,13 +0,0 @@
|
|||
(define-module (lang elisp internals null)
|
||||
#:export (->nil lambda->nil null))
|
||||
|
||||
(define (->nil x)
|
||||
(or x %nil))
|
||||
|
||||
(define (lambda->nil proc)
|
||||
(lambda args
|
||||
(->nil (apply proc args))))
|
||||
|
||||
(define (null obj)
|
||||
(->nil (or (not obj)
|
||||
(null? obj))))
|
|
@ -1,20 +0,0 @@
|
|||
(define-module (lang elisp internals set)
|
||||
#:use-module (lang elisp internals evaluation)
|
||||
#:use-module (lang elisp internals signal)
|
||||
#:export (set value))
|
||||
|
||||
;; Set SYM's variable value to VAL, and return VAL.
|
||||
(define (set sym val)
|
||||
(if (module-defined? the-elisp-module sym)
|
||||
(module-set! the-elisp-module sym val)
|
||||
(module-define! the-elisp-module sym val))
|
||||
val)
|
||||
|
||||
;; Return SYM's variable value. If it has none, signal an error if
|
||||
;; MUST-EXIST is true, just return #nil otherwise.
|
||||
(define (value sym must-exist)
|
||||
(if (module-defined? the-elisp-module sym)
|
||||
(module-ref the-elisp-module sym)
|
||||
(if must-exist
|
||||
(error "Symbol's value as variable is void:" sym)
|
||||
%nil)))
|
|
@ -1,18 +0,0 @@
|
|||
(define-module (lang elisp internals signal)
|
||||
#:use-module (lang elisp internals format)
|
||||
#:replace (error)
|
||||
#:export (signal
|
||||
wta))
|
||||
|
||||
(define (signal error-symbol data)
|
||||
(scm-error 'elisp-signal
|
||||
#f
|
||||
"Signalling ~A with data ~S"
|
||||
(list error-symbol data)
|
||||
#f))
|
||||
|
||||
(define (error . args)
|
||||
(signal 'error (list (apply format args))))
|
||||
|
||||
(define (wta expected actual pos)
|
||||
(signal 'wrong-type-argument (list expected actual)))
|
|
@ -1,14 +0,0 @@
|
|||
(define-module (lang elisp internals time)
|
||||
#:use-module (ice-9 optargs)
|
||||
#:export (format-time-string))
|
||||
|
||||
(define* (format-time-string format-string #:optional time universal)
|
||||
(strftime format-string
|
||||
((if universal gmtime localtime)
|
||||
(if time
|
||||
(+ (ash (car time) 16)
|
||||
(let ((time-cdr (cdr time)))
|
||||
(if (pair? time-cdr)
|
||||
(car time-cdr)
|
||||
time-cdr)))
|
||||
(current-time)))))
|
|
@ -1,28 +0,0 @@
|
|||
(define-module (lang elisp internals trace)
|
||||
#:export (trc trc-syms trc-all trc-none))
|
||||
|
||||
(define *syms* #f)
|
||||
|
||||
(define (trc-syms . syms)
|
||||
(set! *syms* syms))
|
||||
|
||||
(define (trc-all)
|
||||
(set! *syms* #f))
|
||||
|
||||
(define (trc-none)
|
||||
(set! *syms* '()))
|
||||
|
||||
(define (trc . args)
|
||||
(let ((sym (car args))
|
||||
(args (cdr args)))
|
||||
(if (or (and *syms*
|
||||
(memq sym *syms*))
|
||||
(not *syms*))
|
||||
(begin
|
||||
(write sym)
|
||||
(display ": ")
|
||||
(write args)
|
||||
(newline)))))
|
||||
|
||||
;; Default to no tracing.
|
||||
(trc-none)
|
|
@ -1,16 +0,0 @@
|
|||
(define-module (lang elisp primitives buffers)
|
||||
#:use-module (ice-9 optargs)
|
||||
#:use-module (lang elisp internals fset))
|
||||
|
||||
(fset 'buffer-disable-undo
|
||||
(lambda* (#:optional buffer)
|
||||
'unimplemented))
|
||||
|
||||
(fset 're-search-forward
|
||||
(lambda* (regexp #:optional bound noerror count)
|
||||
'unimplemented))
|
||||
|
||||
(fset 're-search-backward
|
||||
(lambda* (regexp #:optional bound noerror count)
|
||||
'unimplemented))
|
||||
|
|
@ -1,24 +0,0 @@
|
|||
(define-module (lang elisp primitives char-table)
|
||||
#:use-module (lang elisp internals fset)
|
||||
#:use-module (lang elisp internals null)
|
||||
#:use-module (ice-9 optargs))
|
||||
|
||||
(fset 'make-char-table
|
||||
(lambda* (purpose #:optional init)
|
||||
"Return a newly created char-table, with purpose PURPOSE.
|
||||
Each element is initialized to INIT, which defaults to nil.
|
||||
PURPOSE should be a symbol which has a `char-table-extra-slots' property.
|
||||
The property's value should be an integer between 0 and 10."
|
||||
(list purpose (vector init))))
|
||||
|
||||
(fset 'define-charset
|
||||
(lambda (charset-id charset-symbol info-vector)
|
||||
(list 'charset charset-id charset-symbol info-vector)))
|
||||
|
||||
(fset 'setup-special-charsets
|
||||
(lambda ()
|
||||
'unimplemented))
|
||||
|
||||
(fset 'make-char-internal
|
||||
(lambda ()
|
||||
'unimplemented))
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue