mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-06-16 16:50:21 +02:00
Merge branch 'stable-2.2' into compile-to-js-2017
This commit is contained in:
commit
1b36a76ea4
859 changed files with 56134 additions and 56340 deletions
5
.gitignore
vendored
5
.gitignore
vendored
|
@ -16,6 +16,7 @@ config.h
|
|||
*.x
|
||||
*.lo
|
||||
*.la
|
||||
*.exe
|
||||
aclocal.m4
|
||||
libtool
|
||||
ltmain.sh
|
||||
|
@ -142,6 +143,7 @@ INSTALL
|
|||
/test-suite/standalone/test-scm-spawn-thread
|
||||
/test-suite/standalone/test-pthread-create
|
||||
/test-suite/standalone/test-pthread-create-secondary
|
||||
/test-suite/standalone/test-smob-mark-race
|
||||
/lib/fcntl.h
|
||||
/lib/sys/uio.h
|
||||
/lib/stdalign.h
|
||||
|
@ -163,3 +165,6 @@ INSTALL
|
|||
/libguile/vm-operations.h
|
||||
/test-suite/standalone/test-foreign-object-c
|
||||
/test-suite/standalone/test-srfi-4
|
||||
/meta/build-env
|
||||
/lib/limits.h
|
||||
/lib/stdint.h
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
--user ludo@gnu.org
|
60
ANNOUNCE
60
ANNOUNCE
|
@ -1,60 +0,0 @@
|
|||
We are pleased to announce the release of Guile 1.8.0. It can be
|
||||
found here:
|
||||
|
||||
ftp://ftp.gnu.org/gnu/guile/guile-1.8.0.tar.gz
|
||||
|
||||
Its SHA1 checksum is
|
||||
|
||||
22462680feeda1e5400195c01dee666162503d66 guile-1.8.0.tar.gz
|
||||
|
||||
We already know about some issues with 1.8.0, please check the mailing
|
||||
lists:
|
||||
|
||||
http://www.gnu.org/software/guile/mail/mail.html
|
||||
|
||||
The NEWS file is quite long. Here are the most interesting entries:
|
||||
|
||||
Changes since 1.6:
|
||||
|
||||
* Guile is now licensed with the GNU Lesser General Public License.
|
||||
|
||||
* The manual is now licensed with the GNU Free Documentation License.
|
||||
|
||||
* We now use GNU MP for bignums.
|
||||
|
||||
* We now have exact rationals, such as 1/3.
|
||||
|
||||
* We now use native POSIX threads for real concurrent threads.
|
||||
|
||||
* There is a new way to initalize Guile that allows one to use Guile
|
||||
from threads that have not been created by Guile.
|
||||
|
||||
* Mutexes and condition variables are now always fair. A recursive
|
||||
mutex must be requested explicitly.
|
||||
|
||||
* The low-level thread API has been removed.
|
||||
|
||||
* There is now support for copy-on-write substrings and
|
||||
mutation-sharing substrings.
|
||||
|
||||
* A new family of functions for converting between C values and
|
||||
Scheme values has been added that is future-proof and thread-safe.
|
||||
|
||||
* The INUM macros like SCM_MAKINUM have been deprecated.
|
||||
|
||||
* The macros SCM_STRINGP, SCM_STRING_CHARS, SCM_STRING_LENGTH,
|
||||
SCM_SYMBOL_CHARS, and SCM_SYMBOL_LENGTH have been deprecated.
|
||||
|
||||
* There is a new way to deal with non-local exits and re-entries in
|
||||
C code, which is nicer than scm_internal_dynamic_wind.
|
||||
|
||||
* There are new malloc-like functions that work better than
|
||||
scm_must_malloc, etc.
|
||||
|
||||
* There is a new way to access all kinds of vectors and arrays from
|
||||
C that is efficient and thread-safe.
|
||||
|
||||
* The concept of dynamic roots has been factored into continuation
|
||||
barriers and dynamic states.
|
||||
|
||||
See NEWS and the manual for more details.
|
|
@ -5,7 +5,7 @@
|
|||
# It is necessary if you want to build targets usually of interest
|
||||
# only to the maintainer.
|
||||
|
||||
# Copyright (C) 2001, 2003, 2006-2014 Free Software Foundation, Inc.
|
||||
# Copyright (C) 2001, 2003, 2006-2017 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
|
||||
|
|
|
@ -2,8 +2,8 @@
|
|||
|
||||
# Note: `GUILE_VERSION' is defined in `configure.ac' using `git-version-gen'.
|
||||
GUILE_MAJOR_VERSION=2
|
||||
GUILE_MINOR_VERSION=1
|
||||
GUILE_MICRO_VERSION=0
|
||||
GUILE_MINOR_VERSION=2
|
||||
GUILE_MICRO_VERSION=2
|
||||
|
||||
GUILE_EFFECTIVE_VERSION=2.2
|
||||
|
||||
|
@ -16,7 +16,7 @@ GUILE_EFFECTIVE_VERSION=2.2
|
|||
# See libtool info pages for more information on how and when to
|
||||
# change these.
|
||||
|
||||
LIBGUILE_INTERFACE_CURRENT=0
|
||||
LIBGUILE_INTERFACE_CURRENT=3
|
||||
LIBGUILE_INTERFACE_REVISION=0
|
||||
LIBGUILE_INTERFACE_AGE=0
|
||||
LIBGUILE_INTERFACE_AGE=2
|
||||
LIBGUILE_INTERFACE="${LIBGUILE_INTERFACE_CURRENT}:${LIBGUILE_INTERFACE_REVISION}:${LIBGUILE_INTERFACE_AGE}"
|
||||
|
|
121
HACKING
121
HACKING
|
@ -1,6 +1,6 @@
|
|||
-*-text-*-
|
||||
Guile Hacking Guide
|
||||
Copyright (c) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2008, 2012 Free software Foundation, Inc.
|
||||
Copyright (c) 1996-2002,2008,2012,2015,2017 Free Software Foundation, Inc.
|
||||
|
||||
Permission is granted to anyone to make or distribute verbatim copies
|
||||
of this document as received, in any medium, provided that the
|
||||
|
@ -20,13 +20,8 @@ What to Hack =========================================================
|
|||
|
||||
You can hack whatever you want, thank GNU.
|
||||
|
||||
However, to see what others have indicated as their interest (and avoid
|
||||
potential wasteful duplication of effort), see file TODO. Note that
|
||||
the version you find may be out of date; a CVS checkout is recommended:
|
||||
see below for details (see also the files ANON-CVS and SNAPSHOTS).
|
||||
|
||||
It's also a good idea to join the guile-devel@gnu.org mailing list.
|
||||
See http://www.gnu.org/software/guile/mail/mail.html for more info.
|
||||
It's a good idea to join the guile-devel@gnu.org mailing list. See
|
||||
http://www.gnu.org/software/guile/mail/mail.html for more info.
|
||||
|
||||
|
||||
Hacking It Yourself ==================================================
|
||||
|
@ -69,7 +64,7 @@ gettext --- a system for rigging a program so that it can output its
|
|||
itself.
|
||||
|
||||
flex --- a scanner generator. It's probably not essential to have the
|
||||
latest version.
|
||||
latest version; Flex 2.5.37 is known to work.
|
||||
|
||||
One false move and you will be lost in a little maze of automatically
|
||||
generated files, all different.
|
||||
|
@ -77,67 +72,11 @@ generated files, all different.
|
|||
Here is the authoritative list of tool/version/platform tuples that
|
||||
have been known to cause problems, and a short description of the problem.
|
||||
|
||||
- automake 1.4 adds extraneous rules to the top-level Makefile if
|
||||
you specify specific Makefiles to rebuild on the command line.
|
||||
|
||||
- automake 1.4-p4 (debian "1:1.4-p4-1.1") all platforms
|
||||
automake "include" facility does not recognize filenames w/ "-".
|
||||
|
||||
- libtool 1.4 uses acconfig.h, which is deprecated by newest autoconf
|
||||
(which constructs the equivalent through 3rd arg of AC_DEFINE forms).
|
||||
|
||||
- autoreconf from autoconf prior to 2.59 will run gettextize, which
|
||||
will mess up the Guile tree.
|
||||
|
||||
- libtool 1.5.26 does not know that it should remove the -R options
|
||||
that the Gnulib libunistring and havelib modules generate (because
|
||||
gcc doesn't actually support -R).
|
||||
|
||||
- (add here.)
|
||||
|
||||
|
||||
Sample GDB Initialization File=========================================
|
||||
|
||||
Here is a sample .gdbinit posted by Bill Schottstaedt (modified to
|
||||
use `set' instead of `call' in some places):
|
||||
|
||||
define gp
|
||||
set gdb_print($arg0)
|
||||
print gdb_output
|
||||
end
|
||||
document gp
|
||||
Executes (object->string arg)
|
||||
end
|
||||
|
||||
define ge
|
||||
call gdb_read($arg0)
|
||||
call gdb_eval(gdb_result)
|
||||
set gdb_print(gdb_result)
|
||||
print gdb_output
|
||||
end
|
||||
document ge
|
||||
Executes (print (eval (read arg))): ge "(+ 1 2)" => 3
|
||||
end
|
||||
|
||||
define gh
|
||||
call g_help(scm_str2symbol($arg0), 20)
|
||||
set gdb_print($1)
|
||||
print gdb_output
|
||||
end
|
||||
document gh
|
||||
Prints help string for arg: gh "enved-target"
|
||||
end
|
||||
|
||||
Bill further writes:
|
||||
|
||||
so in gdb if you see something useless like:
|
||||
|
||||
#32 0x081ae8f4 in scm_primitive_load (filename=1112137128) at load.c:129
|
||||
|
||||
You can get the file name with gp:
|
||||
|
||||
(gdb) gp 1112137128
|
||||
$1 = 0x40853fac "\"/home/bil/test/share/guile/1.5.0/ice-9/session.scm\""
|
||||
In GDB, you probably want to load the gdbinit file included with Guile,
|
||||
which defines a number of GDB helpers to inspect Scheme values.
|
||||
|
||||
|
||||
Contributing Your Changes ============================================
|
||||
|
@ -178,19 +117,15 @@ To make sure of this, you can use the --enable-error-on-warning option
|
|||
to configure. This option will make GCC fail if it hits a warning.
|
||||
|
||||
Note that the warnings generated vary from one version of GCC to the
|
||||
next, and from one architecture to the next (apparently). To provide
|
||||
a concrete common standard, Guile should compile without warnings from
|
||||
GCC 2.7.2.3 in a Red Hat 5.2 i386 Linux machine. Furthermore, each
|
||||
developer should pursue any additional warnings noted by on their
|
||||
compiler. This means that people using more stringent compilers will
|
||||
have more work to do, and assures that everyone won't switch to the
|
||||
most lenient compiler they can find. :)
|
||||
next, and from one architecture to the next. For this reason,
|
||||
--enable-error-on-warning is not enabled by default.
|
||||
|
||||
- If you add code which uses functions or other features that are not
|
||||
entirely portable, please make sure the rest of Guile will still
|
||||
function properly on systems where they are missing. This usually
|
||||
entails adding a test to configure.in, and then adding #ifdefs to your
|
||||
code to disable it if the system's features are missing.
|
||||
code to disable it if the system's features are missing. Do check first
|
||||
if the function has a Gnulib wrapper, though.
|
||||
|
||||
- The normal way of removing a function, macro or variable is to mark
|
||||
it as "deprecated", keep it for a while, and remove it in a later
|
||||
|
@ -224,10 +159,6 @@ When deprecating a definition, always follow this procedure:
|
|||
4. Add an entry that the definition has been deprecated in NEWS and
|
||||
explain what to do instead.
|
||||
|
||||
5. In file TODO, there is a list of releases with reminders about what
|
||||
to do at each release. Add a reminder about the removal of the
|
||||
deprecated defintion at the appropriate release.
|
||||
|
||||
- Write commit messages for functions written in C using the
|
||||
functions' C names, and write entries for functions written in Scheme
|
||||
using the functions' Scheme names. For example,
|
||||
|
@ -265,12 +196,12 @@ Maintainers of GNU Software":
|
|||
has signed copyright papers, and that the Free Software Foundation has
|
||||
received them.
|
||||
|
||||
If you receive contributions you want to use from someone, let me know
|
||||
and I'll take care of the administrivia. Put the contributions aside
|
||||
until we have the necessary papers.
|
||||
If you receive contributions you want to use from someone, let a
|
||||
maintainer know and they will take care of the administrivia. Put the
|
||||
contributions aside until we have the necessary papers.
|
||||
|
||||
Once you accept a contribution, be sure to keep the files AUTHORS and
|
||||
THANKS uptodate.
|
||||
THANKS up-to-date.
|
||||
|
||||
- When you make substantial changes to a file, add the current year to
|
||||
the list of years in the copyright notice at the top of the file.
|
||||
|
@ -324,27 +255,3 @@ The follwing syllables also have a technical meaning:
|
|||
str - this denotes a zero terminated C string
|
||||
|
||||
mem - a C string with an explicit count
|
||||
|
||||
|
||||
See also the file `devel/names.text'.
|
||||
|
||||
|
||||
Helpful hints ========================================================
|
||||
|
||||
- [From Mikael Djurfeldt] When working on the Guile internals, it is
|
||||
quite often practical to implement a scheme-level procedure which
|
||||
helps you examine the feature you're working on.
|
||||
|
||||
Examples of such procedures are: pt-size, debug-hand and
|
||||
current-pstate.
|
||||
|
||||
I've now put #ifdef GUILE_DEBUG around all such procedures, so that
|
||||
they are not compiled into the "normal" Guile library. Please do the
|
||||
same when you add new procedures/C functions for debugging purpose.
|
||||
|
||||
You can define the GUILE_DEBUG flag by passing --enable-guile-debug to
|
||||
the configure script.
|
||||
|
||||
|
||||
Jim Blandy, and others
|
||||
|
||||
|
|
17
Makefile.am
17
Makefile.am
|
@ -2,7 +2,7 @@
|
|||
##
|
||||
## Copyright (C) 1998, 1999, 2000, 2001, 2002, 2006, 2007,
|
||||
## 2008, 2009, 2010, 2011, 2012, 2013,
|
||||
## 2014 Free Software Foundation, Inc.
|
||||
## 2014, 2015, 2016 Free Software Foundation, Inc.
|
||||
##
|
||||
## This file is part of GUILE.
|
||||
##
|
||||
|
@ -30,6 +30,7 @@ SUBDIRS = \
|
|||
lib \
|
||||
meta \
|
||||
libguile \
|
||||
bootstrap \
|
||||
module \
|
||||
guile-readline \
|
||||
examples \
|
||||
|
@ -40,6 +41,8 @@ SUBDIRS = \
|
|||
am \
|
||||
doc
|
||||
|
||||
DIST_SUBDIRS = $(SUBDIRS) prebuilt
|
||||
|
||||
libguileincludedir = $(pkgincludedir)/$(GUILE_EFFECTIVE_VERSION)
|
||||
libguileinclude_HEADERS = libguile.h
|
||||
|
||||
|
@ -88,7 +91,7 @@ DISTCLEANFILES = check-guile.log
|
|||
|
||||
DISTCHECK_CONFIGURE_FLAGS = --enable-error-on-warning
|
||||
|
||||
dist-hook: gen-ChangeLog gen-tarball-version
|
||||
dist-hook: gen-ChangeLog gen-tarball-version assert-no-store-file-names
|
||||
|
||||
clean-local:
|
||||
rm -rf cache/
|
||||
|
@ -105,6 +108,16 @@ gen-ChangeLog:
|
|||
mv $(distdir)/cl-t $(distdir)/ChangeLog; \
|
||||
fi
|
||||
|
||||
# Make sure we're not shipping a file that embeds a /gnu/store file
|
||||
# name, for maintainers who use Guix.
|
||||
.PHONY: assert-no-store-file-names
|
||||
assert-no-store-file-names:
|
||||
if grep -rE "/gnu/store/[a-z0-9]{32}-" $(distdir) ; \
|
||||
then \
|
||||
echo "error: store file names embedded in the distribution" >&2 ; \
|
||||
exit 1 ; \
|
||||
fi
|
||||
|
||||
BUILT_SOURCES += $(top_srcdir)/.version
|
||||
$(top_srcdir)/.version:
|
||||
echo $(VERSION) > $@-t && mv $@-t $@
|
||||
|
|
877
NEWS
877
NEWS
|
@ -1,12 +1,149 @@
|
|||
Guile NEWS --- history of user-visible changes.
|
||||
Copyright (C) 1996-2015 Free Software Foundation, Inc.
|
||||
Copyright (C) 1996-2017 Free Software Foundation, Inc.
|
||||
See the end for copying conditions.
|
||||
|
||||
Please send Guile bug reports to bug-guile@gnu.org.
|
||||
|
||||
|
||||
|
||||
Changes in 2.1.1 (changes since the 2.0.x series):
|
||||
Changes in 2.2.3 (since 2.2.2):
|
||||
|
||||
* New interfaces
|
||||
|
||||
** (web uri) module has better support for RFC 3986
|
||||
|
||||
The URI standard, RFC 3986, defines additional "relative-ref" and
|
||||
"URI-reference" data types. Thanks to Daniel Hartwig, Guile's support
|
||||
for these URI subtypes has been improved. See "Universal Resource
|
||||
Identifiers" in the manual, for more.
|
||||
|
||||
* New deprecations
|
||||
|
||||
** Using `uri?' as a predicate on relative-refs deprecated
|
||||
|
||||
If you don't care whether the URI is a relative-ref or not, use
|
||||
`uri-reference?'. If you do, use `uri-reference?' and `relative-ref?'.
|
||||
In the future `uri?' will return a true value only for URIs that specify
|
||||
a scheme.
|
||||
|
||||
* Bug fixes
|
||||
|
||||
** Enable GNU Readline 7.0's support for "bracketed paste".
|
||||
|
||||
Before, when pasting an expression that contained TAB characters into
|
||||
Guile's REPL with GNU Readline support enabled, the pasted TAB
|
||||
characters would trigger autocompletion in Readline. This was never
|
||||
what you wanted. Guile now sets the new "bracketed-paste" option in GNU
|
||||
Readline 7.0 to on by default, making readline treat pastes into the
|
||||
terminal as atomic units without control characters. See "Readline
|
||||
Options" in the manual for full details.
|
||||
|
||||
** Fix time-monotonic from SRFI-19; broken in 2.2.1.
|
||||
|
||||
|
||||
Changes in 2.2.2 (since 2.2.1):
|
||||
|
||||
* Bug fixes
|
||||
|
||||
** Syntax objects are once more comparable with 'equal?'
|
||||
|
||||
The syntax object change in 2.2.1 had the unintended effect of making
|
||||
syntax objects no longer comparable with equal?. This release restores
|
||||
the previous behavior.
|
||||
|
||||
** Restore libgc dependency
|
||||
|
||||
The change to throw exceptions when mutating literal constants partly
|
||||
relied on an interface that was added to our garbage collector (BDW-GC)
|
||||
after its 7.2 release. Guile 2.2.2 adds a workaround to allow Guile to
|
||||
continue be used with libgc as old as 7.2.
|
||||
|
||||
** SRFI-37 bug fix to not error on empty-string arguments.
|
||||
|
||||
Thanks to Thomas Danckaert for fixing this long-standing bug.
|
||||
|
||||
|
||||
|
||||
Changes in 2.2.1 (since 2.2.0):
|
||||
|
||||
* Notable changes
|
||||
|
||||
** New sandboxed evaluation facility
|
||||
|
||||
Guile now has a way to execute untrusted code in a safe way. See
|
||||
"Sandboxed Evaluation" in the manual for full details, including some
|
||||
important notes on limitations on the sandbox's ability to prevent
|
||||
resource exhaustion.
|
||||
|
||||
** All literal constants are read-only
|
||||
|
||||
According to the Scheme language definition, it is an error to attempt
|
||||
to mutate a "constant literal". A constant literal is data that is a
|
||||
literal quoted part of a program. For example, all of these are errors:
|
||||
|
||||
(set-car! '(1 . 2) 42)
|
||||
(append! '(1 2 3) '(4 5 6))
|
||||
(vector-set! '#(a b c) 1 'B)
|
||||
|
||||
Guile takes advantage of this provision of Scheme to deduplicate shared
|
||||
structure in constant literals within a compilation unit, and to
|
||||
allocate constant data directly in the compiled object file. If the
|
||||
data needs no relocation at run-time, as is the case for pairs or
|
||||
vectors that only contain immediate values, then the data can actually
|
||||
be shared between different Guile processes, using the operating
|
||||
system's virtual memory facilities.
|
||||
|
||||
However, in Guile 2.2.0, constants that needed relocation were actually
|
||||
mutable -- though (vector-set! '#(a b c) 1 'B) was an error, Guile
|
||||
wouldn't actually cause an exception to be raised, silently allowing the
|
||||
mutation. This could affect future users of this constant, or indeed of
|
||||
any constant in the compilation unit that shared structure with the
|
||||
original vector.
|
||||
|
||||
Additionally, attempting to mutate constant literals mapped in the
|
||||
read-only section of files would actually cause a segmentation fault, as
|
||||
the operating system prohibits writes to read-only memory. "Don't do
|
||||
that" isn't a very nice solution :)
|
||||
|
||||
Both of these problems have been fixed. Any attempt to mutate a
|
||||
constant literal will now raise an exception, whether the constant needs
|
||||
relocation or not.
|
||||
|
||||
** Syntax objects are now a distinct type
|
||||
|
||||
It used to be that syntax objects were represented as a tagged vector.
|
||||
These values could be forged by users to break scoping abstractions,
|
||||
preventing the implementation of sandboxing facilities in Guile. We are
|
||||
as embarrassed about the previous situation as we pleased are about the
|
||||
fact that we've fixed it.
|
||||
|
||||
Unfortunately, during the 2.2 stable series (or at least during part of
|
||||
it), we need to support files compiled with Guile 2.2.0. These files
|
||||
may contain macros that contain legacy syntax object constants. See the
|
||||
discussion of "allow-legacy-syntax-objects?" in "Syntax Transformer
|
||||
Helpers" in the manual for full details.
|
||||
|
||||
* Bug fixes
|
||||
|
||||
*** Fix snarfing with -ggdb3 (#25803)
|
||||
*** Fix spurious snarf warnings for net_db.c
|
||||
*** Output statprof flat display to correct port
|
||||
*** Document guile-2.2 cond-expand feature
|
||||
*** Add --with-bdw-gc for BSDs that use bdw-gc-threaded (see README)
|
||||
*** Documentation typo fixes (#26188)
|
||||
*** Fix SRFI-9 date->string bugs with ~N and ~F (#26261, #26260, #26259)
|
||||
*** SRFI-19 current-time-monotonic returns time of right type (#26329)
|
||||
*** Avoid causing GC when looking up exception handler
|
||||
*** Increment objcode version, in a compatible way
|
||||
*** Fix compile warning in (system base types)
|
||||
*** Only run tests that require fork if it is provided
|
||||
*** Speed up procedure-minimum-arity for fixed arity
|
||||
*** REPL server tests catch ECONNABORTED
|
||||
*** Avoid deprecated argument to setvbuf in (web client)
|
||||
*** Remove non-existent 'open-connection-for-uri' export from (web client)
|
||||
|
||||
|
||||
Changes in 2.2.0 (changes since the 2.0.x stable release series):
|
||||
|
||||
* Notable changes
|
||||
|
||||
|
@ -21,9 +158,9 @@ better memory usage, and faster execution of user code. See the
|
|||
|
||||
This new release series takes the ABI-break opportunity to fix some
|
||||
interfaces that were difficult to use correctly from multiple threads.
|
||||
Notably, weak hash tables are now transparently thread-safe. Ports are
|
||||
also thread-safe; see "New interfaces" below for details on the changes
|
||||
to the C interface.
|
||||
Notably, weak hash tables and ports are now transparently thread-safe.
|
||||
See "Scheduling" in the manual, for updated documentation on threads and
|
||||
communications primitives.
|
||||
|
||||
** Better space-safety
|
||||
|
||||
|
@ -55,14 +192,14 @@ hash-bang line (e.g. "#!/usr/bin/guile"), it now installs the current
|
|||
locale via a call to `(setlocale LC_ALL "")'. For users with a unicode
|
||||
locale, this makes all ports unicode-capable by default, without the
|
||||
need to call `setlocale' in your program. This behavior may be
|
||||
controlled via the GUILE_INSTALL_LOCALE environment variable; see the
|
||||
manual for more.
|
||||
controlled via the GUILE_INSTALL_LOCALE environment variable; see
|
||||
"Environment Variables" in the manual, for more.
|
||||
|
||||
** Complete Emacs-compatible Elisp implementation
|
||||
|
||||
Thanks to the work of BT Templeton, Guile's Elisp implementation is now
|
||||
fully Emacs-compatible, implementing all of Elisp's features and quirks
|
||||
in the same way as the editor we know and love.
|
||||
Thanks to the work of Robin Templeton, Guile's Elisp implementation is
|
||||
now fully Emacs-compatible, implementing all of Elisp's features and
|
||||
quirks in the same way as the editor we know and love.
|
||||
|
||||
** Dynamically expandable stacks
|
||||
|
||||
|
@ -101,6 +238,40 @@ in Scheme. This decreases its maintenance burden on the rest of Guile,
|
|||
while also makes it possible to implement new features in the future,
|
||||
such as method combinations or `eqv?' specializers.
|
||||
|
||||
** Better handling of GUILE_LOAD_COMPILED_PATH
|
||||
|
||||
It used to be that Guile would stop at the first .go file it found in
|
||||
the GUILE_LOAD_COMPILED_PATH. If that file turned out to be out of
|
||||
date, then no .go file would be loaded. Now Guile will continue to
|
||||
search the path for a file which is both present and up-to-date, with
|
||||
respect to the .scm file.
|
||||
|
||||
** C99 required
|
||||
|
||||
Following Emacs, you must use a C99-capable compiler when building
|
||||
Guile. In the future we also expect require C99 to use Guile's C
|
||||
interface, at least for `stdint' support.
|
||||
|
||||
** Lightweight pre-emptive threading primitives
|
||||
|
||||
The compiler now inserts special "handle-interrupts" opcodes before each
|
||||
call, return, and backwards jump target. This allows the user to
|
||||
interrupt any computation and to accurately profile code using
|
||||
interrupts. It used to be that interrupts were run by calling a C
|
||||
function from the VM; now interrupt thunks are run directly from the VM.
|
||||
This allows interrupts to save a delimited continuation and, if the
|
||||
continuation was established from the same VM invocation (the usual
|
||||
restriction), that continuation can then be resumed. In this way users
|
||||
can implement lightweight pre-emptive threading facilities.
|
||||
|
||||
** with-dynamic-state in VM
|
||||
|
||||
Similarly, `with-dynamic-state' no longer recurses out of the VM,
|
||||
allowing captured delimited continuations that include a
|
||||
`with-dynamic-state' invocation to be resumed. This is a precondition
|
||||
to allow lightweight threading libraries to establish a dynamic state
|
||||
per lightweight fiber.
|
||||
|
||||
* Performance improvements
|
||||
|
||||
** Faster programs via new virtual machine
|
||||
|
@ -132,10 +303,11 @@ Guile's compiler now uses a Continuation-Passing Style (CPS)
|
|||
intermediate language, allowing it to reason easily about temporary
|
||||
values and control flow. Examples of optimizations that this permits
|
||||
are optimal contification, optimal common subexpression elimination,
|
||||
dead code elimination, parallel moves with at most one temporary,
|
||||
allocation of stack slots using precise liveness information, and
|
||||
closure optimization. For more, see "Continuation-Passing Style" in the
|
||||
manual.
|
||||
dead code elimination, loop-invariant code motion, loop peeling, loop
|
||||
inversion, parallel moves with at most one temporary, allocation of
|
||||
stack slots using precise liveness information, unboxing of 64-bit
|
||||
integers and floating point values, and closure optimization. For more,
|
||||
see "Continuation-Passing Style" in the manual.
|
||||
|
||||
** Faster interpreter
|
||||
|
||||
|
@ -169,6 +341,20 @@ Thanks to work by Daniel Llorens, the generic array facility is much
|
|||
faster now, as it is internally better able to dispatch on the type of
|
||||
the underlying backing store.
|
||||
|
||||
** All ports are now buffered, can be targets of `setvbuf'
|
||||
|
||||
See "Buffering" in the manual, for more. A port with a buffer size of 1
|
||||
is equivalent to an unbuffered port. Ports may set their default buffer
|
||||
sizes, and some ports (for example soft ports) are unbuffered by default
|
||||
for historical reasons.
|
||||
|
||||
** Mutexes are now faster under contention
|
||||
|
||||
Guile implements its own mutexes, so that threads that are trying to
|
||||
acquire a mutex can be interrupted. These mutexes used to be quite
|
||||
inefficient when many threads were trying to acquire them, causing many
|
||||
spurious wakeups and contention. This has been fixed.
|
||||
|
||||
* New interfaces
|
||||
|
||||
** New `cond-expand' feature: `guile-2.2'
|
||||
|
@ -185,29 +371,55 @@ Since the compiler was rewritten, there are new modules for the back-end
|
|||
of the compiler and the low-level loader and introspection interfaces.
|
||||
See the "Guile Implementation" chapter in the manual for all details.
|
||||
|
||||
** New functions: `scm_to_intptr_t', `scm_from_intptr_t'
|
||||
** New functions: `scm_to_uintptr_t', `scm_from_uintptr_t'
|
||||
** Add "tree" display mode for statprof.
|
||||
|
||||
See "Integers" in the manual, for more.
|
||||
See the newly updated "Statprof" section of the manual, for more.
|
||||
|
||||
** New thread-safe port API
|
||||
** Support for non-blocking I/O
|
||||
|
||||
For details on `scm_c_make_port', `scm_c_make_port_with_encoding',
|
||||
`scm_c_lock_port', `scm_c_try_lock_port', `scm_c_unlock_port',
|
||||
`scm_c_port_type_ref', `scm_c_port_type_add_x', `SCM_PORT_DESCRIPTOR',
|
||||
and `scm_dynwind_lock_port', see XXX.
|
||||
See "Non-Blocking I/O" in the manual, for more.
|
||||
|
||||
There is now a routine to atomically adjust port "revealed counts". See
|
||||
XXX for more on `scm_adjust_port_revealed_x' and
|
||||
`adjust-port-revealed!',
|
||||
** Implement R6RS custom binary input/output ports
|
||||
|
||||
All other port API now takes the lock on the port if needed. There are
|
||||
some C interfaces if you know that you don't need to take a lock; see
|
||||
XXX for details on `scm_get_byte_or_eof_unlocked',
|
||||
`scm_peek_byte_or_eof_unlocked' `scm_c_read_unlocked',
|
||||
`scm_getc_unlocked' `scm_unget_byte_unlocked', `scm_ungetc_unlocked',
|
||||
`scm_ungets_unlocked', `scm_fill_input_unlocked' `scm_putc_unlocked',
|
||||
`scm_puts_unlocked', and `scm_lfwrite_unlocked'.
|
||||
See "Custom Ports" in the manual.
|
||||
|
||||
** Implement R6RS output-buffer-mode
|
||||
** Implement R6RS bytevector->string, string->bytevector
|
||||
|
||||
See "R6RS Transcoders" in the manual.
|
||||
|
||||
** `accept' now takes optional flags argument
|
||||
|
||||
These flags can include `SOCK_NONBLOCK' and `SOCK_CLOEXEC', indicating
|
||||
options to apply to the returned socket, potentially removing the need
|
||||
for additional system calls to set these options. See "Network Sockets
|
||||
and Communication" in the manual, for more.
|
||||
|
||||
** Thread-safe atomic boxes (references)
|
||||
|
||||
See "Atomics" in the manual.
|
||||
|
||||
** Thread-local fluids
|
||||
|
||||
Guile now has support for fluids whose values are not captured by
|
||||
`current-dynamic-state' and not inheritied by child threads, and thus
|
||||
are local to the kernel thread they run on. See "Thread-Local
|
||||
Variables" in the manual, for more.
|
||||
|
||||
** suspendable-continuation?
|
||||
|
||||
This predicate returns true if the delimited continuation captured by
|
||||
aborting to a prompt would be able to be resumed. See "Prompt
|
||||
Primitives" in the manual for more.
|
||||
|
||||
** scm_c_prepare_to_wait_on_fd, scm_c_prepare_to_wait_on_cond,
|
||||
** scm_c_wait_finished
|
||||
|
||||
See "Asyncs" in the manual for more.
|
||||
|
||||
** File descriptor finalizers
|
||||
|
||||
See "Ports and File Descriptors" in the manual.
|
||||
|
||||
** New inline functions: `scm_new_smob', `scm_new_double_smob'
|
||||
|
||||
|
@ -224,14 +436,22 @@ For more on `SCM_HAS_TYP7', `SCM_HAS_TYP7S', `SCM_HAS_TYP16', see XXX.
|
|||
the old `SCM2PTR' and `PTR2SCM'. Also, `SCM_UNPACK_POINTER' yields a
|
||||
void*.
|
||||
|
||||
** `TCP_NODELAY' and `TCP_CORK' socket options, if provided by the system
|
||||
|
||||
** `scm_c_put_latin1_chars', `scm_c_put_utf32_chars'
|
||||
|
||||
Use these instead of `scm_lfwrite'. See the new "Using Ports from C"
|
||||
section of the manual, for more.
|
||||
|
||||
** <standard-vtable>, standard-vtable-fields
|
||||
|
||||
See "Structures" in the manual for more on these
|
||||
See "Structures" in the manual for more on these.
|
||||
|
||||
** Convenience utilities for ports and strings.
|
||||
|
||||
See XXX for more on `scm_from_port_string', `scm_from_port_stringn',
|
||||
`scm_to_port_string', and `scm_to_port_stringn'.
|
||||
See "Conversion to/from C" for more on `scm_from_port_string',
|
||||
`scm_from_port_stringn', `scm_to_port_string', and
|
||||
`scm_to_port_stringn'.
|
||||
|
||||
** New expressive PEG parser
|
||||
|
||||
|
@ -264,6 +484,97 @@ ASCII as ISO-8859-1. This is likely to be a problem only if the user's
|
|||
locale is set to ASCII, and the user or a program writes non-ASCII
|
||||
codepoints to a port.
|
||||
|
||||
** Decoding errors do not advance the read pointer before erroring
|
||||
|
||||
When the user sets a port's conversion strategy to "error", indicating
|
||||
that Guile should throw an error if it tries to read from a port whose
|
||||
incoming bytes are not valid for the port's encoding, it used to be that
|
||||
Guile would advance the read pointer past the bad bytes, and then throw
|
||||
an error. This would allow the following `read-char' invocation to
|
||||
proceed after the bad bytes. This behavior is incompatible with the
|
||||
final R6RS standard, and besides contravenes the user's intention to
|
||||
raise an error on bad input. Guile now raises an error without
|
||||
advancing the read pointer. To skip over a bad encoding, set the port
|
||||
conversion strategy to "substitute" and read a substitute character.
|
||||
|
||||
** Decoding errors with `substitute' strategy return U+FFFD
|
||||
|
||||
It used to be that decoding errors with the `substitute' conversion
|
||||
strategy would replace the bad bytes with a `?' character. This has
|
||||
been changed to use the standard U+FFFD REPLACEMENT CHARACTER, in
|
||||
accordance with the Unicode recommendations.
|
||||
|
||||
** API to define new port types from C has changed
|
||||
|
||||
Guile's ports have been completely overhauled to allow Guile developers
|
||||
and eventually Guile users to write low-level input and output routines
|
||||
in Scheme. The new internals will eventually allow for user-space
|
||||
tasklets or green threads that suspend to a scheduler when they would
|
||||
cause blocking I/O, allowing users to write straightforward network
|
||||
services that parse their input and send their output as if it were
|
||||
blocking, while under the hood Guile can multiplex many active
|
||||
connections at once.
|
||||
|
||||
At the same time, this change makes Guile's ports implementation much
|
||||
more maintainable, rationalizing the many legacy port internals and
|
||||
making sure that the abstractions between the user, Guile's core ports
|
||||
facility, and the port implementations result in a system that is as
|
||||
performant and expressive as possible.
|
||||
|
||||
The interface to the user has no significant change, neither on the C
|
||||
side nor on the Scheme side. However this refactoring has changed the
|
||||
interface to the port implementor in an incompatible way. See the newly
|
||||
expanded "I/O Extensions" in the manual, for full details.
|
||||
|
||||
*** Remove `scm_set_port_mark'
|
||||
|
||||
Port mark functions have not been called since the switch to the BDW
|
||||
garbage collector.
|
||||
|
||||
*** Remove `scm_set_port_equalp'
|
||||
|
||||
Likewise port equal functions weren't being called. Given that ports
|
||||
have their own internal buffers, it doesn't make sense to hook them into
|
||||
equal? anyway.
|
||||
|
||||
*** Remove `scm_set_port_free'
|
||||
|
||||
It used to be that if an open port became unreachable, a special "free"
|
||||
function would be called instead of the "close" function. Now that the
|
||||
BDW-GC collector allows us to run arbitrary code in finalizers, we can
|
||||
simplify to just call "close" on the port and remove the separate free
|
||||
functions. Note that hooking into the garbage collector has some
|
||||
overhead. For that reason Guile exposes a new interface,
|
||||
`scm_set_port_needs_close_on_gc', allowing port implementations to
|
||||
indicate to Guile whether they need closing on GC or not.
|
||||
|
||||
*** Remove `scm_set_port_end_input', `scm_set_port_flush'
|
||||
|
||||
As buffering is handled by Guile itself, these functions which were to
|
||||
manage an implementation-side buffer are no longer needed.
|
||||
|
||||
*** Change prototype of `scm_make_port_type'
|
||||
|
||||
The `read' (renamed from `fill_input') and `write' functions now operate
|
||||
on bytevectors. Also the `mode_bits' argument now inplicitly includes
|
||||
SCM_OPN, so you don't need to include these.
|
||||
|
||||
*** Change prototype of port `close' function
|
||||
|
||||
The port close function now returns void.
|
||||
|
||||
*** Port and port type data structures are now opaque
|
||||
|
||||
Port type implementations should now use API to access port state.
|
||||
However, since the change to handle port buffering centrally, port type
|
||||
implementations rarely need to access unrelated port state.
|
||||
|
||||
*** Port types are now `scm_t_port_type*', not a tc16 value
|
||||
|
||||
`scm_make_port_type' now returns an opaque pointer, not a tc16.
|
||||
Relatedly, the limitation that there only be 256 port types has been
|
||||
lifted.
|
||||
|
||||
** String ports default to UTF-8
|
||||
|
||||
Guile 2.0 would use the `%default-port-encoding' when creating string
|
||||
|
@ -285,6 +596,122 @@ ports are both textual and binary, Guile's R6RS ports are also both
|
|||
textual and binary, and thus both kinds have port transcoders. This is
|
||||
an incompatibility with respect to R6RS.
|
||||
|
||||
** Threading facilities moved to (ice-9 threads)
|
||||
|
||||
It used to be that call-with-new-thread and other threading primitives
|
||||
were available in the default environment. This is no longer the case;
|
||||
they have been moved to (ice-9 threads) instead. Existing code will not
|
||||
break, however; we used the deprecation facility to signal a warning
|
||||
message while also providing these bindings in the root environment for
|
||||
the duration of the 2.2 series.
|
||||
|
||||
** cancel-thread uses asynchronous interrupts, not pthread_cancel
|
||||
|
||||
See "Asyncs" in the manual, for more on asynchronous interrupts.
|
||||
|
||||
** SRFI-18 threads, mutexes, cond vars disjoint from Guile
|
||||
|
||||
When we added support for the SRFI-18 threading library in Guile 2.0, we
|
||||
did so in a way that made SRFI-18 mutexes the same as Guile mutexes.
|
||||
This was a mistake. In Guile our goal is to provide basic,
|
||||
well-thought-out, well-implemented, minimal primitives, on top of which
|
||||
we can build a variety of opinionated frameworks. Incorporating SRFI-18
|
||||
functionality into core Guile caused us to bloat and slow down our core
|
||||
threading primitives. Worse, they became very hard to describe; they
|
||||
did many things, did them poorly, and all that they did was never
|
||||
adequately specified.
|
||||
|
||||
For all of these reasons we have returned to a situation where SRFI-18
|
||||
concepts are implemented only in the `(srfi srfi-18)' module. This
|
||||
means that SRFI-18 threads are built on Guile threads, but aren't the
|
||||
same as Guile threads; calling Guile `thread?' on a thread no longer
|
||||
returns true.
|
||||
|
||||
We realize this causes inconvenience to users who use both Guile
|
||||
threading interfaces and SRFI-18 interfaces, and we lament the change --
|
||||
but we are better off now. We hope the newly revised "Scheduling"
|
||||
section in the manual compensates for the headache.
|
||||
|
||||
** Remove `lock-mutex' "owner" argument
|
||||
|
||||
Mutex owners are a SRFI-18 concept; use SRFI-18 mutexes instead.
|
||||
Relatedly, `scm_lock_mutex_timed' taking the owner argument is now
|
||||
deprecated; use `scm_timed_lock_mutex' instead.
|
||||
|
||||
** Remove `unlock-mutex' cond var and timeout arguments
|
||||
|
||||
It used to be that `unlock-mutex' included `wait-condition-variable'
|
||||
functionality. This has been deprecated; use SRFI-18 if you want this
|
||||
behavior from `mutex-unlock!'. Relatedly, `scm_unlock_mutex_timed' is
|
||||
deprecated; use `scm_unlock_mutex' instead.
|
||||
|
||||
** Removed `unchecked-unlock' mutex flag
|
||||
|
||||
This flag was introduced for internal use by SRFI-18; use SRFI-18
|
||||
mutexes if you need this behaviour.
|
||||
|
||||
** SRFI-18 mutexes no longer recursive
|
||||
|
||||
Contrary to specification, SRFI-18 mutexes in Guile were recursive.
|
||||
This is no longer the case.
|
||||
|
||||
** Thread cleanup handlers removed
|
||||
|
||||
The `set-thread-cleanup!' and `thread-cleanup' functions that were added
|
||||
in Guile 2.0 to support cleanup after thread cancellation are no longer
|
||||
needed, since threads can declare cleanup handlers via `dynamic-wind'.
|
||||
|
||||
** Only threads created by Guile are joinable
|
||||
|
||||
`join-thread' used to work on "foreign" threads that were not created by
|
||||
Guile itself, though their join value was always `#f'. This is no
|
||||
longer the case; attempting to join a foreign thread will throw an
|
||||
error.
|
||||
|
||||
** Dynamic states capture values, not locations
|
||||
|
||||
Dynamic states used to capture the locations of fluid-value
|
||||
associations. Capturing the current dynamic state then setting a fluid
|
||||
would result in a mutation of that captured state. Now capturing a
|
||||
dynamic state simply captures the current values, and calling
|
||||
`with-dynamic-state' copies those values into the Guile virtual machine
|
||||
instead of aliasing them in a way that could allow them to be mutated in
|
||||
place. This change allows Guile's fluid variables to be thread-safe.
|
||||
To capture the locations of a dynamic state, capture a
|
||||
`with-dynamic-state' invocation using partial continuations instead.
|
||||
|
||||
** Remove `frame-procedure'
|
||||
|
||||
Several optimizations in Guile make `frame-procedure' an interface that
|
||||
we can no longer support. For background, `frame-procedure' used to
|
||||
return the value at slot 0 in a frame, which usually corresponds to the
|
||||
SCM value of the procedure being applied. However it could be that this
|
||||
slot is re-used for some other value, because the closure was not needed
|
||||
in the function. Such a re-use might even be for an untagged value, in
|
||||
which case treating slot 0 as a SCM value is quite dangerous. It's also
|
||||
possible that so-called "well-known" closures (closures whose callers
|
||||
are all known) are optimized in such a way that slot 0 is not a
|
||||
procedure but some optimized representation of the procedure's free
|
||||
variables. Instead, developers building debugging tools that would like
|
||||
access to `frame-procedure' are invited to look at the source for the
|
||||
`(system vm frame)' module for alternate interfaces, including the new
|
||||
`frame-procedure-name'.
|
||||
|
||||
** Remove `,procedure' REPL command
|
||||
|
||||
Not all procedures have values, so it doesn't make sense to expose this
|
||||
interface to the user. Instead, the `,locals' REPL command will include
|
||||
the callee, if it is live.
|
||||
|
||||
** Remove `frame-local-ref', `frame-local-set!', `frame-num-locals'
|
||||
|
||||
These procedures reference values in a frame on the stack. Since we now
|
||||
have unboxed values of different kinds, it is now necessary to specify
|
||||
the type when reference locals, and once this incompatible change needs
|
||||
to be made, we might as well make these interfaces private. See
|
||||
"Frames' in the manual, for more information on the replacements for
|
||||
these low-level interfaces.
|
||||
|
||||
** Vtable hierarchy changes
|
||||
|
||||
In an attempt to make Guile's structure and record types integrate
|
||||
|
@ -351,6 +778,37 @@ are matched by binding. This allows literals to be reliably bound to
|
|||
values, renamed by imports or exports, et cetera. See "Syntax-rules
|
||||
Macros" in the manual for more on literals.
|
||||
|
||||
** Fix bug importing specific bindings with #:select
|
||||
|
||||
It used to be that if #:select didn't find a binding in the public
|
||||
interface of a module, it would actually grovel in the module's
|
||||
unexported private bindings. This was not intended and is now fixed.
|
||||
|
||||
** Statically scoped module duplicate handlers
|
||||
|
||||
It used to be that if a module did not specify a #:duplicates handler,
|
||||
when a name was first referenced in that module and multiple imported
|
||||
modules provide that name, the value of the
|
||||
`default-duplicate-binding-handlers' parameter would be used to resolve
|
||||
the duplicate bindings. We have changed so that instead a module
|
||||
defaults to the set of handlers described in the manual. If the module
|
||||
specifies #:duplicates, of course we use that. The
|
||||
`default-duplicate-binding-handlers' parameter now simply accesses the
|
||||
handlers of the current module, instead of some global value.
|
||||
|
||||
** Fix too-broad capture of dynamic stack by delimited continuations
|
||||
|
||||
Guile was using explicit stacks to represent, for example, the chain of
|
||||
current exception handlers. This means that a delimited continuation
|
||||
that captured a "catch" expression would capture the whole stack of
|
||||
exception handlers, not just the exception handler added by the "catch".
|
||||
This led to strangeness when resuming the continuation in some other
|
||||
context like other threads; "throw" could see an invalid stack of
|
||||
exception handlers. This has been fixed by the addition of the new
|
||||
"fluid-ref*" procedure that can access older values of fluids; in this
|
||||
way the exception handler stack is now implicit. See "Fluids and
|
||||
Dynamic States" in the manual, for more on fluid-ref*.
|
||||
|
||||
** `dynamic-wind' doesn't check that guards are thunks
|
||||
|
||||
Checking that the dynamic-wind out-guard procedure was actually a thunk
|
||||
|
@ -472,6 +930,62 @@ scm_t_debug_info', `scm_pure_generic_p', `SCM_PUREGENERICP',
|
|||
|
||||
* New deprecations
|
||||
|
||||
** `SCM_FDES_RANDOM_P'
|
||||
|
||||
Instead, use `lseek (fd, 0, SEEK_CUR)' directly.
|
||||
|
||||
** `_IONBF', `_IOLBF', and `_IOFBF'
|
||||
|
||||
Instead, use the symbol values `none', `line', or `block', respectively,
|
||||
as arguments to the `setvbuf' function.
|
||||
|
||||
** `SCM_FDES_RANDOM_P'
|
||||
|
||||
Instead, use `lseek (fd, 0, SEEK_CUR)' directly.
|
||||
|
||||
** Arbiters
|
||||
|
||||
Arbiters were an experimental mutual exclusion facility from 20 years
|
||||
ago that didn't survive the test of time. Use mutexes or atomic boxes
|
||||
instead.
|
||||
|
||||
** User asyncs
|
||||
|
||||
Guile had (and still has) "system asyncs", which are asynchronous
|
||||
interrupts, and also had this thing called "user asyncs", which was a
|
||||
trivial unused data structure. Now that we have deprecated the old
|
||||
`async', `async-mark', and `run-asyncs' procedures that comprised the
|
||||
"user async" facility, we have been able to clarify our documentation to
|
||||
only refer to "asyncs".
|
||||
|
||||
** Critical sections
|
||||
|
||||
Critical sections have long been just a fancy way to lock a mutex and
|
||||
defer asynchronous interrupts. Instead of SCM_CRITICAL_SECTION_START,
|
||||
make sure you're in a "scm_dynwind_begin (0)" and use
|
||||
scm_dynwind_pthread_mutex_lock instead, possibly also with
|
||||
scm_dynwind_block_asyncs.
|
||||
|
||||
** `scm_make_mutex_with_flags'
|
||||
|
||||
Use `scm_make_mutex_with_kind' instead. See "Mutexes and Condition
|
||||
Variables" in the manual, for more.
|
||||
|
||||
** Dynamic roots
|
||||
|
||||
This was a facility that predated threads, was unused as far as we can
|
||||
tell, and was never documented. Still, a grep of your code for
|
||||
dynamic-root or dynamic_root would not be amiss.
|
||||
|
||||
** `make-dynamic-state'
|
||||
|
||||
Use `current-dynamic-state' to get an immutable copy of the current
|
||||
fluid-value associations.
|
||||
|
||||
** `with-statprof' macro
|
||||
|
||||
Use the `statprof' procedure instead.
|
||||
|
||||
** SCM_WTA_DISPATCH_0, SCM_WTA_DISPATCH_1, SCM_WTA_DISPATCH_2, SCM_WTA_DISPATCH_N
|
||||
** SCM_GASSERT0, SCM_GASSERT1, SCM_GASSERT2, SCM_GASSERTn
|
||||
** SCM_WTA_DISPATCH_1_SUBR
|
||||
|
@ -524,6 +1038,19 @@ Instead use the normal `scm_slot_ref' and similar procedures.
|
|||
|
||||
* Changes to the distribution
|
||||
|
||||
** Pre-built binary files in the tarball
|
||||
|
||||
Building Guile from a tarball can now take advantage of a "prebuilt/"
|
||||
tree of prebuilt .go files. These compiled files are created when a
|
||||
tarball is made, and are used to speed up the build for users of
|
||||
official releases.
|
||||
|
||||
These pre-built binaries are not necessary, however: they are not stored
|
||||
in revision control and can always be re-created from the source, given
|
||||
that Guile can bootstrap itself from its minimal bootstrap C
|
||||
interpreter. If you do not want to depend on these pre-built binaries,
|
||||
you can "make -C prebuilt clean" before building.
|
||||
|
||||
** New minor version
|
||||
|
||||
The "effective version" of Guile is now 2.2, which allows parallel
|
||||
|
@ -533,6 +1060,15 @@ Notably, the `pkg-config' file is now `guile-2.2'.
|
|||
|
||||
** Bump required libgc version to 7.2, released March 2012.
|
||||
|
||||
** GUILE_PROGS searches for versioned Guile
|
||||
|
||||
The GUILE_PROGS autoconf macro can take a required version argument. As
|
||||
a new change, that version argument is additionally searched for as a
|
||||
suffix. For example, GUILE_PROGS(2.2) would look for guile-2.2,
|
||||
guile2.2, guile-2, guile2, and then guile. The found prefix is also
|
||||
applied to guild, guile-config, and the like. Thanks to Freja Nordsiek
|
||||
for this work.
|
||||
|
||||
** The readline extension is now installed in the extensionsdir
|
||||
|
||||
The shared library that implements Guile's readline extension is no
|
||||
|
@ -540,6 +1076,277 @@ longer installed to the libdir. This change should be transparent to
|
|||
users, but packagers may be interested.
|
||||
|
||||
|
||||
|
||||
Changes in 2.0.14 (since 2.0.13):
|
||||
|
||||
* Bug fixes
|
||||
|
||||
** Builds of .go files and of Guile itself are now bit-reproducible
|
||||
(<http://bugs.gnu.org/20272>)
|
||||
|
||||
** 'number->locale-string' and 'monetary-amount->locale-string' fixes
|
||||
(<http://bugs.gnu.org/24990>)
|
||||
|
||||
** (system base target) now recognizes "sh3" as a cross-compilation target
|
||||
|
||||
** Fix race condition in '00-repl-server.test'
|
||||
(<http://bugs.gnu.org/24769>)
|
||||
|
||||
** 'scandir' from (ice-9 ftw) no longer calls 'stat' for each entry
|
||||
|
||||
** Several documentation improvements
|
||||
|
||||
|
||||
Changes in 2.0.13 (since 2.0.12):
|
||||
|
||||
* Security fixes
|
||||
|
||||
** CVE-2016-8606: REPL server now protects against HTTP inter-protocol
|
||||
attacks
|
||||
|
||||
Guile 2.x provides a "REPL server" started by the '--listen'
|
||||
command-line option or equivalent API (see "REPL Servers" in the
|
||||
manual).
|
||||
|
||||
The REPL server is vulnerable to the HTTP inter-protocol attack as
|
||||
described at
|
||||
<https://en.wikipedia.org/wiki/Inter-protocol_exploitation>, notably the
|
||||
HTML form protocol attack described at
|
||||
<https://www.jochentopf.com/hfpa/hfpa.pdf>. A "DNS rebinding attack"
|
||||
can be combined with this attack and allow an attacker to send arbitrary
|
||||
Guile code to the REPL server through web pages accessed by the
|
||||
developer, even though the REPL server is listening to a loopback device
|
||||
("localhost"). This was demonstrated in an article entitled "How to
|
||||
steal any developer's local database" available at
|
||||
<http://bouk.co/blog/hacking-developers/>.
|
||||
|
||||
The REPL server in Guile 2.0.13 now detects attempts to exploit this
|
||||
vulnerability. It immediately closes the connection when it receives a
|
||||
line that looks like an HTTP request.
|
||||
|
||||
Nevertheless, we recommend binding the REPL server to a Unix-domain
|
||||
socket, for instance by running:
|
||||
|
||||
guile --listen=/tmp/guile-socket
|
||||
|
||||
** CVE-2016-8605: 'mkdir' procedure no longer calls umask(2)
|
||||
(<http://bugs.gnu.org/24659>)
|
||||
|
||||
When the second argument to the 'mkdir' procedure was omitted, it would
|
||||
call umask(0) followed by umask(previous_umask) and apply the umask to
|
||||
mode #o777.
|
||||
|
||||
This was unnecessary and a security issue for multi-threaded
|
||||
applications: during a small window the process' umask was set to zero,
|
||||
so other threads calling mkdir(2) or open(2) could end up creating
|
||||
world-readable/writable/executable directories or files.
|
||||
|
||||
* New interfaces
|
||||
|
||||
** mkstemp! takes optional "mode" argument
|
||||
|
||||
See "File System" in the manual, for more.
|
||||
|
||||
** New 'scm_to_uintptr_t' and 'scm_from_uintptr_t' C functions
|
||||
|
||||
* Bug fixes
|
||||
|
||||
** Fix optimizer bug when compiling fixpoint operator
|
||||
** Fix build error on MinGW
|
||||
** Update 'uname' implementation on MinGW
|
||||
** 'port-encoding' and 'set-port-encoding!' ensure they are passed an
|
||||
open port
|
||||
** (system base target) now recognizes Alpha as a cross-compilation target
|
||||
|
||||
|
||||
Changes in 2.0.12 (since 2.0.11):
|
||||
|
||||
* Notable changes
|
||||
|
||||
** FFI: Add support for functions that set 'errno'
|
||||
|
||||
When accessing POSIX functions from a system's libc via Guile's dynamic
|
||||
FFI, you commonly want to access the 'errno' variable to be able to
|
||||
produce useful diagnostic messages.
|
||||
|
||||
This is now possible using 'pointer->procedure' or
|
||||
'scm_pointer_to_procedure_with_errno'. See "Dynamic FFI" in the manual.
|
||||
|
||||
** The #!r6rs directive now influences read syntax
|
||||
|
||||
The #!r6rs directive now changes the per-port reader options to make
|
||||
Guile's reader conform more closely to the R6RS syntax. In particular:
|
||||
|
||||
- It makes the reader case sensitive.
|
||||
- It disables the recognition of keyword syntax in conflict with the
|
||||
R6RS (and R5RS).
|
||||
- It enables the `square-brackets', `hungry-eol-escapes' and
|
||||
`r6rs-hex-escapes' reader options.
|
||||
|
||||
** 'read' now accepts "\(" as equivalent to "("
|
||||
|
||||
This is indented for use at the beginning of lines in multi-line strings
|
||||
to avoid confusing Emacs' lisp modes. Previously "\(" was an error.
|
||||
|
||||
** SRFI-14 character data set upgraded to Unicode 8.0.0
|
||||
|
||||
** SRFI-19 table of leap seconds updated
|
||||
|
||||
** 'string-hash', 'read-string', and 'write' have been optimized
|
||||
|
||||
** GOOPS bug fix for inherited accessor methods
|
||||
|
||||
In the port of GOOPS to Guile 2.0, we introduced a bug related to
|
||||
accessor methods. The bug resulted in GOOPS assuming that a slot S in
|
||||
an object whose class is C would always be present in instances of all
|
||||
subclasses C, and allocated to the same struct index. This is not the
|
||||
case for multiple inheritance. This behavior has been fixed to be as it
|
||||
was in 1.8.
|
||||
|
||||
One aspect of this change may cause confusion among users. Previously
|
||||
if you defined a class C:
|
||||
|
||||
(use-modules (oop goops))
|
||||
(define-class C ()
|
||||
(a #:getter get-a))
|
||||
|
||||
And now you define a subclass, intending to provide an #:init-value for
|
||||
the slot A:
|
||||
|
||||
(define-class D (A)
|
||||
(a #:init-value 42))
|
||||
|
||||
Really what you have done is define in D a new slot with the same name,
|
||||
overriding the existing slot. The problem comes in that before fixing
|
||||
this bug (but not in 1.8), the getter 'get-a' would succeed for
|
||||
instances of D, even though 'get-a' should only work for the slot 'a'
|
||||
that is defined on class C, not any other slot that happens to have the
|
||||
same name and be in a class with C as a superclass.
|
||||
|
||||
It would be possible to "merge" the slot definitions on C and D, but
|
||||
that part of the meta-object protocol (`compute-slots' et al) is not
|
||||
fully implemented.
|
||||
|
||||
Somewhat relatedly, GOOPS also had a fix around #:init-value on
|
||||
class-allocated slots. GOOPS was re-initializing the value of slots
|
||||
with #:class or #:each-subclass allocation every time instances of that
|
||||
class was allocated. This has been fixed.
|
||||
|
||||
* New interfaces
|
||||
|
||||
** New SRFI-28 string formatting implementation
|
||||
|
||||
See "SRFI-28" in the manual.
|
||||
|
||||
** New (ice-9 unicode) module
|
||||
|
||||
See "Characters" in the manual.
|
||||
|
||||
** Web server
|
||||
|
||||
The (web server) module now exports 'make-server-impl', 'server-impl?',
|
||||
and related procedures. Likewise, (web server http) exports 'http'.
|
||||
|
||||
** New procedures: 'string-utf8-length' and 'scm_c_string_utf8_length'
|
||||
|
||||
See "Bytevectors as Strings" in the manual, for more.
|
||||
|
||||
** New 'EXIT_SUCCESS' and 'EXIT_FAILURE' Scheme variables
|
||||
|
||||
See "Processes" in the manual.
|
||||
|
||||
** New C functions to disable automatic SMOB finalization
|
||||
|
||||
The new 'scm_set_automatic_finalization_enabled' C function allows you
|
||||
to choose whether automatic object finalization should be enabled (as
|
||||
was the case until now, and still is by default.) This is meant for
|
||||
applications that are not thread-safe nor async-safe; such applications
|
||||
can disable automatic finalization and call the new 'scm_run_finalizers'
|
||||
function when appropriate.
|
||||
|
||||
See the "Garbage Collecting Smobs" and "Smobs" sections in the manual.
|
||||
|
||||
** Cross-compilation to ARM
|
||||
|
||||
More ARM cross-compilation targets are supported: "arm.*eb",
|
||||
"^aarch64.*be", and "aarch64".
|
||||
|
||||
* New deprecation
|
||||
|
||||
** The undocumented and unused C function 'scm_string_hash' is now deprecated
|
||||
|
||||
* Bugs fixed
|
||||
|
||||
** Compiler
|
||||
*** 'call-with-prompt' does not truncate multiple-value returns
|
||||
(<http://bugs.gnu.org/14347>)
|
||||
*** Use permissions of source file for compiled file
|
||||
(<http://bugs.gnu.org/18477>)
|
||||
*** Fix bug when inlining some functions with optional arguments
|
||||
(<http://bugs.gnu.org/17634>)
|
||||
*** Avoid quadratic expansion time in 'and' and 'or' macros
|
||||
(<http://bugs.gnu.org/17147>)
|
||||
*** Fix expander bug introduced when adding support for tail patterns
|
||||
(<http://lists.gnu.org/archive/html/guile-user/2015-09/msg00017.html>)
|
||||
*** Handle ~p in 'format' warnings (<http://bugs.gnu.org/18299>)
|
||||
*** Fix bug that exposed `list' invocations to CSE
|
||||
(<http://bugs.gnu.org/21899>)
|
||||
*** Reduce eq? and eqv? over constants using equal?
|
||||
(<http://bugs.gnu.org/21855>)
|
||||
*** Skip invalid .go files found in GUILE_LOAD_COMPILED_PATH
|
||||
|
||||
** Threads
|
||||
*** Fix data races leading to corruption (<http://bugs.gnu.org/22152>)
|
||||
|
||||
** Memory management
|
||||
*** Fix race between SMOB marking and finalization
|
||||
(<http://bugs.gnu.org/19883>)
|
||||
|
||||
** Ports
|
||||
*** Fix port position handling on binary input ports
|
||||
(<http://bugs.gnu.org/20302>)
|
||||
*** Bytevector and custom binary ports to use ISO-8859-1
|
||||
(<http://bugs.gnu.org/20200>)
|
||||
*** Fix buffer overrun with unbuffered custom binary input ports
|
||||
(<http://bugs.gnu.org/19621>)
|
||||
*** Fix memory corruption that arose when using 'get-bytevector-n'
|
||||
(<http://bugs.gnu.org/17466>)
|
||||
|
||||
** System
|
||||
*** {get,set}sockopt now expect type 'int' for SO_SNDBUF/SO_RCVBUF
|
||||
*** 'system*' now available on MS-Windows
|
||||
*** 'open-pipe' now available on MS-Windows
|
||||
*** Better support for file names containing backslashes on Windows
|
||||
|
||||
** Web
|
||||
*** 'split-and-decode-uri-path' no longer decodes "+" to space
|
||||
*** HTTP: Support date strings with a leading space for hours
|
||||
(<http://bugs.gnu.org/23421>)
|
||||
*** HTTP: Accept empty reason phrases (<http://bugs.gnu.org/22273>)
|
||||
*** HTTP: 'Location' header can now contain URI references, not just
|
||||
absolute URIs
|
||||
*** HTTP: Improve chunked-mode support (<http://bugs.gnu.org/19939>)
|
||||
*** HTTP: 'open-socket-for-uri' now sets better OS buffering parameters
|
||||
(<http://bugs.gnu.org/15368>)
|
||||
|
||||
** Miscellaneous
|
||||
*** Fix 'atan' procedure when applied to complex numbers
|
||||
*** Fix Texinfo to HTML conversion for @itemize and @acronym
|
||||
(<http://bugs.gnu.org/21772>)
|
||||
*** 'bytevector-fill!' accepts fill arguments greater than 127
|
||||
(<http://bugs.gnu.org/19027>)
|
||||
*** 'bytevector-copy' correctly copies SRFI-4 homogeneous vectors
|
||||
(<http://bugs.gnu.org/18866>)
|
||||
*** 'strerror' no longer hangs when passed a non-integer argument
|
||||
(<http://bugs.gnu.org/18065>)
|
||||
*** 'scm_boot_guile' now gracefully handles argc == 0
|
||||
(<http://bugs.gnu.org/18680>)
|
||||
*** Fix 'SCM_SMOB_OBJECT_LOC' definition (<http://bugs.gnu.org/18495>)
|
||||
*** Fix bug where 'bit-count*' was not using its second argument
|
||||
*** SRFI-1 'length+' raises an error for non-lists and dotted lists
|
||||
(<http://bugs.gnu.org/17296>)
|
||||
*** Add documentation for SXPath (<http://bugs.gnu.org/19478>)
|
||||
|
||||
|
||||
Changes in 2.0.11 (since 2.0.10):
|
||||
|
||||
|
|
|
@ -1,57 +0,0 @@
|
|||
Guile-VM NEWS
|
||||
|
||||
|
||||
Guile-VM is a bytecode compiler and virtual machine for Guile.
|
||||
|
||||
|
||||
guile-vm 0.7 -- 2008-05-20
|
||||
==========================
|
||||
|
||||
* Initial release with NEWS.
|
||||
|
||||
* Revived from Keisuke Nishida's Guile-VM project from 2000-2001, with
|
||||
the help of Ludovic Courtès.
|
||||
|
||||
* Meta-level changes
|
||||
** Updated to compile with Guile 1.8.
|
||||
** Documentation updated, including documentation on the instructions.
|
||||
** Added benchmarking and a test harness.
|
||||
|
||||
* Changes to the inventory
|
||||
** Renamed the library from libguilevm to libguile-vm.
|
||||
** Added new executable script, guile-disasm.
|
||||
|
||||
* New features
|
||||
** Add support for compiling macros, both defmacros and syncase macros.
|
||||
Primitive macros produced with the procedure->macro family of procedures
|
||||
are not supported, however.
|
||||
** Improvements to the REPL
|
||||
Multiple values support, readline integration, ice-9 history integration
|
||||
** Add support for eval-case
|
||||
The compiler recognizes compile-toplevel in addition to load-toplevel
|
||||
** Completely self-compiling
|
||||
Almost, anyway: not (system repl describe), because it uses GOOPS
|
||||
|
||||
* Internal cleanups
|
||||
** Internal objects are now based on Guile records.
|
||||
** Guile-VM's code doesn't use the dot-syntax any more.
|
||||
** Changed (ice-9 match) for Kiselyov's pmatch.scm
|
||||
** New instructions: define, link-later, link-now, late-variable-{ref,set}
|
||||
** Object code now represented as u8vectors instead of strings.
|
||||
** Remove local import of an old version of slib
|
||||
|
||||
* Bugfixes
|
||||
** The `optimize' procedure is coming out of bitrot
|
||||
** The Scheme compiler is now more strict about placement of internal
|
||||
defines
|
||||
** set! is now compiled differently from define
|
||||
** Module-level variables are now bound at first use instead of in the
|
||||
program prolog
|
||||
** Bugfix to load-program (stack misinterpretation)
|
||||
|
||||
|
||||
Copyright (C) 2008 Free Software Foundation, Inc.
|
||||
|
||||
Copying and distribution of this file, with or without modification, are
|
||||
permitted in any medium without royalty provided the copyright notice
|
||||
and this notice are preserved.
|
27
README
27
README
|
@ -1,4 +1,4 @@
|
|||
This is version 2.0 of Guile, Project GNU's extension language library.
|
||||
This is version 2.2 of Guile, Project GNU's extension language library.
|
||||
Guile is an implementation of the Scheme programming language, packaged
|
||||
as a library that can be linked into applications to give them their own
|
||||
extension language. Guile supports other languages as well, giving
|
||||
|
@ -78,7 +78,7 @@ 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, at least version 7.2
|
||||
|
||||
libgc (aka. the Boehm-Demers-Weiser garbage collector) is the
|
||||
conservative garbage collector used by Guile. It is available
|
||||
|
@ -124,7 +124,20 @@ instructions above, but it seems that a few systems still need special
|
|||
treatment. If you can send us fixes for these problems, we'd be
|
||||
grateful.
|
||||
|
||||
<none yet listed>
|
||||
FreeBSD 11.0:
|
||||
For a build supporting threads, please `pkg install' the following
|
||||
- pkgconf : provides pkg-config
|
||||
- gmake : /usr/bin/make does not work
|
||||
- boehm-gc-threaded : needed for threaded support
|
||||
|
||||
Configure as:
|
||||
|
||||
./configure --with-bdw-gc=bdw-gc-threaded
|
||||
|
||||
Alternately if you want a Guile without threads, then install boehm-gc
|
||||
and configure as:
|
||||
|
||||
./configure --without-threads
|
||||
|
||||
Guile specific flags Accepted by Configure =================================
|
||||
|
||||
|
@ -244,7 +257,7 @@ switches specific to Guile you may find useful in some circumstances.
|
|||
|
||||
Cross building Guile =====================================================
|
||||
|
||||
As of Guile 2.0.x, the build process produces a library, libguile-2.0,
|
||||
As of Guile 2.2.x, the build process produces a library, libguile-2.2,
|
||||
along with Guile "object files" containing bytecode to be interpreted by
|
||||
Guile's virtual machine. The bytecode format depends on the endianness
|
||||
and word size of the host CPU.
|
||||
|
@ -401,8 +414,6 @@ Documentation in Info format, in ${prefix}/info:
|
|||
|
||||
guile --- Guile reference manual.
|
||||
|
||||
guile-tut --- Guile tutorial.
|
||||
|
||||
GOOPS --- GOOPS reference manual.
|
||||
|
||||
r5rs --- Revised(5) Report on the Algorithmic Language Scheme.
|
||||
|
@ -413,9 +424,7 @@ The Guile source tree is laid out as follows:
|
|||
libguile:
|
||||
The Guile Scheme interpreter --- both the object library
|
||||
for you to link with your programs, and the executable you can run.
|
||||
ice-9: Guile's module system, initialization code, and other infrastructure.
|
||||
guile-config:
|
||||
Source for the guile-config script.
|
||||
module: Scheme libraries included with Guile.
|
||||
guile-readline:
|
||||
The glue code for using GNU readline with Guile. This
|
||||
will be build when configure can find a recent enough readline
|
||||
|
|
117
README.guile-vm
117
README.guile-vm
|
@ -1,117 +0,0 @@
|
|||
This is an attempt to revive the Guile-VM project by Keisuke Nishida
|
||||
written back in the years 2000 and 2001. Below are a few pointers to
|
||||
relevant threads on Guile's development mailing list.
|
||||
|
||||
Enjoy!
|
||||
|
||||
Ludovic Courtès <ludovic.courtes@laas.fr>, Apr. 2005.
|
||||
|
||||
|
||||
Pointers
|
||||
--------
|
||||
|
||||
Status of the last release, 0.5
|
||||
http://lists.gnu.org/archive/html/guile-devel/2001-04/msg00266.html
|
||||
|
||||
The very first release, 0.0
|
||||
http://sources.redhat.com/ml/guile/2000-07/msg00418.html
|
||||
|
||||
Simple benchmark
|
||||
http://sources.redhat.com/ml/guile/2000-07/msg00425.html
|
||||
|
||||
Performance, portability, GNU Lightning
|
||||
http://lists.gnu.org/archive/html/guile-devel/2001-03/msg00132.html
|
||||
|
||||
Playing with GNU Lightning
|
||||
http://lists.gnu.org/archive/html/guile-devel/2001-03/msg00185.html
|
||||
|
||||
On things left to be done
|
||||
http://lists.gnu.org/archive/html/guile-devel/2001-03/msg00146.html
|
||||
|
||||
|
||||
---8<--- Original README below. -----------------------------------------
|
||||
|
||||
Installation
|
||||
------------
|
||||
|
||||
1. Install the latest Guile from CVS.
|
||||
|
||||
2. Install Guile VM:
|
||||
|
||||
% configure
|
||||
% make install
|
||||
% ln -s module/{guile,system,language} /usr/local/share/guile/
|
||||
|
||||
3. Add the following lines to your ~/.guile:
|
||||
|
||||
(use-modules (system vm core)
|
||||
|
||||
(cond ((string=? (car (command-line)) "guile-vm")
|
||||
(use-modules (system repl repl))
|
||||
(start-repl 'scheme)
|
||||
(quit)))
|
||||
|
||||
Example Session
|
||||
---------------
|
||||
|
||||
% guile-vm
|
||||
Guile Scheme interpreter 0.5 on Guile 1.4.1
|
||||
Copyright (C) 2001 Free Software Foundation, Inc.
|
||||
|
||||
Enter `,help' for help.
|
||||
scheme@guile-user> (+ 1 2)
|
||||
3
|
||||
scheme@guile-user> ,c -c (+ 1 2) ;; Compile into GLIL
|
||||
(@asm (0 1 0 0)
|
||||
(module-ref #f +)
|
||||
(const 1)
|
||||
(const 2)
|
||||
(tail-call 2))
|
||||
scheme@guile-user> ,c (+ 1 2) ;; Compile into object code
|
||||
Disassembly of #<objcode 403c5fb0>:
|
||||
|
||||
nlocs = 0 nexts = 0
|
||||
|
||||
0 link "+" ;; (+ . ???)
|
||||
3 variable-ref
|
||||
4 make-int8:1 ;; 1
|
||||
5 make-int8 2 ;; 2
|
||||
7 tail-call 2
|
||||
|
||||
scheme@guile-user> (define (add x y) (+ x y))
|
||||
scheme@guile-user> (add 1 2)
|
||||
3
|
||||
scheme@guile-user> ,x add ;; Disassemble
|
||||
Disassembly of #<program add>:
|
||||
|
||||
nargs = 2 nrest = 0 nlocs = 0 nexts = 0
|
||||
|
||||
Bytecode:
|
||||
|
||||
0 object-ref 0 ;; (+ . #<primitive-procedure +>)
|
||||
2 variable-ref
|
||||
3 local-ref 0
|
||||
5 local-ref 1
|
||||
7 tail-call 2
|
||||
|
||||
Objects:
|
||||
|
||||
0 (+ . #<primitive-procedure +>)
|
||||
|
||||
scheme@guile-user>
|
||||
|
||||
Compile Modules
|
||||
---------------
|
||||
|
||||
Use `guilec' to compile your modules:
|
||||
|
||||
% cat fib.scm
|
||||
(define-module (fib) :export (fib))
|
||||
(define (fib n) (if (< n 2) 1 (+ (fib (- n 1)) (fib (- n 2)))))
|
||||
|
||||
% guilec fib.scm
|
||||
Wrote fib.go
|
||||
% guile
|
||||
guile> (use-modules (fib))
|
||||
guile> (fib 8)
|
||||
34
|
3
THANKS
3
THANKS
|
@ -134,6 +134,7 @@ For fixes or providing information which led to a fix:
|
|||
Dan McMahill
|
||||
Roger Mc Murtrie
|
||||
Scott McPeak
|
||||
David Michael
|
||||
Glenn Michaels
|
||||
Andrew Milkowski
|
||||
Tim Mooney
|
||||
|
@ -170,6 +171,7 @@ For fixes or providing information which led to a fix:
|
|||
Dale Smith
|
||||
Cesar Strauss
|
||||
Klaus Stehle
|
||||
Kouhei Sutou
|
||||
Rainer Tammer
|
||||
Frank Terbeck
|
||||
Samuel Thibault
|
||||
|
@ -199,6 +201,7 @@ For fixes or providing information which led to a fix:
|
|||
Jon Wilson
|
||||
Andy Wingo
|
||||
Keith Wright
|
||||
Ricardo Wurmus
|
||||
William Xu
|
||||
Atom X Zane
|
||||
|
||||
|
|
|
@ -557,6 +557,8 @@ AC_DEFUN([GUILE_CHECK_GUILE_FOR_BUILD], [
|
|||
if test "$GUILE_FOR_BUILD" = "not-found"; then
|
||||
AC_MSG_ERROR([a native Guile $PACKAGE_VERSION is required to cross-build Guile])
|
||||
fi
|
||||
else
|
||||
GUILE_FOR_BUILD=$(which "$GUILE_FOR_BUILD" || echo "$GUILE_FOR_BUILD")
|
||||
fi
|
||||
AC_MSG_CHECKING([guile for build])
|
||||
AC_MSG_RESULT([$GUILE_FOR_BUILD])
|
||||
|
|
155
am/bootstrap.am
Normal file
155
am/bootstrap.am
Normal file
|
@ -0,0 +1,155 @@
|
|||
## Copyright (C) 2009, 2010, 2011, 2012, 2013,
|
||||
## 2014, 2015 Free Software Foundation, Inc.
|
||||
##
|
||||
## This file is part of GNU Guile.
|
||||
##
|
||||
## GNU 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.
|
||||
##
|
||||
## GNU 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 GNU 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
|
||||
|
||||
# These variables can be set before you include bootstrap.am.
|
||||
GUILE_WARNINGS ?= -Wunbound-variable -Warity-mismatch -Wformat
|
||||
GUILE_OPTIMIZATIONS ?= -O2
|
||||
GUILE_TARGET ?= $(host)
|
||||
GUILE_BUILD_TAG ?= BOOTSTRAP
|
||||
|
||||
GOBJECTS = $(SOURCES:%.scm=%.go)
|
||||
nobase_noinst_DATA = $(GOBJECTS)
|
||||
CLEANFILES = $(GOBJECTS)
|
||||
|
||||
VM_TARGETS = system/vm/assembler.go system/vm/disassembler.go
|
||||
$(VM_TARGETS): $(top_builddir)/libguile/vm-operations.h
|
||||
|
||||
AM_V_GUILEC = $(AM_V_GUILEC_$(V))
|
||||
AM_V_GUILEC_ = $(AM_V_GUILEC_$(AM_DEFAULT_VERBOSITY))
|
||||
AM_V_GUILEC_0 = @echo " $(GUILE_BUILD_TAG) GUILEC" $@;
|
||||
|
||||
vpath %.scm @top_srcdir@/module
|
||||
|
||||
SUFFIXES = .scm .go
|
||||
|
||||
.scm.go:
|
||||
$(AM_V_GUILEC)GUILE_AUTO_COMPILE=0 \
|
||||
$(top_builddir)/meta/build-env \
|
||||
guild compile --target="$(GUILE_TARGET)" \
|
||||
$(GUILE_WARNINGS) $(GUILE_OPTIMIZATIONS) \
|
||||
-L "$(abs_top_srcdir)/module" \
|
||||
-L "$(abs_top_srcdir)/guile-readline" \
|
||||
-o "$@" "$<"
|
||||
|
||||
# A subset of sources that are used by the compiler. We can compile
|
||||
# these in any order; the order below is designed to hopefully result in
|
||||
# the lowest total compile time.
|
||||
SOURCES = \
|
||||
ice-9/eval.scm \
|
||||
ice-9/psyntax-pp.scm \
|
||||
language/cps/intmap.scm \
|
||||
language/cps/intset.scm \
|
||||
language/cps/utils.scm \
|
||||
ice-9/vlist.scm \
|
||||
srfi/srfi-1.scm \
|
||||
\
|
||||
language/tree-il.scm \
|
||||
language/tree-il/analyze.scm \
|
||||
language/tree-il/canonicalize.scm \
|
||||
language/tree-il/compile-cps.scm \
|
||||
language/tree-il/debug.scm \
|
||||
language/tree-il/effects.scm \
|
||||
language/tree-il/fix-letrec.scm \
|
||||
language/tree-il/optimize.scm \
|
||||
language/tree-il/peval.scm \
|
||||
language/tree-il/primitives.scm \
|
||||
language/tree-il/spec.scm \
|
||||
\
|
||||
language/cps.scm \
|
||||
language/cps/closure-conversion.scm \
|
||||
language/cps/compile-bytecode.scm \
|
||||
language/cps/constructors.scm \
|
||||
language/cps/contification.scm \
|
||||
language/cps/cse.scm \
|
||||
language/cps/dce.scm \
|
||||
language/cps/effects-analysis.scm \
|
||||
language/cps/elide-values.scm \
|
||||
language/cps/handle-interrupts.scm \
|
||||
language/cps/licm.scm \
|
||||
language/cps/peel-loops.scm \
|
||||
language/cps/primitives.scm \
|
||||
language/cps/prune-bailouts.scm \
|
||||
language/cps/prune-top-level-scopes.scm \
|
||||
language/cps/reify-primitives.scm \
|
||||
language/cps/renumber.scm \
|
||||
language/cps/rotate-loops.scm \
|
||||
language/cps/optimize.scm \
|
||||
language/cps/simplify.scm \
|
||||
language/cps/self-references.scm \
|
||||
language/cps/slot-allocation.scm \
|
||||
language/cps/spec.scm \
|
||||
language/cps/specialize-primcalls.scm \
|
||||
language/cps/specialize-numbers.scm \
|
||||
language/cps/split-rec.scm \
|
||||
language/cps/type-checks.scm \
|
||||
language/cps/type-fold.scm \
|
||||
language/cps/types.scm \
|
||||
language/cps/verify.scm \
|
||||
language/cps/with-cps.scm \
|
||||
\
|
||||
language/scheme/spec.scm \
|
||||
language/scheme/compile-tree-il.scm \
|
||||
language/scheme/decompile-tree-il.scm \
|
||||
\
|
||||
language/bytecode.scm \
|
||||
language/bytecode/spec.scm \
|
||||
\
|
||||
language/value/spec.scm \
|
||||
\
|
||||
system/base/pmatch.scm \
|
||||
system/base/syntax.scm \
|
||||
system/base/compile.scm \
|
||||
system/base/language.scm \
|
||||
system/base/lalr.scm \
|
||||
system/base/message.scm \
|
||||
system/base/target.scm \
|
||||
system/base/types.scm \
|
||||
system/base/ck.scm \
|
||||
\
|
||||
ice-9/boot-9.scm \
|
||||
ice-9/ports.scm \
|
||||
ice-9/r5rs.scm \
|
||||
ice-9/deprecated.scm \
|
||||
ice-9/binary-ports.scm \
|
||||
ice-9/command-line.scm \
|
||||
ice-9/control.scm \
|
||||
ice-9/format.scm \
|
||||
ice-9/getopt-long.scm \
|
||||
ice-9/i18n.scm \
|
||||
ice-9/match.scm \
|
||||
ice-9/networking.scm \
|
||||
ice-9/posix.scm \
|
||||
ice-9/rdelim.scm \
|
||||
ice-9/receive.scm \
|
||||
ice-9/regex.scm \
|
||||
ice-9/session.scm \
|
||||
ice-9/pretty-print.scm \
|
||||
\
|
||||
system/vm/assembler.scm \
|
||||
system/vm/debug.scm \
|
||||
system/vm/disassembler.scm \
|
||||
system/vm/dwarf.scm \
|
||||
system/vm/elf.scm \
|
||||
system/vm/frame.scm \
|
||||
system/vm/linker.scm \
|
||||
system/vm/loader.scm \
|
||||
system/vm/program.scm \
|
||||
system/vm/vm.scm \
|
||||
system/foreign.scm
|
|
@ -1,7 +1,7 @@
|
|||
# -*- makefile -*-
|
||||
GOBJECTS = $(SOURCES:%.scm=%.go) $(ELISP_SOURCES:%.el=%.go)
|
||||
|
||||
GUILE_WARNINGS = -Wunbound-variable -Warity-mismatch -Wformat
|
||||
GUILE_WARNINGS = -Wunbound-variable -Wmacro-use-before-definition -Warity-mismatch -Wformat
|
||||
|
||||
moddir = $(pkgdatadir)/$(GUILE_EFFECTIVE_VERSION)/$(modpath)
|
||||
nobase_mod_DATA = $(SOURCES) $(ELISP_SOURCES) $(NOCOMP_SOURCES)
|
||||
|
@ -28,7 +28,7 @@ SUFFIXES = .scm .el .go
|
|||
|
||||
.scm.go:
|
||||
$(AM_V_GUILEC)GUILE_AUTO_COMPILE=0 \
|
||||
$(top_builddir)/meta/uninstalled-env \
|
||||
$(top_builddir)/meta/build-env \
|
||||
guild compile --target="$(host)" $(GUILE_WARNINGS) \
|
||||
-L "$(abs_srcdir)" -L "$(abs_builddir)" \
|
||||
-L "$(abs_top_srcdir)/guile-readline" \
|
||||
|
@ -36,7 +36,7 @@ SUFFIXES = .scm .el .go
|
|||
|
||||
.el.go:
|
||||
$(AM_V_GUILEC)GUILE_AUTO_COMPILE=0 \
|
||||
$(top_builddir)/meta/uninstalled-env \
|
||||
$(top_builddir)/meta/build-env \
|
||||
guild compile --target="$(host)" $(GUILE_WARNINGS) \
|
||||
-L "$(abs_srcdir)" -L "$(abs_builddir)" \
|
||||
-L "$(abs_top_srcdir)/guile-readline" \
|
||||
|
|
|
@ -51,20 +51,20 @@
|
|||
|
||||
(with-benchmark-prefix "read"
|
||||
|
||||
(benchmark "_IONBF" 5 ;; this one is very slow
|
||||
(exercise-read (list _IONBF)))
|
||||
(benchmark "'none" 5 ;; this one is very slow
|
||||
(exercise-read (list 'none)))
|
||||
|
||||
(benchmark "_IOLBF" 10
|
||||
(exercise-read (list _IOLBF)))
|
||||
(benchmark "'line" 10
|
||||
(exercise-read (list 'line)))
|
||||
|
||||
(benchmark "_IOFBF 4096" 10
|
||||
(exercise-read (list _IOFBF 4096)))
|
||||
(benchmark "'block 4096" 10
|
||||
(exercise-read (list 'block 4096)))
|
||||
|
||||
(benchmark "_IOFBF 8192" 10
|
||||
(exercise-read (list _IOFBF 8192)))
|
||||
(benchmark "'block 8192" 10
|
||||
(exercise-read (list 'block 8192)))
|
||||
|
||||
(benchmark "_IOFBF 16384" 10
|
||||
(exercise-read (list _IOFBF 16384)))
|
||||
(benchmark "'block 16384" 10
|
||||
(exercise-read (list 'block 16384)))
|
||||
|
||||
(benchmark "small strings" 100000
|
||||
(call-with-input-string small read))
|
||||
|
|
|
@ -43,7 +43,7 @@
|
|||
|
||||
(benchmark "uniform-vector-read!" 20000
|
||||
(let ((input (open-input-file file-name)))
|
||||
(setvbuf input _IONBF)
|
||||
(setvbuf input 'none)
|
||||
(uniform-vector-read! buf input)
|
||||
(close input)))
|
||||
|
||||
|
|
31
bootstrap/Makefile.am
Normal file
31
bootstrap/Makefile.am
Normal file
|
@ -0,0 +1,31 @@
|
|||
## Process this file with automake to produce Makefile.in.
|
||||
##
|
||||
## Copyright (C) 2009, 2010, 2011, 2012, 2013,
|
||||
## 2014, 2015 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
|
||||
|
||||
|
||||
GUILE_WARNINGS =
|
||||
GUILE_OPTIMIZATIONS = -O1
|
||||
|
||||
include $(top_srcdir)/am/bootstrap.am
|
||||
|
||||
# We must build the evaluator first, so that we can be sure to control
|
||||
# the stack.
|
||||
$(filter-out ice-9/eval.go, $(GOBJECTS)): ice-9/eval.go
|
|
@ -1,15 +1,15 @@
|
|||
eval '(exit $?0)' && eval 'exec perl -wS "$0" ${1+"$@"}'
|
||||
eval '(exit $?0)' && eval 'exec perl -wS "$0" "$@"'
|
||||
& eval 'exec perl -wS "$0" $argv:q'
|
||||
if 0;
|
||||
# Generate a release announcement message.
|
||||
|
||||
my $VERSION = '2012-06-08 06:53'; # UTC
|
||||
my $VERSION = '2016-01-12 23:09'; # 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-2014 Free Software Foundation, Inc.
|
||||
# Copyright (C) 2002-2017 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
|
||||
|
@ -29,15 +29,18 @@ my $VERSION = '2012-06-08 06:53'; # UTC
|
|||
use strict;
|
||||
|
||||
use Getopt::Long;
|
||||
use Digest::MD5;
|
||||
eval { require Digest::SHA; }
|
||||
or eval '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');
|
||||
my %digest_classes =
|
||||
(
|
||||
'md5' => (eval { require Digest::MD5; } and 'Digest::MD5'),
|
||||
'sha1' => ((eval { require Digest::SHA; } and 'Digest::SHA')
|
||||
or (eval { require Digest::SHA1; } and 'Digest::SHA1'))
|
||||
);
|
||||
my $srcdir = '.';
|
||||
|
||||
sub usage ($)
|
||||
|
@ -157,15 +160,13 @@ sub print_checksums (@)
|
|||
|
||||
foreach my $meth (qw (md5 sha1))
|
||||
{
|
||||
my $class = $digest_classes{$meth} or next;
|
||||
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);
|
||||
my $dig = $class->new->addfile(*IN)->hexdigest;
|
||||
close IN;
|
||||
print "$dig $f\n";
|
||||
}
|
||||
|
@ -416,14 +417,15 @@ sub get_tool_versions ($$)
|
|||
@url_dir_list
|
||||
or (warn "URL directory name(s) not specified\n"), $fail = 1;
|
||||
|
||||
my @tool_list = split ',', $bootstrap_tools;
|
||||
my @tool_list = split ',', $bootstrap_tools
|
||||
if $bootstrap_tools;
|
||||
|
||||
grep (/^gnulib$/, @tool_list) ^ defined $gnulib_version
|
||||
and (warn "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}
|
||||
!$release_type || exists $valid_release_types{$release_type}
|
||||
or (warn "'$release_type': invalid release type\n"), $fail = 1;
|
||||
|
||||
@ARGV
|
||||
|
@ -550,6 +552,6 @@ EOF
|
|||
## 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-time-zone: "UTC0"
|
||||
## time-stamp-end: "'; # UTC"
|
||||
## End:
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
# Output a system dependent set of variables, describing how to set the
|
||||
# run time search path of shared libraries in an executable.
|
||||
#
|
||||
# Copyright 1996-2014 Free Software Foundation, Inc.
|
||||
# Copyright 1996-2017 Free Software Foundation, Inc.
|
||||
# Taken from GNU libtool, 2001
|
||||
# Originally by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996
|
||||
#
|
||||
|
@ -367,11 +367,7 @@ else
|
|||
dgux*)
|
||||
hardcode_libdir_flag_spec='-L$libdir'
|
||||
;;
|
||||
freebsd2.2*)
|
||||
hardcode_libdir_flag_spec='-R$libdir'
|
||||
hardcode_direct=yes
|
||||
;;
|
||||
freebsd2*)
|
||||
freebsd2.[01]*)
|
||||
hardcode_direct=yes
|
||||
hardcode_minus_L=yes
|
||||
;;
|
||||
|
@ -548,13 +544,11 @@ case "$host_os" in
|
|||
dgux*)
|
||||
library_names_spec='$libname$shrext'
|
||||
;;
|
||||
freebsd[23].*)
|
||||
library_names_spec='$libname$shrext$versuffix'
|
||||
;;
|
||||
freebsd* | dragonfly*)
|
||||
case "$host_os" in
|
||||
freebsd[123]*)
|
||||
library_names_spec='$libname$shrext$versuffix' ;;
|
||||
*)
|
||||
library_names_spec='$libname$shrext' ;;
|
||||
esac
|
||||
library_names_spec='$libname$shrext'
|
||||
;;
|
||||
gnu*)
|
||||
library_names_spec='$libname$shrext'
|
||||
|
|
|
@ -2,10 +2,9 @@
|
|||
# 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=2013-10-10.09
|
||||
scriptversion=2016-12-31.18
|
||||
|
||||
# Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013
|
||||
# Free Software Foundation, Inc.
|
||||
# Copyright 2003-2017 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
|
||||
|
@ -21,17 +20,16 @@ scriptversion=2013-10-10.09
|
|||
# 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.
|
||||
# Send bug reports and any other correspondence to bug-gnulib@gnu.org.
|
||||
#
|
||||
# The latest version of this script, and the companion template, is
|
||||
# available from Texinfo CVS:
|
||||
# http://savannah.gnu.org/cgi-bin/viewcvs/texinfo/texinfo/util/gendocs.sh
|
||||
# http://savannah.gnu.org/cgi-bin/viewcvs/texinfo/texinfo/util/gendocs_template
|
||||
# available from the Gnulib repository:
|
||||
#
|
||||
# An up-to-date copy is also maintained in Gnulib (gnu.org/software/gnulib).
|
||||
# http://git.savannah.gnu.org/cgit/gnulib.git/tree/build-aux/gendocs.sh
|
||||
# http://git.savannah.gnu.org/cgit/gnulib.git/tree/doc/gendocs_template
|
||||
|
||||
# TODO:
|
||||
# - image importation was only implemented for HTML generated by
|
||||
# - image importing was only implemented for HTML generated by
|
||||
# makeinfo. But it should be simple enough to adjust.
|
||||
# - images are not imported in the source tarball. All the needed
|
||||
# formats (PDF, PNG, etc.) should be included.
|
||||
|
@ -39,12 +37,12 @@ scriptversion=2013-10-10.09
|
|||
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"
|
||||
scripturl="http://git.savannah.gnu.org/cgit/gnulib.git/plain/build-aux/gendocs.sh"
|
||||
templateurl="http://git.savannah.gnu.org/cgit/gnulib.git/plain/doc/gendocs_template"
|
||||
|
||||
: ${SETLANG="env LANG= LC_MESSAGES= LC_ALL= LANGUAGE="}
|
||||
: ${MAKEINFO="makeinfo"}
|
||||
: ${TEXI2DVI="texi2dvi -t @finalout"}
|
||||
: ${TEXI2DVI="texi2dvi"}
|
||||
: ${DOCBOOK2HTML="docbook2html"}
|
||||
: ${DOCBOOK2PDF="docbook2pdf"}
|
||||
: ${DOCBOOK2TXT="docbook2txt"}
|
||||
|
@ -54,9 +52,27 @@ templateurl="http://savannah.gnu.org/cgi-bin/viewcvs/~checkout~/texinfo/texinfo/
|
|||
unset CDPATH
|
||||
unset use_texi2html
|
||||
|
||||
MANUAL_TITLE=
|
||||
PACKAGE=
|
||||
EMAIL=webmasters@gnu.org # please override with --email
|
||||
commonarg= # passed to all makeinfo/texi2html invcations.
|
||||
dirargs= # passed to all tools (-I dir).
|
||||
dirs= # -I directories.
|
||||
htmlarg="--css-ref=/software/gnulib/manual.css -c TOP_NODE_UP_URL=/manual"
|
||||
infoarg=--no-split
|
||||
generate_ascii=true
|
||||
generate_html=true
|
||||
generate_info=true
|
||||
generate_tex=true
|
||||
outdir=manual
|
||||
source_extra=
|
||||
split=node
|
||||
srcfile=
|
||||
texarg="-t @finalout"
|
||||
|
||||
version="gendocs.sh $scriptversion
|
||||
|
||||
Copyright 2013 Free Software Foundation, Inc.
|
||||
Copyright 2017 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."
|
||||
|
@ -75,11 +91,16 @@ Options:
|
|||
-o OUTDIR write files into OUTDIR, instead of manual/.
|
||||
-I DIR append DIR to the Texinfo search path.
|
||||
--common ARG pass ARG in all invocations.
|
||||
--html ARG pass ARG to makeinfo or texi2html for HTML targets.
|
||||
--html ARG pass ARG to makeinfo or texi2html for HTML targets,
|
||||
instead of '$htmlarg'.
|
||||
--info ARG pass ARG to makeinfo for Info, instead of --no-split.
|
||||
--no-ascii skip generating the plain text output.
|
||||
--no-html skip generating the html output.
|
||||
--no-info skip generating the info output.
|
||||
--no-tex skip generating the dvi and pdf output.
|
||||
--source ARG include ARG in tar archive of sources.
|
||||
--split HOW make split HTML by node, section, chapter; default node.
|
||||
--tex ARG pass ARG to texi2dvi for DVI and PDF, instead of -t @finalout.
|
||||
|
||||
--texi2html use texi2html to make HTML target, with all split versions.
|
||||
--docbook convert through DocBook too (xml, txt, html, pdf).
|
||||
|
@ -131,23 +152,9 @@ 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.
|
||||
Email bug reports or enhancement requests to bug-gnulib@gnu.org.
|
||||
"
|
||||
|
||||
MANUAL_TITLE=
|
||||
PACKAGE=
|
||||
EMAIL=webmasters@gnu.org # please override with --email
|
||||
commonarg= # passed to all makeinfo/texi2html invcations.
|
||||
dirargs= # passed to all tools (-I dir).
|
||||
dirs= # -I's directories.
|
||||
htmlarg=
|
||||
infoarg=--no-split
|
||||
generate_ascii=true
|
||||
outdir=manual
|
||||
source_extra=
|
||||
split=node
|
||||
srcfile=
|
||||
|
||||
while test $# -gt 0; do
|
||||
case $1 in
|
||||
-s) shift; srcfile=$1;;
|
||||
|
@ -159,8 +166,12 @@ while test $# -gt 0; do
|
|||
--html) shift; htmlarg=$1;;
|
||||
--info) shift; infoarg=$1;;
|
||||
--no-ascii) generate_ascii=false;;
|
||||
--no-html) generate_ascii=false;;
|
||||
--no-info) generate_info=false;;
|
||||
--no-tex) generate_tex=false;;
|
||||
--source) shift; source_extra=$1;;
|
||||
--split) shift; split=$1;;
|
||||
--tex) shift; texarg=$1;;
|
||||
--texi2html) use_texi2html=1;;
|
||||
|
||||
--help) echo "$usage"; exit 0;;
|
||||
|
@ -221,8 +232,9 @@ calcsize()
|
|||
|
||||
# copy_images OUTDIR HTML-FILE...
|
||||
# -------------------------------
|
||||
# Copy all the images needed by the HTML-FILEs into OUTDIR. Look
|
||||
# for them in the -I directories.
|
||||
# Copy all the images needed by the HTML-FILEs into OUTDIR.
|
||||
# Look for them in . and the -I directories; this is simpler than what
|
||||
# makeinfo supports with -I, but hopefully it will suffice.
|
||||
copy_images()
|
||||
{
|
||||
local odir
|
||||
|
@ -232,7 +244,7 @@ copy_images()
|
|||
BEGIN {
|
||||
\$me = '$prog';
|
||||
\$odir = '$odir';
|
||||
@dirs = qw($dirs);
|
||||
@dirs = qw(. $dirs);
|
||||
}
|
||||
" -e '
|
||||
/<img src="(.*?)"/g && ++$need{$1};
|
||||
|
@ -270,32 +282,39 @@ echo "Making output for $srcfile"
|
|||
echo " in `pwd`"
|
||||
mkdir -p "$outdir/"
|
||||
|
||||
cmd="$SETLANG $MAKEINFO -o $PACKAGE.info $commonarg $infoarg \"$srcfile\""
|
||||
echo "Generating info... ($cmd)"
|
||||
rm -f $PACKAGE.info* # get rid of any strays
|
||||
eval "$cmd"
|
||||
tar czf "$outdir/$PACKAGE.info.tar.gz" $PACKAGE.info*
|
||||
ls -l "$outdir/$PACKAGE.info.tar.gz"
|
||||
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.
|
||||
#
|
||||
if $generate_info; then
|
||||
cmd="$SETLANG $MAKEINFO -o $PACKAGE.info $commonarg $infoarg \"$srcfile\""
|
||||
echo "Generating info... ($cmd)"
|
||||
rm -f $PACKAGE.info* # get rid of any strays
|
||||
eval "$cmd"
|
||||
tar czf "$outdir/$PACKAGE.info.tar.gz" $PACKAGE.info*
|
||||
ls -l "$outdir/$PACKAGE.info.tar.gz"
|
||||
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.
|
||||
fi # end info
|
||||
|
||||
cmd="$SETLANG $TEXI2DVI $dirargs \"$srcfile\""
|
||||
printf "\nGenerating dvi... ($cmd)\n"
|
||||
eval "$cmd"
|
||||
# compress/finish dvi:
|
||||
gzip -f -9 $PACKAGE.dvi
|
||||
dvi_gz_size=`calcsize $PACKAGE.dvi.gz`
|
||||
mv $PACKAGE.dvi.gz "$outdir/"
|
||||
ls -l "$outdir/$PACKAGE.dvi.gz"
|
||||
#
|
||||
if $generate_tex; then
|
||||
cmd="$SETLANG $TEXI2DVI $dirargs $texarg \"$srcfile\""
|
||||
printf "\nGenerating dvi... ($cmd)\n"
|
||||
eval "$cmd"
|
||||
# compress/finish dvi:
|
||||
gzip -f -9 $PACKAGE.dvi
|
||||
dvi_gz_size=`calcsize $PACKAGE.dvi.gz`
|
||||
mv $PACKAGE.dvi.gz "$outdir/"
|
||||
ls -l "$outdir/$PACKAGE.dvi.gz"
|
||||
|
||||
cmd="$SETLANG $TEXI2DVI --pdf $dirargs \"$srcfile\""
|
||||
printf "\nGenerating pdf... ($cmd)\n"
|
||||
eval "$cmd"
|
||||
pdf_size=`calcsize $PACKAGE.pdf`
|
||||
mv $PACKAGE.pdf "$outdir/"
|
||||
ls -l "$outdir/$PACKAGE.pdf"
|
||||
cmd="$SETLANG $TEXI2DVI --pdf $dirargs $texarg \"$srcfile\""
|
||||
printf "\nGenerating pdf... ($cmd)\n"
|
||||
eval "$cmd"
|
||||
pdf_size=`calcsize $PACKAGE.pdf`
|
||||
mv $PACKAGE.pdf "$outdir/"
|
||||
ls -l "$outdir/$PACKAGE.pdf"
|
||||
fi # end tex (dvi + pdf)
|
||||
|
||||
#
|
||||
if $generate_ascii; then
|
||||
opt="-o $PACKAGE.txt --no-split --no-headers $commonarg"
|
||||
cmd="$SETLANG $MAKEINFO $opt \"$srcfile\""
|
||||
|
@ -308,6 +327,9 @@ if $generate_ascii; then
|
|||
ls -l "$outdir/$PACKAGE.txt" "$outdir/$PACKAGE.txt.gz"
|
||||
fi
|
||||
|
||||
#
|
||||
|
||||
if $generate_html; then
|
||||
# Split HTML at level $1. Used for texi2html.
|
||||
html_split()
|
||||
{
|
||||
|
@ -382,7 +404,9 @@ else # use texi2html:
|
|||
html_split chapter
|
||||
html_split section
|
||||
fi
|
||||
fi # end html
|
||||
|
||||
#
|
||||
printf "\nMaking .tar.gz for sources...\n"
|
||||
d=`dirname $srcfile`
|
||||
(
|
||||
|
@ -393,6 +417,8 @@ d=`dirname $srcfile`
|
|||
)
|
||||
texi_tgz_size=`calcsize "$outdir/$PACKAGE.texi.tar.gz"`
|
||||
|
||||
#
|
||||
# Do everything again through docbook.
|
||||
if test -n "$docbook"; then
|
||||
opt="-o - --docbook $commonarg"
|
||||
cmd="$SETLANG $MAKEINFO $opt \"$srcfile\" >${srcdir}/$PACKAGE-db.xml"
|
||||
|
@ -431,7 +457,8 @@ if test -n "$docbook"; then
|
|||
mv $PACKAGE-db.pdf "$outdir/"
|
||||
fi
|
||||
|
||||
printf "\nMaking index file...\n"
|
||||
#
|
||||
printf "\nMaking index.html for $PACKAGE...\n"
|
||||
if test -z "$use_texi2html"; then
|
||||
CONDS="/%%IF *HTML_SECTION%%/,/%%ENDIF *HTML_SECTION%%/d;\
|
||||
/%%IF *HTML_CHAPTER%%/,/%%ENDIF *HTML_CHAPTER%%/d"
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
#!/bin/sh
|
||||
# Print a version string.
|
||||
scriptversion=2012-12-31.23; # UTC
|
||||
scriptversion=2017-01-09.19; # UTC
|
||||
|
||||
# Copyright (C) 2007-2014 Free Software Foundation, Inc.
|
||||
# Copyright (C) 2007-2017 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
|
||||
|
@ -85,9 +85,10 @@ Print a version string.
|
|||
|
||||
Options:
|
||||
|
||||
--prefix prefix of git tags (default 'v')
|
||||
--prefix PREFIX prefix of git tags (default 'v')
|
||||
--match pattern for git tags to match (default: '\$prefix*')
|
||||
--fallback fallback version to use if \"git --version\" fails
|
||||
--fallback VERSION
|
||||
fallback version to use if \"git --version\" fails
|
||||
|
||||
--help display this help and exit
|
||||
--version output version information and exit
|
||||
|
@ -104,9 +105,9 @@ while test $# -gt 0; do
|
|||
case $1 in
|
||||
--help) echo "$usage"; exit 0;;
|
||||
--version) echo "$version"; exit 0;;
|
||||
--prefix) shift; prefix="$1";;
|
||||
--prefix) shift; prefix=${1?};;
|
||||
--match) shift; match="$1";;
|
||||
--fallback) shift; fallback="$1";;
|
||||
--fallback) shift; fallback=${1?};;
|
||||
-*)
|
||||
echo "$0: Unknown option '$1'." >&2
|
||||
echo "$0: Try '--help' for more information." >&2
|
||||
|
@ -205,7 +206,7 @@ v=`echo "$v" |sed "s/^$prefix//"`
|
|||
# string we're using came from git. I.e., skip the test if it's "UNKNOWN"
|
||||
# or if it came from .tarball-version.
|
||||
if test "x$v_from_git" != x; then
|
||||
# Don't declare a version "dirty" merely because a time stamp has changed.
|
||||
# Don't declare a version "dirty" merely because a timestamp has changed.
|
||||
git update-index --refresh > /dev/null 2>&1
|
||||
|
||||
dirty=`exec 2>/dev/null;git diff-index --name-only HEAD` || dirty=
|
||||
|
@ -220,12 +221,12 @@ if test "x$v_from_git" != x; then
|
|||
fi
|
||||
|
||||
# Omit the trailing newline, so that m4_esyscmd can use the result directly.
|
||||
echo "$v" | tr -d "$nl"
|
||||
printf %s "$v"
|
||||
|
||||
# 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-time-zone: "UTC0"
|
||||
# time-stamp-end: "; # UTC"
|
||||
# End:
|
||||
|
|
|
@ -1,15 +1,15 @@
|
|||
eval '(exit $?0)' && eval 'exec perl -wS "$0" ${1+"$@"}'
|
||||
eval '(exit $?0)' && eval 'exec perl -wS "$0" "$@"'
|
||||
& eval 'exec perl -wS "$0" $argv:q'
|
||||
if 0;
|
||||
# Convert git log output to ChangeLog format.
|
||||
|
||||
my $VERSION = '2012-07-29 06:11'; # UTC
|
||||
my $VERSION = '2016-03-22 21:49'; # 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-2014 Free Software Foundation, Inc.
|
||||
# Copyright (C) 2008-2017 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
|
||||
|
@ -72,6 +72,9 @@ OPTIONS:
|
|||
directory can be derived.
|
||||
--since=DATE convert only the logs since DATE;
|
||||
the default is to convert all log entries.
|
||||
--until=DATE convert only the logs older than DATE.
|
||||
--ignore-matching=PAT ignore commit messages whose first lines match PAT.
|
||||
--ignore-line=PAT ignore lines of commit messages that match PAT.
|
||||
--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'
|
||||
|
@ -220,10 +223,13 @@ sub git_dir_option($)
|
|||
|
||||
{
|
||||
my $since_date;
|
||||
my $until_date;
|
||||
my $format_string = '%s%n%b%n';
|
||||
my $amend_file;
|
||||
my $append_dot = 0;
|
||||
my $cluster = 1;
|
||||
my $ignore_matching;
|
||||
my $ignore_line;
|
||||
my $strip_tab = 0;
|
||||
my $strip_cherry_pick = 0;
|
||||
my $srcdir;
|
||||
|
@ -232,10 +238,13 @@ sub git_dir_option($)
|
|||
help => sub { usage 0 },
|
||||
version => sub { print "$ME version $VERSION\n"; exit },
|
||||
'since=s' => \$since_date,
|
||||
'until=s' => \$until_date,
|
||||
'format=s' => \$format_string,
|
||||
'amend=s' => \$amend_file,
|
||||
'append-dot' => \$append_dot,
|
||||
'cluster!' => \$cluster,
|
||||
'ignore-matching=s' => \$ignore_matching,
|
||||
'ignore-line=s' => \$ignore_line,
|
||||
'strip-tab' => \$strip_tab,
|
||||
'strip-cherry-pick' => \$strip_cherry_pick,
|
||||
'srcdir=s' => \$srcdir,
|
||||
|
@ -243,6 +252,8 @@ sub git_dir_option($)
|
|||
|
||||
defined $since_date
|
||||
and unshift @ARGV, "--since=$since_date";
|
||||
defined $until_date
|
||||
and unshift @ARGV, "--until=$until_date";
|
||||
|
||||
# This is a hash that maps an SHA1 to perl code (i.e., s/old/new/)
|
||||
# that makes a correction in the log or attribution of that commit.
|
||||
|
@ -259,6 +270,7 @@ sub git_dir_option($)
|
|||
my $prev_multi_paragraph;
|
||||
my $prev_date_line = '';
|
||||
my @prev_coauthors = ();
|
||||
my @skipshas = ();
|
||||
while (1)
|
||||
{
|
||||
defined (my $in = <PIPE>)
|
||||
|
@ -279,6 +291,19 @@ sub git_dir_option($)
|
|||
$sha =~ /^[0-9a-fA-F]{40}$/
|
||||
or die "$ME:$.: invalid SHA1: $sha\n";
|
||||
|
||||
my $skipflag = 0;
|
||||
if (@skipshas)
|
||||
{
|
||||
foreach(@skipshas)
|
||||
{
|
||||
if ($sha =~ /^$_/)
|
||||
{
|
||||
$skipflag = $_;
|
||||
last;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# If this commit's log requires any transformation, do it now.
|
||||
my $code = $amend_code->{$sha};
|
||||
if (defined $code)
|
||||
|
@ -306,7 +331,7 @@ sub git_dir_option($)
|
|||
$rest =~ s/^\s*\(cherry picked from commit [\da-f]+\)\n//m;
|
||||
}
|
||||
|
||||
my @line = split "\n", $rest;
|
||||
my @line = split /[ \t]*\n/, $rest;
|
||||
my $author_line = shift @line;
|
||||
defined $author_line
|
||||
or die "$ME:$.: unexpected EOF\n";
|
||||
|
@ -316,17 +341,18 @@ sub git_dir_option($)
|
|||
|
||||
# Format 'Copyright-paperwork-exempt: Yes' as a standard ChangeLog
|
||||
# `(tiny change)' annotation.
|
||||
my $tiny = (grep (/^Copyright-paperwork-exempt:\s+[Yy]es$/, @line)
|
||||
my $tiny = (grep (/^(?:Copyright-paperwork-exempt|Tiny-change):\s+[Yy]es$/, @line)
|
||||
? ' (tiny change)' : '');
|
||||
|
||||
my $date_line = sprintf "%s %s$tiny\n",
|
||||
strftime ("%F", localtime ($1)), $2;
|
||||
strftime ("%Y-%m-%d", localtime ($1)), $2;
|
||||
|
||||
my @coauthors = grep /^Co-authored-by:.*$/, @line;
|
||||
# Omit meta-data lines we've already interpreted.
|
||||
@line = grep !/^(?:Signed-off-by:[ ].*>$
|
||||
|Co-authored-by:[ ]
|
||||
|Copyright-paperwork-exempt:[ ]
|
||||
|Tiny-change:[ ]
|
||||
)/x, @line;
|
||||
|
||||
# Remove leading and trailing blank lines.
|
||||
|
@ -336,68 +362,109 @@ sub git_dir_option($)
|
|||
while ($line[$#line] =~ /^\s*$/) { pop @line; }
|
||||
}
|
||||
|
||||
# Record whether there are two or more paragraphs.
|
||||
my $multi_paragraph = grep /^\s*$/, @line;
|
||||
# Handle Emacs gitmerge.el "skipped" commits.
|
||||
# Yes, this should be controlled by an option. So sue me.
|
||||
if ( grep /^(; )?Merge from /, @line )
|
||||
{
|
||||
my $found = 0;
|
||||
foreach (@line)
|
||||
{
|
||||
if (grep /^The following commit.*skipped:$/, $_)
|
||||
{
|
||||
$found = 1;
|
||||
## Reset at each merge to reduce chance of false matches.
|
||||
@skipshas = ();
|
||||
next;
|
||||
}
|
||||
if ($found && $_ =~ /^([0-9a-fA-F]{7,}) [^ ]/)
|
||||
{
|
||||
push ( @skipshas, $1 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Format 'Co-authored-by: A U Thor <email@example.com>' lines in
|
||||
# standard multi-author ChangeLog format.
|
||||
for (@coauthors)
|
||||
# Ignore commits that match the --ignore-matching pattern, if specified.
|
||||
if (defined $ignore_matching && @line && $line[0] =~ /$ignore_matching/)
|
||||
{
|
||||
s/^Co-authored-by:\s*/\t /;
|
||||
s/\s*</ </;
|
||||
|
||||
/<.*?@.*\..*>/
|
||||
or warn "$ME: warning: missing email address for "
|
||||
. substr ($_, 5) . "\n";
|
||||
$skipflag = 1;
|
||||
}
|
||||
elsif ($skipflag)
|
||||
{
|
||||
## Perhaps only warn if a pattern matches more than once?
|
||||
warn "$ME: warning: skipping $sha due to $skipflag\n";
|
||||
}
|
||||
|
||||
# If clustering of commit messages has been disabled, if this header
|
||||
# would be different from the previous date/name/email/coauthors header,
|
||||
# or if this or the previous entry consists of two or more paragraphs,
|
||||
# then print the header.
|
||||
if ( ! $cluster
|
||||
|| $date_line ne $prev_date_line
|
||||
|| "@coauthors" ne "@prev_coauthors"
|
||||
|| $multi_paragraph
|
||||
|| $prev_multi_paragraph)
|
||||
if (! $skipflag)
|
||||
{
|
||||
$prev_date_line eq ''
|
||||
or print "\n";
|
||||
print $date_line;
|
||||
@coauthors
|
||||
and print join ("\n", @coauthors), "\n";
|
||||
}
|
||||
$prev_date_line = $date_line;
|
||||
@prev_coauthors = @coauthors;
|
||||
$prev_multi_paragraph = $multi_paragraph;
|
||||
|
||||
# If there were any lines
|
||||
if (@line == 0)
|
||||
{
|
||||
warn "$ME: warning: empty commit message:\n $date_line\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
if ($append_dot)
|
||||
if (defined $ignore_line && @line)
|
||||
{
|
||||
# If the first line of the message has enough room, then
|
||||
if (length $line[0] < 72)
|
||||
{
|
||||
# append a dot if there is no other punctuation or blank
|
||||
# at the end.
|
||||
$line[0] =~ /[[:punct:]\s]$/
|
||||
or $line[0] .= '.';
|
||||
}
|
||||
@line = grep ! /$ignore_line/, @line;
|
||||
while ($line[$#line] =~ /^\s*$/) { pop @line; }
|
||||
}
|
||||
|
||||
# Remove one additional leading TAB from each line.
|
||||
$strip_tab
|
||||
and map { s/^\t// } @line;
|
||||
# Record whether there are two or more paragraphs.
|
||||
my $multi_paragraph = grep /^\s*$/, @line;
|
||||
|
||||
# Prefix each non-empty line with a TAB.
|
||||
@line = map { length $_ ? "\t$_" : '' } @line;
|
||||
# Format 'Co-authored-by: A U Thor <email@example.com>' lines in
|
||||
# standard multi-author ChangeLog format.
|
||||
for (@coauthors)
|
||||
{
|
||||
s/^Co-authored-by:\s*/\t /;
|
||||
s/\s*</ </;
|
||||
|
||||
print "\n", join ("\n", @line), "\n";
|
||||
/<.*?@.*\..*>/
|
||||
or warn "$ME: warning: missing email address for "
|
||||
. substr ($_, 5) . "\n";
|
||||
}
|
||||
|
||||
# If clustering of commit messages has been disabled, if this header
|
||||
# would be different from the previous date/name/etc. header,
|
||||
# or if this or the previous entry consists of two or more paragraphs,
|
||||
# then print the header.
|
||||
if ( ! $cluster
|
||||
|| $date_line ne $prev_date_line
|
||||
|| "@coauthors" ne "@prev_coauthors"
|
||||
|| $multi_paragraph
|
||||
|| $prev_multi_paragraph)
|
||||
{
|
||||
$prev_date_line eq ''
|
||||
or print "\n";
|
||||
print $date_line;
|
||||
@coauthors
|
||||
and print join ("\n", @coauthors), "\n";
|
||||
}
|
||||
$prev_date_line = $date_line;
|
||||
@prev_coauthors = @coauthors;
|
||||
$prev_multi_paragraph = $multi_paragraph;
|
||||
|
||||
# If there were any lines
|
||||
if (@line == 0)
|
||||
{
|
||||
warn "$ME: warning: empty commit message:\n $date_line\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
if ($append_dot)
|
||||
{
|
||||
# If the first line of the message has enough room, then
|
||||
if (length $line[0] < 72)
|
||||
{
|
||||
# append a dot if there is no other punctuation or blank
|
||||
# at the end.
|
||||
$line[0] =~ /[[:punct:]\s]$/
|
||||
or $line[0] .= '.';
|
||||
}
|
||||
}
|
||||
|
||||
# Remove one additional leading TAB from each line.
|
||||
$strip_tab
|
||||
and map { s/^\t// } @line;
|
||||
|
||||
# Prefix each non-empty line with a TAB.
|
||||
@line = map { length $_ ? "\t$_" : '' } @line;
|
||||
|
||||
print "\n", join ("\n", @line), "\n";
|
||||
}
|
||||
}
|
||||
|
||||
defined ($in = <PIPE>)
|
||||
|
@ -427,6 +494,6 @@ sub git_dir_option($)
|
|||
# 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-time-zone: "UTC0"
|
||||
# time-stamp-end: "'; # UTC"
|
||||
# End:
|
||||
|
|
|
@ -2,9 +2,9 @@
|
|||
# Run this after each non-alpha release, to update the web documentation at
|
||||
# http://www.gnu.org/software/$pkg/manual/
|
||||
|
||||
VERSION=2012-12-16.14; # UTC
|
||||
VERSION=2016-01-12.23; # UTC
|
||||
|
||||
# Copyright (C) 2009-2014 Free Software Foundation, Inc.
|
||||
# Copyright (C) 2009-2017 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
|
||||
|
@ -40,6 +40,7 @@ assumes all documentation is in the doc/ sub-directory.
|
|||
Options:
|
||||
-C, --builddir=DIR location of (configured) Makefile (default: .)
|
||||
-n, --dry-run don't actually commit anything
|
||||
-m, --mirror remove out of date files from document server
|
||||
--help print this help, then exit
|
||||
--version print version number, then exit
|
||||
|
||||
|
@ -107,6 +108,7 @@ find_tool XARGS gxargs xargs
|
|||
|
||||
builddir=.
|
||||
dryrun=
|
||||
rm_stale='echo'
|
||||
while test $# != 0
|
||||
do
|
||||
# Handle --option=value by splitting apart and putting back on argv.
|
||||
|
@ -115,7 +117,7 @@ do
|
|||
opt=$(echo "$1" | sed -e 's/=.*//')
|
||||
val=$(echo "$1" | sed -e 's/[^=]*=//')
|
||||
shift
|
||||
set dummy "$opt" "$val" ${1+"$@"}; shift
|
||||
set dummy "$opt" "$val" "$@"; shift
|
||||
;;
|
||||
esac
|
||||
|
||||
|
@ -123,6 +125,7 @@ do
|
|||
--help|--version) ${1#--};;
|
||||
-C|--builddir) shift; builddir=$1; shift ;;
|
||||
-n|--dry-run) dryrun=echo; shift;;
|
||||
-m|--mirror) rm_stale=''; shift;;
|
||||
--*) die "unrecognized option: $1";;
|
||||
*) break;;
|
||||
esac
|
||||
|
@ -159,6 +162,7 @@ $GIT submodule update --recursive
|
|||
./bootstrap
|
||||
srcdir=$(pwd)
|
||||
cd "$builddir"
|
||||
builddir=$(pwd)
|
||||
./config.status --recheck
|
||||
./config.status
|
||||
make
|
||||
|
@ -175,13 +179,25 @@ $RSYNC -avP "$builddir"/doc/manual/ $tmp/$pkg/manual
|
|||
cd $tmp/$pkg/manual
|
||||
|
||||
# Add all the files. This is simpler than trying to add only the
|
||||
# new ones because of new directories: it would require iterating on
|
||||
# adding the outer directories, and then their contents.
|
||||
#
|
||||
# find guarantees that we add outer directories first.
|
||||
find . -name CVS -prune -o -print \
|
||||
# new ones because of new directories
|
||||
# First add non empty dirs individually
|
||||
find . -name CVS -prune -o -type d \! -empty -print \
|
||||
| $XARGS -n1 --no-run-if-empty -- $dryrun $CVS add -ko
|
||||
# Now add all files
|
||||
find . -name CVS -prune -o -type f -print \
|
||||
| $XARGS --no-run-if-empty -- $dryrun $CVS add -ko
|
||||
|
||||
# Report/Remove stale files
|
||||
# excluding doc server specific files like CVS/* and .symlinks
|
||||
if test -n "$rm_stale"; then
|
||||
echo 'Consider the --mirror option if all of the manual is generated,' >&2
|
||||
echo 'which will run `cvs remove` to remove stale files.' >&2
|
||||
fi
|
||||
{ find . \( -name CVS -o -type f -name '.*' \) -prune -o -type f -print
|
||||
(cd "$builddir"/doc/manual/ && find . -type f -print | sed p)
|
||||
} | sort | uniq -u \
|
||||
| $XARGS --no-run-if-empty -- ${rm_stale:-$dryrun} $CVS remove -f
|
||||
|
||||
$dryrun $CVS ci -m $version
|
||||
)
|
||||
|
||||
|
@ -189,6 +205,6 @@ $RSYNC -avP "$builddir"/doc/manual/ $tmp/$pkg/manual
|
|||
# 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-time-zone: "UTC0"
|
||||
# time-stamp-end: "; # UTC"
|
||||
# End:
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
#!/bin/sh
|
||||
# Sign files and upload them.
|
||||
|
||||
scriptversion=2013-03-19.17; # UTC
|
||||
scriptversion=2016-01-11.22; # UTC
|
||||
|
||||
# Copyright (C) 2004-2014 Free Software Foundation, Inc.
|
||||
# Copyright (C) 2004-2017 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
|
||||
|
@ -435,6 +435,6 @@ exit 0
|
|||
# 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-time-zone: "UTC0"
|
||||
# time-stamp-end: "; # UTC"
|
||||
# End:
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* A C macro for declaring that specific arguments must not be NULL.
|
||||
Copyright (C) 2009-2014 Free Software Foundation, Inc.
|
||||
Copyright (C) 2009-2017 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
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* C++ compatible function declaration macros.
|
||||
Copyright (C) 2010-2014 Free Software Foundation, Inc.
|
||||
Copyright (C) 2010-2017 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
|
||||
|
@ -17,6 +17,15 @@
|
|||
#ifndef _GL_CXXDEFS_H
|
||||
#define _GL_CXXDEFS_H
|
||||
|
||||
/* Begin/end the GNULIB_NAMESPACE namespace. */
|
||||
#if defined __cplusplus && defined GNULIB_NAMESPACE
|
||||
# define _GL_BEGIN_NAMESPACE namespace GNULIB_NAMESPACE {
|
||||
# define _GL_END_NAMESPACE }
|
||||
#else
|
||||
# define _GL_BEGIN_NAMESPACE
|
||||
# define _GL_END_NAMESPACE
|
||||
#endif
|
||||
|
||||
/* The three most frequent use cases of these macros are:
|
||||
|
||||
* For providing a substitute for a function that is missing on some
|
||||
|
@ -111,14 +120,25 @@
|
|||
that redirects to rpl_func, if GNULIB_NAMESPACE is defined.
|
||||
Example:
|
||||
_GL_CXXALIAS_RPL (open, int, (const char *filename, int flags, ...));
|
||||
*/
|
||||
|
||||
Wrapping rpl_func in an object with an inline conversion operator
|
||||
avoids a reference to rpl_func unless GNULIB_NAMESPACE::func is
|
||||
actually used in the program. */
|
||||
#define _GL_CXXALIAS_RPL(func,rettype,parameters) \
|
||||
_GL_CXXALIAS_RPL_1 (func, rpl_##func, rettype, parameters)
|
||||
#if defined __cplusplus && defined GNULIB_NAMESPACE
|
||||
# define _GL_CXXALIAS_RPL_1(func,rpl_func,rettype,parameters) \
|
||||
namespace GNULIB_NAMESPACE \
|
||||
{ \
|
||||
rettype (*const func) parameters = ::rpl_func; \
|
||||
static const struct _gl_ ## func ## _wrapper \
|
||||
{ \
|
||||
typedef rettype (*type) parameters; \
|
||||
\
|
||||
inline operator type () const \
|
||||
{ \
|
||||
return ::rpl_func; \
|
||||
} \
|
||||
} func = {}; \
|
||||
} \
|
||||
_GL_EXTERN_C int _gl_cxxalias_dummy
|
||||
#else
|
||||
|
@ -135,8 +155,15 @@
|
|||
# define _GL_CXXALIAS_RPL_CAST_1(func,rpl_func,rettype,parameters) \
|
||||
namespace GNULIB_NAMESPACE \
|
||||
{ \
|
||||
rettype (*const func) parameters = \
|
||||
reinterpret_cast<rettype(*)parameters>(::rpl_func); \
|
||||
static const struct _gl_ ## func ## _wrapper \
|
||||
{ \
|
||||
typedef rettype (*type) parameters; \
|
||||
\
|
||||
inline operator type () const \
|
||||
{ \
|
||||
return reinterpret_cast<type>(::rpl_func); \
|
||||
} \
|
||||
} func = {}; \
|
||||
} \
|
||||
_GL_EXTERN_C int _gl_cxxalias_dummy
|
||||
#else
|
||||
|
@ -150,19 +177,24 @@
|
|||
is defined.
|
||||
Example:
|
||||
_GL_CXXALIAS_SYS (open, int, (const char *filename, int flags, ...));
|
||||
*/
|
||||
|
||||
Wrapping func in an object with an inline conversion operator
|
||||
avoids a reference to func unless GNULIB_NAMESPACE::func is
|
||||
actually used in the program. */
|
||||
#if defined __cplusplus && defined GNULIB_NAMESPACE
|
||||
/* If we were to write
|
||||
rettype (*const func) parameters = ::func;
|
||||
like above in _GL_CXXALIAS_RPL_1, the compiler could optimize calls
|
||||
better (remove an indirection through a 'static' pointer variable),
|
||||
but then the _GL_CXXALIASWARN macro below would cause a warning not only
|
||||
for uses of ::func but also for uses of GNULIB_NAMESPACE::func. */
|
||||
# define _GL_CXXALIAS_SYS(func,rettype,parameters) \
|
||||
namespace GNULIB_NAMESPACE \
|
||||
{ \
|
||||
static rettype (*func) parameters = ::func; \
|
||||
} \
|
||||
# define _GL_CXXALIAS_SYS(func,rettype,parameters) \
|
||||
namespace GNULIB_NAMESPACE \
|
||||
{ \
|
||||
static const struct _gl_ ## func ## _wrapper \
|
||||
{ \
|
||||
typedef rettype (*type) parameters; \
|
||||
\
|
||||
inline operator type () const \
|
||||
{ \
|
||||
return ::func; \
|
||||
} \
|
||||
} func = {}; \
|
||||
} \
|
||||
_GL_EXTERN_C int _gl_cxxalias_dummy
|
||||
#else
|
||||
# define _GL_CXXALIAS_SYS(func,rettype,parameters) \
|
||||
|
@ -178,8 +210,15 @@
|
|||
# define _GL_CXXALIAS_SYS_CAST(func,rettype,parameters) \
|
||||
namespace GNULIB_NAMESPACE \
|
||||
{ \
|
||||
static rettype (*func) parameters = \
|
||||
reinterpret_cast<rettype(*)parameters>(::func); \
|
||||
static const struct _gl_ ## func ## _wrapper \
|
||||
{ \
|
||||
typedef rettype (*type) parameters; \
|
||||
\
|
||||
inline operator type () const \
|
||||
{ \
|
||||
return reinterpret_cast<type>(::func); \
|
||||
} \
|
||||
} func = {}; \
|
||||
} \
|
||||
_GL_EXTERN_C int _gl_cxxalias_dummy
|
||||
#else
|
||||
|
@ -202,9 +241,15 @@
|
|||
# define _GL_CXXALIAS_SYS_CAST2(func,rettype,parameters,rettype2,parameters2) \
|
||||
namespace GNULIB_NAMESPACE \
|
||||
{ \
|
||||
static rettype (*func) parameters = \
|
||||
reinterpret_cast<rettype(*)parameters>( \
|
||||
(rettype2(*)parameters2)(::func)); \
|
||||
static const struct _gl_ ## func ## _wrapper \
|
||||
{ \
|
||||
typedef rettype (*type) parameters; \
|
||||
\
|
||||
inline operator type () const \
|
||||
{ \
|
||||
return reinterpret_cast<type>((rettype2 (*) parameters2)(::func)); \
|
||||
} \
|
||||
} func = {}; \
|
||||
} \
|
||||
_GL_EXTERN_C int _gl_cxxalias_dummy
|
||||
#else
|
||||
|
|
|
@ -1,36 +0,0 @@
|
|||
/* A C macro for declaring that specific function parameters are not used.
|
||||
Copyright (C) 2008-2014 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/>. */
|
||||
|
||||
/* _GL_UNUSED_PARAMETER is a marker that can be appended to function parameter
|
||||
declarations for parameters that are not used. This helps to reduce
|
||||
warnings, such as from GCC -Wunused-parameter. The syntax is as follows:
|
||||
type param _GL_UNUSED_PARAMETER
|
||||
or more generally
|
||||
param_decl _GL_UNUSED_PARAMETER
|
||||
For example:
|
||||
int param _GL_UNUSED_PARAMETER
|
||||
int *(*param)(void) _GL_UNUSED_PARAMETER
|
||||
Other possible, but obscure and discouraged syntaxes:
|
||||
int _GL_UNUSED_PARAMETER *(*param)(void)
|
||||
_GL_UNUSED_PARAMETER int *(*param)(void)
|
||||
*/
|
||||
#ifndef _GL_UNUSED_PARAMETER
|
||||
# if __GNUC__ >= 3 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 7)
|
||||
# define _GL_UNUSED_PARAMETER __attribute__ ((__unused__))
|
||||
# else
|
||||
# define _GL_UNUSED_PARAMETER
|
||||
# endif
|
||||
#endif
|
|
@ -1,5 +1,5 @@
|
|||
/* A C macro for emitting warnings if a function is used.
|
||||
Copyright (C) 2010-2014 Free Software Foundation, Inc.
|
||||
Copyright (C) 2010-2017 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
|
||||
|
|
|
@ -1,16 +1,16 @@
|
|||
eval '(exit $?0)' && eval 'exec perl -wST "$0" ${1+"$@"}'
|
||||
eval '(exit $?0)' && eval 'exec perl -wST "$0" "$@"'
|
||||
& eval 'exec perl -wST "$0" $argv:q'
|
||||
if 0;
|
||||
# Detect instances of "if (p) free (p);".
|
||||
# Likewise "if (p != 0)", "if (0 != p)", or with NULL; and with braces.
|
||||
|
||||
my $VERSION = '2012-01-06 07:23'; # UTC
|
||||
my $VERSION = '2016-08-01 17:47'; # 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-2014 Free Software Foundation, Inc.
|
||||
# Copyright (C) 2008-2017 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
|
||||
|
@ -129,6 +129,9 @@ sub is_NULL ($)
|
|||
$err = EXIT_ERROR, next;
|
||||
while (defined (my $line = <FH>))
|
||||
{
|
||||
# Skip non-matching lines early to save time
|
||||
$line =~ /\bif\b/
|
||||
or next;
|
||||
while ($line =~
|
||||
/\b(if\s*\(\s*([^)]+?)(?:\s*!=\s*([^)]+?))?\s*\)
|
||||
# 1 2 3
|
||||
|
@ -202,6 +205,6 @@ EOF
|
|||
## 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-time-zone: "UTC0"
|
||||
## time-stamp-end: "'; # UTC"
|
||||
## End:
|
||||
|
|
|
@ -2,9 +2,9 @@
|
|||
# List version-controlled file names.
|
||||
|
||||
# Print a version string.
|
||||
scriptversion=2011-05-16.22; # UTC
|
||||
scriptversion=2016-01-11.22; # UTC
|
||||
|
||||
# Copyright (C) 2006-2014 Free Software Foundation, Inc.
|
||||
# Copyright (C) 2006-2017 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
|
||||
|
@ -108,6 +108,6 @@ done
|
|||
# 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-time-zone: "UTC0"
|
||||
# time-stamp-end: "; # UTC"
|
||||
# End:
|
||||
|
|
125
configure.ac
125
configure.ac
|
@ -5,7 +5,7 @@ dnl
|
|||
define(GUILE_CONFIGURE_COPYRIGHT,[[
|
||||
|
||||
Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
|
||||
2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015 Free Software Foundation, Inc.
|
||||
2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GUILE
|
||||
|
||||
|
@ -39,7 +39,7 @@ dnl Use `serial-tests' so the output `check-guile' is not hidden
|
|||
dnl (`parallel-tests' is the default in Automake 1.13.)
|
||||
dnl `serial-tests' was introduced in Automake 1.12.
|
||||
AM_INIT_AUTOMAKE([1.12 gnu no-define -Wall -Wno-override \
|
||||
serial-tests color-tests dist-xz])
|
||||
serial-tests color-tests dist-lzip dist-xz])
|
||||
m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])], [AC_SUBST([AM_DEFAULT_VERBOSITY],1)])
|
||||
|
||||
AC_COPYRIGHT(GUILE_CONFIGURE_COPYRIGHT)
|
||||
|
@ -66,6 +66,18 @@ AC_LIBTOOL_WIN32_DLL
|
|||
|
||||
AC_PROG_INSTALL
|
||||
AC_PROG_CC
|
||||
|
||||
# Sadly, there is no released version of Autoconf with a nice
|
||||
# C11-ensuring macro. This should work for gcc/clang within the last 5
|
||||
# years though.
|
||||
AC_MSG_CHECKING([how to enable C11 support])
|
||||
if test "$GCC" = yes; then
|
||||
AC_MSG_RESULT([-std=gnu11])
|
||||
CC="$CC -std=gnu11"
|
||||
else
|
||||
AC_MSG_RESULT([assuming $CC supports C11 by default])
|
||||
fi
|
||||
|
||||
gl_EARLY
|
||||
AC_PROG_CPP
|
||||
AC_PROG_SED
|
||||
|
@ -83,7 +95,8 @@ AC_DEFINE([GNULIB_LOCK], [1],
|
|||
[Define to allow Gnulib modules to use Guile's locks.])
|
||||
|
||||
|
||||
AC_PROG_CC_C89
|
||||
dnl Guile needs C99 or later.
|
||||
gl_PROG_CC_C99
|
||||
|
||||
# for per-target cflags in the libguile subdir
|
||||
AM_PROG_CC_C_O
|
||||
|
@ -313,6 +326,7 @@ AC_SUBST([SCM_I_GSC_T_PTRDIFF])
|
|||
|
||||
AC_CHECK_HEADERS([stdint.h])
|
||||
AC_CHECK_HEADERS([inttypes.h])
|
||||
AC_CHECK_HEADERS([stdatomic.h])
|
||||
|
||||
AC_CHECK_SIZEOF(intmax_t)
|
||||
|
||||
|
@ -617,6 +631,18 @@ AC_SUBST([SCM_I_GSC_T_UINTPTR])
|
|||
AC_SUBST([SCM_I_GSC_NEEDS_STDINT_H])
|
||||
AC_SUBST([SCM_I_GSC_NEEDS_INTTYPES_H])
|
||||
|
||||
AC_MSG_CHECKING([for which prebuilt binary set to use during bootstrap])
|
||||
SCM_PREBUILT_BINARIES=
|
||||
case "$ac_cv_c_bigendian-$ac_cv_sizeof_void_p" in
|
||||
yes-8) SCM_PREBUILT_BINARIES=64-bit-big-endian;;
|
||||
yes-4) SCM_PREBUILT_BINARIES=32-bit-big-endian;;
|
||||
no-8) SCM_PREBUILT_BINARIES=64-bit-little-endian;;
|
||||
no-4) SCM_PREBUILT_BINARIES=32-bit-little-endian;;
|
||||
*) AC_MSG_ERROR([Unexpected endianness+pointer size combination.])
|
||||
esac
|
||||
AC_MSG_RESULT($SCM_PREBUILT_BINARIES)
|
||||
AC_SUBST([SCM_PREBUILT_BINARIES])
|
||||
|
||||
AC_HEADER_STDC
|
||||
AC_HEADER_TIME
|
||||
AC_HEADER_SYS_WAIT
|
||||
|
@ -715,7 +741,7 @@ case $host in
|
|||
AC_CHECK_HEADER(winsock2.h, [AC_DEFINE([HAVE_WINSOCK2_H], 1,
|
||||
[Define if you have the <winsock2.h> header file.])])
|
||||
AC_CHECK_LIB(ws2_32, main)
|
||||
AC_LIBOBJ([win32-uname])
|
||||
AC_LIBOBJ([posix-w32])
|
||||
if test "$enable_shared" = yes ; then
|
||||
EXTRA_DEFS="-DSCM_IMPORT"
|
||||
AC_DEFINE([USE_DLL_IMPORT], 1,
|
||||
|
@ -752,21 +778,22 @@ AC_CHECK_HEADERS([assert.h crt_externs.h])
|
|||
# isblank - available as a GNU extension or in C99
|
||||
# _NSGetEnviron - Darwin specific
|
||||
# strcoll_l, newlocale, uselocale, utimensat - POSIX.1-2008
|
||||
# strtol_l - non-POSIX, found in glibc
|
||||
# fork - unavailable on Windows
|
||||
# sched_getaffinity, sched_setaffinity - GNU extensions (glibc)
|
||||
# sendfile - non-POSIX, found in glibc
|
||||
#
|
||||
AC_CHECK_FUNCS([DINFINITY DQNAN cexp chsize clog clog10 ctermid \
|
||||
fesetround ftime ftruncate fchown fchmod getcwd geteuid getsid \
|
||||
gettimeofday gmtime_r ioctl lstat mkdir mknod nice \
|
||||
readdir_r readdir64_r readlink rename rmdir setegid seteuid \
|
||||
setlocale setpgid setsid sigaction siginterrupt stat64 \
|
||||
gettimeofday getuid getgid gmtime_r ioctl lstat mkdir mknod nice \
|
||||
readlink rename rmdir setegid seteuid \
|
||||
setlocale setuid setgid setpgid setsid sigaction siginterrupt stat64 \
|
||||
strptime symlink sync sysconf tcgetpgrp tcsetpgrp uname waitpid \
|
||||
strdup system usleep atexit on_exit chown link fcntl ttyname getpwent \
|
||||
getgrent kill getppid getpgrp fork setitimer getitimer strchr strcmp \
|
||||
index bcopy memcpy rindex truncate unsetenv isblank _NSGetEnviron \
|
||||
strcoll strcoll_l newlocale uselocale utimensat sched_getaffinity \
|
||||
sched_setaffinity sendfile])
|
||||
index bcopy memcpy rindex truncate isblank _NSGetEnviron \
|
||||
strcoll strcoll_l strtod_l strtol_l newlocale uselocale utimensat \
|
||||
sched_getaffinity sched_setaffinity sendfile])
|
||||
|
||||
# Reasons for testing:
|
||||
# netdb.h - not in mingw
|
||||
|
@ -865,6 +892,57 @@ main (void)
|
|||
esac
|
||||
fi
|
||||
|
||||
# Cygwin and Hurd (circa 2017) and various prior versions defined stub
|
||||
# versions of the virtual and profiling itimers that would always fail
|
||||
# when called.
|
||||
if test "$ac_cv_func_getitimer" = yes; then
|
||||
|
||||
AC_CACHE_CHECK([whether getitimer(ITIMER_PROF) is usable],
|
||||
guile_cv_use_getitimer_prof,
|
||||
[AC_RUN_IFELSE([AC_LANG_SOURCE([[
|
||||
#include <sys/time.h>
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
struct itimerval I;
|
||||
if (getitimer (ITIMER_PROF, &I) == 0)
|
||||
return 0; /* good */
|
||||
else
|
||||
return 1; /* bad */
|
||||
}]])],
|
||||
[guile_cv_use_getitimer_prof=yes],
|
||||
[guile_cv_use_getitimer_prof=no],
|
||||
[guile_cv_use_getitimer_prof="yes, hopefully (cross-compiling)"])])
|
||||
case $guile_cv_use_getitimer_prof in
|
||||
yes*)
|
||||
AC_DEFINE([HAVE_USABLE_GETITIMER_PROF], 1, [Define to 1 if getitimer(ITIMER_PROF, ...) is functional])
|
||||
;;
|
||||
esac
|
||||
|
||||
AC_CACHE_CHECK([whether getitimer(ITIMER_VIRTUAL) is usable],
|
||||
guile_cv_use_getitimer_virtual,
|
||||
[AC_RUN_IFELSE([AC_LANG_SOURCE([[
|
||||
#include <sys/time.h>
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
struct itimerval I;
|
||||
if (getitimer (ITIMER_VIRTUAL, &I) == 0)
|
||||
return 0; /* good */
|
||||
else
|
||||
return 1; /* bad */
|
||||
}]])],
|
||||
[guile_cv_use_getitimer_virtual=yes],
|
||||
[guile_cv_use_getitimer_virtual=no],
|
||||
[guile_cv_use_getitimer_virtual="yes, hopefully (cross-compiling)"])])
|
||||
case $guile_cv_use_getitimer_virtual in
|
||||
yes*)
|
||||
AC_DEFINE([HAVE_USABLE_GETITIMER_VIRTUAL], 1, [Define to 1 if getitimer(ITIMER_VIRTUAL, ...) is functional])
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
|
||||
AC_CACHE_SAVE
|
||||
|
||||
dnl GMP tests
|
||||
|
@ -890,6 +968,13 @@ if test "x$LTLIBUNISTRING" = "x"; then
|
|||
AC_MSG_ERROR([GNU libunistring is required, please install it.])
|
||||
fi
|
||||
|
||||
dnl Sloppy check to make sure people aren't trying to use too-old libunistring.
|
||||
case "$LIBUNISTRING_VERSION" in
|
||||
0.9.0 | 0.9.1 | 0.9.2 )
|
||||
AC_MSG_ERROR([libunistring too old. Please install a recent libunistring (>= 0.9.3).])
|
||||
;;
|
||||
esac
|
||||
|
||||
GUILE_LIBUNISTRING_WITH_ICONV_SUPPORT
|
||||
if test "x$ac_cv_libunistring_with_iconv_support" != "xyes"; then
|
||||
AC_MSG_ERROR([No iconv support. Please recompile libunistring with iconv enabled.])
|
||||
|
@ -1124,14 +1209,15 @@ if test "$enable_regex" = yes; then
|
|||
AC_DEFINE([ENABLE_REGEX], 1, [Define when regex support is enabled.])
|
||||
fi
|
||||
|
||||
AC_REPLACE_FUNCS([strerror memmove mkstemp])
|
||||
AC_REPLACE_FUNCS([strerror memmove])
|
||||
|
||||
# Reasons for testing:
|
||||
# asinh, acosh, atanh, trunc - C99 standard, generally not available on
|
||||
# older systems
|
||||
# sincos - GLIBC extension
|
||||
# __sincos - APPLE extension
|
||||
#
|
||||
AC_CHECK_FUNCS(asinh acosh atanh copysign finite sincos trunc)
|
||||
AC_CHECK_FUNCS(asinh acosh atanh copysign finite sincos __sincos trunc)
|
||||
|
||||
# C99 specifies isinf and isnan as macros.
|
||||
# HP-UX provides only macros, no functions.
|
||||
|
@ -1246,7 +1332,11 @@ main (int argc, char **argv)
|
|||
# Boehm's GC library
|
||||
#
|
||||
#--------------------------------------------------------------------
|
||||
PKG_CHECK_MODULES([BDW_GC], [bdw-gc >= 7.2])
|
||||
AC_MSG_CHECKING(for which bdw-gc pkg-config file to use)
|
||||
AC_ARG_WITH(bdw_gc, [ --with-bdw-gc=PKG name of BDW-GC pkg-config file],
|
||||
[bdw_gc="$withval"], [bdw_gc=bdw-gc])
|
||||
AC_MSG_RESULT($bdw_gc)
|
||||
PKG_CHECK_MODULES([BDW_GC], [$bdw_gc >= 7.2])
|
||||
|
||||
save_LIBS="$LIBS"
|
||||
LIBS="$BDW_GC_LIBS $LIBS"
|
||||
|
@ -1256,7 +1346,7 @@ CFLAGS="$BDW_GC_CFLAGS $CFLAGS"
|
|||
AC_CHECK_FUNCS([GC_pthread_exit GC_pthread_cancel GC_pthread_sigmask])
|
||||
|
||||
# Functions from GC 7.3.
|
||||
AC_CHECK_FUNCS([GC_move_disappearing_link])
|
||||
AC_CHECK_FUNCS([GC_move_disappearing_link GC_is_heap_ptr])
|
||||
|
||||
LIBS="$save_LIBS"
|
||||
|
||||
|
@ -1643,12 +1733,19 @@ AC_CONFIG_FILES([
|
|||
test-suite/standalone/Makefile
|
||||
test-suite/vm/Makefile
|
||||
meta/Makefile
|
||||
bootstrap/Makefile
|
||||
module/Makefile
|
||||
prebuilt/Makefile
|
||||
prebuilt/x86_64-unknown-linux-gnu/Makefile
|
||||
prebuilt/i686-pc-linux-gnu/Makefile
|
||||
prebuilt/mips-unknown-linux-gnu/Makefile
|
||||
])
|
||||
|
||||
|
||||
GUILE_CONFIG_SCRIPT([check-guile])
|
||||
GUILE_CONFIG_SCRIPT([benchmark-guile])
|
||||
GUILE_CONFIG_SCRIPT([meta/guile])
|
||||
GUILE_CONFIG_SCRIPT([meta/build-env])
|
||||
GUILE_CONFIG_SCRIPT([meta/uninstalled-env])
|
||||
GUILE_CONFIG_SCRIPT([meta/gdb-uninstalled-guile])
|
||||
GUILE_CONFIG_SCRIPT([libguile/guile-snarf])
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
<!--#include virtual="/server/header.html" -->
|
||||
<title>%%TITLE%% - GNU Project - Free Software Foundation (FSF)</title>
|
||||
<!-- Parent-Version: 1.77 -->
|
||||
<title>%%TITLE%% - GNU Project - Free Software Foundation</title>
|
||||
<!--#include virtual="/server/banner.html" -->
|
||||
<h2>%%TITLE%%</h2>
|
||||
|
||||
|
@ -67,19 +68,22 @@ script</a>.)</p>
|
|||
</div><!-- for id="content", starts in the include above -->
|
||||
<!--#include virtual="/server/footer.html" -->
|
||||
<div id="footer">
|
||||
<div class="unprintable">
|
||||
|
||||
<p>Please send general 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>
|
||||
the FSF. Broken links and other corrections or suggestions can be sent
|
||||
to <a href="mailto:%%EMAIL%%"><%%EMAIL%%></a>.</p>
|
||||
</div>
|
||||
|
||||
<p>Copyright © 2014 Free Software Foundation, Inc.</p>
|
||||
<p>Copyright © 2017 Free Software Foundation, Inc.</p>
|
||||
|
||||
<p>Verbatim copying and distribution of this entire article are
|
||||
permitted worldwide, without royalty, in any medium, provided this
|
||||
notice, and the copyright notice, are preserved.</p>
|
||||
<p>This page is licensed under a <a rel="license"
|
||||
href="http://creativecommons.org/licenses/by-nd/3.0/us/">Creative
|
||||
Commons Attribution-NoDerivs 3.0 United States License</a>.</p>
|
||||
|
||||
<!--#include virtual="/server/bottom-notes.html" -->
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
|
93
doc/gendocs_template_min
Normal file
93
doc/gendocs_template_min
Normal file
|
@ -0,0 +1,93 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
|
||||
|
||||
<head>
|
||||
<title>%%TITLE%% - GNU Project - Free Software Foundation</title>
|
||||
<meta http-equiv="content-type" content='text/html; charset=utf-8' />
|
||||
<link rel="stylesheet" type="text/css" href="/gnu.css" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<h3>%%TITLE%%</h3>
|
||||
|
||||
<address>Free Software Foundation</address>
|
||||
<address>last updated %%DATE%%</address>
|
||||
<p>
|
||||
<a href="/graphics/gnu-head.jpg">
|
||||
<img src="/graphics/gnu-head-sm.jpg"
|
||||
alt=" [image of the head of a GNU] " width="129" height="122"/>
|
||||
</a>
|
||||
</p>
|
||||
<hr />
|
||||
|
||||
<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%%.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>(This page generated by the <a href="%%SCRIPTURL%%">%%SCRIPTNAME%%
|
||||
script</a>.)</p>
|
||||
|
||||
<div id="footer" class="copyright">
|
||||
|
||||
<p>Please send general 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. Broken links and other corrections or suggestions can be sent
|
||||
to <a href="mailto:%%EMAIL%%"><%%EMAIL%%></a>.</p>
|
||||
</div>
|
||||
|
||||
<p>Copyright © 2017 Free Software Foundation, Inc.</p>
|
||||
|
||||
<p>This page is licensed under a <a rel="license"
|
||||
href="http://creativecommons.org/licenses/by-nd/3.0/us/">Creative
|
||||
Commons Attribution-NoDerivs 3.0 United States License</a>.</p>
|
||||
|
||||
<!--#include virtual="/server/bottom-notes.html" -->
|
||||
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
|
@ -125,7 +125,7 @@ is being run interactively.
|
|||
Compile source files automatically (default behavior).
|
||||
.
|
||||
.TP
|
||||
.B --no-autocompile
|
||||
.B --no-auto-compile
|
||||
Disable automatic source file compilation.
|
||||
.
|
||||
.TP
|
||||
|
|
|
@ -1,75 +0,0 @@
|
|||
2004-08-25 Marius Vollmer <mvo@zagadka.de>
|
||||
|
||||
* docstring.el (docstring-process-alist): Consider entries in
|
||||
reverse order. That puts them in new-docstrings.texi in the same
|
||||
order as in the C source.
|
||||
|
||||
2004-08-23 Marius Vollmer <marius.vollmer@uni-dortmund.de>
|
||||
|
||||
* docstring.el: Replaced all "@c module" markers with "@c
|
||||
module-for-docstring", making it less likely to collide with a
|
||||
real commentary.
|
||||
|
||||
2002-10-19 Neil Jerram <neil@ossau.uklinux.net>
|
||||
|
||||
* guile.texi: Replaced by regenerated libguile version.
|
||||
|
||||
2002-07-10 Gary Houston <ghouston@arglist.com>
|
||||
|
||||
* docstring.el: optional 2nd environment variable to locate
|
||||
built files.
|
||||
|
||||
2002-07-09 Gary Houston <ghouston@arglist.com>
|
||||
|
||||
* docstring.el: defined caddr, used in several places but missing
|
||||
for some reason.
|
||||
|
||||
2002-04-02 Thien-Thi Nguyen <ttn@giblet.glug.org>
|
||||
|
||||
* doctring.el: List commands in commentary; nfc.
|
||||
|
||||
2002-03-15 Neil Jerram <neil@ossau.uklinux.net>
|
||||
|
||||
* guile.texi: Replaced by regenerated libguile version.
|
||||
|
||||
2002-03-12 Neil Jerram <neil@ossau.uklinux.net>
|
||||
|
||||
* guile.texi: Replaced by regenerated libguile version.
|
||||
|
||||
2002-03-08 Neil Jerram <neil@ossau.uklinux.net>
|
||||
|
||||
* docstring.el (docstring-libguile-directory,
|
||||
docstring-display-location, docstring-show-source): New.
|
||||
|
||||
2001-11-16 Neil Jerram <neil@ossau.uklinux.net>
|
||||
|
||||
* guile.texi: Replaced by regenerated libguile version.
|
||||
|
||||
* docstring.el (make-module-description-list): Exclude @deffn's
|
||||
with category {C Function}.
|
||||
(docstring-process-alist): Bind key "d" to
|
||||
docstring-ediff-this-line in the docstring output buffer.
|
||||
|
||||
2001-11-13 Neil Jerram <neil@ossau.uklinux.net>
|
||||
|
||||
* guile.texi: Replaced by libguile version (after automatically
|
||||
updating docstrings in the reference manual).
|
||||
|
||||
2001-11-07 Neil Jerram <neil@ossau.uklinux.net>
|
||||
|
||||
* guile.texi: Replaced by libguile version (after automatically
|
||||
updating docstrings in the reference manual).
|
||||
|
||||
* docstring.el (docstring-manual-directory): Added "/ref" to end.
|
||||
(docstring-manual-files): Now calculated automatically, since by
|
||||
definition all the .texi files in doc/ref are reference manual
|
||||
files.
|
||||
|
||||
2001-04-03 Martin Grabmueller <mgrabmue@cs.tu-berlin.de>
|
||||
|
||||
* guile.texi: Automated docstring merging.
|
||||
|
||||
2001-03-23 Neil Jerram <neil@ossau.uklinux.net>
|
||||
|
||||
* ChangeLog, README, docstring.el, guile.texi: New files.
|
||||
|
|
@ -1,35 +0,0 @@
|
|||
README for guile-core/doc/maint -*- text -*-
|
||||
|
||||
The files in this directory are used by the maintainers to automate
|
||||
the process of updating the Guile reference manual when the docstrings
|
||||
in the libguile C source change.
|
||||
|
||||
- ChangeLog is the change log for files in this directory.
|
||||
|
||||
- README is this file.
|
||||
|
||||
- docstring.el is a helpful Emacs Lisp library (see source for
|
||||
customization). The two key entry points are:
|
||||
`docstring-process-module' and
|
||||
`docstring-ediff-this-line'.
|
||||
|
||||
- guile.texi is a snapshot of the built file libguile/guile.texi,
|
||||
copied last time the reference manual was determined to be in sync
|
||||
with the libguile source.
|
||||
|
||||
docstring.el requires the setting of an environment variable, e.g.,
|
||||
|
||||
export GUILE_MAINTAINER_GUILE_CORE_DIR=$HOME/guile/guile-core
|
||||
|
||||
If the build directory differs from the source directory, an additional
|
||||
variable is required:
|
||||
|
||||
export GUILE_MAINTAINER_BUILD_CORE_DIR=$HOME/guile/guile-core-build
|
||||
|
||||
If you've just fixed a docstring in, say, ../libguile/strop.c, do in emacs:
|
||||
|
||||
M-x load-file RET .../doc/maint/docstring.el RET
|
||||
M-x docstring-process-module RET (guile) RET
|
||||
|
||||
Save all modified .texi files and copy the current ../libguile/guile.texi
|
||||
to ./guile.texi, then commit. See elisp var `docstring-snarfed-roots'.
|
|
@ -1,622 +0,0 @@
|
|||
;;; docstring.el --- utilities for Guile docstring maintenance
|
||||
;;;
|
||||
;;; Copyright (C) 2001, 2004 Neil Jerram
|
||||
;;;
|
||||
;;; This file is not part of GUILE, but the same permissions apply.
|
||||
;;;
|
||||
;;; 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.
|
||||
|
||||
;;; Commentary:
|
||||
|
||||
;; The basic premise of these utilities is that - at least in the
|
||||
;; short term - we can get a lot of reference manual mileage by
|
||||
;; co-opting the docstrings that are snarfed automatically from
|
||||
;; Guile's C and Scheme source code. But this leads to problems of
|
||||
;; synchronization... How do you track when a docstring has been
|
||||
;; updated in the source and so needs updating in the reference
|
||||
;; manual. What if a procedure is removed from the Guile source? And
|
||||
;; so on. To complicate matters, the exact snarfed docstring text
|
||||
;; will probably need to be modified so that it fits into the flow of
|
||||
;; the manual section in which it appears. Can we design solutions to
|
||||
;; synchronization problems that continue to work even when the manual
|
||||
;; text has been enhanced in this way?
|
||||
;;
|
||||
;; This file implements an approach to this problem that I have found
|
||||
;; useful. It involves keeping track of three copies of each
|
||||
;; docstring:
|
||||
;;
|
||||
;; "MANUAL" = the docstring as it appears in the reference manual.
|
||||
;;
|
||||
;; "SNARFED" = the docstring as snarfed from the current C or Scheme
|
||||
;; source.
|
||||
;;
|
||||
;; "TRACKING" = the docstring as it appears in a tracking file whose
|
||||
;; purpose is to record the most recent snarfed docstrings
|
||||
;; that are known to be in sync with the reference manual.
|
||||
;;
|
||||
;; The approaches are as follows.
|
||||
;;
|
||||
;; 1. Comparison of MANUAL-DOC, SOURCE-DOC and TRACK-DOC, to produce a
|
||||
;; summary output buffer in which keystrokes are defined to bring up
|
||||
;; detailed comparisons.
|
||||
;;
|
||||
;; 2. Comparison of MANUAL-DOC, SOURCE-DOC and TRACK-DOC using Ediff.
|
||||
;;
|
||||
;; Here is a brief list of commands available (via "M-x COMMAND"):
|
||||
;;
|
||||
;; docstring-process-current-buffer
|
||||
;; docstring-process-current-region BEG END
|
||||
;; docstring-process-module MODULE
|
||||
;; docstring-ediff-this-line
|
||||
;; docstring-show-source
|
||||
|
||||
|
||||
(defvar guile-core-dir (or (getenv "GUILE_MAINTAINER_GUILE_CORE_DIR")
|
||||
(error "GUILE_MAINTAINER_GUILE_CORE_DIR not set"))
|
||||
"*Full path of guile-core source directory.")
|
||||
|
||||
(defvar guile-build-dir (or (getenv "GUILE_MAINTAINER_BUILD_CORE_DIR")
|
||||
guile-core-dir)
|
||||
"*Full path of guile-core build directory. Defaults to guile-core-dir.")
|
||||
|
||||
(defvar docstring-manual-directory (expand-file-name "doc/ref" guile-core-dir)
|
||||
"*The directory containing the Texinfo source for the Guile reference manual.")
|
||||
|
||||
(defvar docstring-tracking-root (expand-file-name "doc/maint" guile-core-dir)
|
||||
"*Root directory for docstring tracking files. The tracking file
|
||||
for module (a b c) is expected to be in the file
|
||||
<docstring-tracking-root>/a/b/c.texi.")
|
||||
|
||||
(defvar docstring-snarfed-roots (mapcar
|
||||
#'(lambda (frag)
|
||||
(expand-file-name frag guile-build-dir))
|
||||
'("libguile" "ice-9" "oop"))
|
||||
"*List of possible root directories for snarfed docstring files.
|
||||
For each entry in this list, the snarfed docstring file for module (a
|
||||
b c) is looked for in the file <entry>/a/b/c.texi.")
|
||||
|
||||
(defvar docstring-manual-files
|
||||
(directory-files docstring-manual-directory nil "\\.texi$" t)
|
||||
"List of Texinfo source files that comprise the Guile reference manual.")
|
||||
|
||||
(defvar docstring-new-docstrings-file "new-docstrings.texi"
|
||||
"The name of a file in the Guile reference manual source directory
|
||||
to which new docstrings should be added.")
|
||||
|
||||
;; Apply FN in turn to each element in the list CANDIDATES until the
|
||||
;; first application that returns non-nil.
|
||||
(defun or-map (fn candidates args)
|
||||
(let ((result nil))
|
||||
(while candidates
|
||||
(setq result (apply fn (car candidates) args))
|
||||
(if result
|
||||
(setq result (cons (car candidates) result)
|
||||
candidates nil)
|
||||
(setq candidates (cdr candidates))))
|
||||
result))
|
||||
|
||||
;; Return t if the current buffer position is in the scope of the
|
||||
;; specified MODULE, as determined by "@c module-for-docstring ..." comments in the
|
||||
;; buffer. DEFAULT-OK specifies the return value in the case that
|
||||
;; there are no preceding module comments at all.
|
||||
(defun docstring-in-module (module default-ok)
|
||||
(save-excursion
|
||||
(if (re-search-backward "^@c module-for-docstring " nil t)
|
||||
(progn
|
||||
(search-forward "@c module-for-docstring ")
|
||||
(equal module (read (current-buffer))))
|
||||
default-ok)))
|
||||
|
||||
;; Find a docstring in the specified FILE-NAME for the item in module
|
||||
;; MODULE and with description DESCRIPTION. MODULE should be a list
|
||||
;; of symbols, Guile-style, for example: '(ice-9 session).
|
||||
;; DESCRIPTION should be the string that is expected after the @deffn,
|
||||
;; for example "primitive acons" or "syntax let*".
|
||||
(defun find-docstring (file-name module description)
|
||||
(and (file-exists-p file-name)
|
||||
(let ((buf (find-file-noselect file-name))
|
||||
(deffn-regexp (concat "^@deffnx? "
|
||||
(regexp-quote description)
|
||||
"[ \n\t]"))
|
||||
found
|
||||
result)
|
||||
(save-excursion
|
||||
(set-buffer buf)
|
||||
(goto-char (point-min))
|
||||
(while (and (not found)
|
||||
(re-search-forward deffn-regexp nil t))
|
||||
(save-excursion
|
||||
(goto-char (match-beginning 0))
|
||||
(beginning-of-line)
|
||||
(if (docstring-in-module module t)
|
||||
(setq found t))))
|
||||
(if found
|
||||
(setq result
|
||||
(list (current-buffer)
|
||||
(progn
|
||||
(re-search-backward "^@deffn ")
|
||||
(beginning-of-line)
|
||||
(point))
|
||||
(progn
|
||||
(re-search-forward "^@end deffn")
|
||||
(forward-line 1)
|
||||
(point))))))
|
||||
result)))
|
||||
|
||||
;; Find the reference manual version of the specified docstring.
|
||||
;; MODULE and DESCRIPTION specify the docstring as per
|
||||
;; `find-docstring'. The set of files that `find-manual-docstring'
|
||||
;; searches is determined by the value of the `docstring-manual-files'
|
||||
;; variable.
|
||||
(defun find-manual-docstring (module description)
|
||||
(let* ((result
|
||||
(or-map 'find-docstring
|
||||
(mapcar (function (lambda (file-name)
|
||||
(concat docstring-manual-directory
|
||||
"/"
|
||||
file-name)))
|
||||
(cons docstring-new-docstrings-file
|
||||
docstring-manual-files))
|
||||
(list module
|
||||
description)))
|
||||
(matched-file-name (and (cdr result)
|
||||
(file-name-nondirectory (car result)))))
|
||||
(if matched-file-name
|
||||
(setq docstring-manual-files
|
||||
(cons matched-file-name
|
||||
(delete matched-file-name docstring-manual-files))))
|
||||
(cdr result)))
|
||||
|
||||
;; Convert MODULE to a directory subpath.
|
||||
(defun module-to-path (module)
|
||||
(mapconcat (function (lambda (component)
|
||||
(symbol-name component)))
|
||||
module
|
||||
"/"))
|
||||
|
||||
;; Find the current snarfed version of the specified docstring.
|
||||
;; MODULE and DESCRIPTION specify the docstring as per
|
||||
;; `find-docstring'. The file that `find-snarfed-docstring' looks in
|
||||
;; is automatically generated from MODULE.
|
||||
(defun find-snarfed-docstring (module description)
|
||||
(let ((modpath (module-to-path module)))
|
||||
(cdr (or-map (function (lambda (root)
|
||||
(find-docstring (concat root
|
||||
"/"
|
||||
modpath
|
||||
".texi")
|
||||
module
|
||||
description)))
|
||||
docstring-snarfed-roots
|
||||
nil))))
|
||||
|
||||
;; Find the tracking version of the specified docstring. MODULE and
|
||||
;; DESCRIPTION specify the docstring as per `find-docstring'. The
|
||||
;; file that `find-tracking-docstring' looks in is automatically
|
||||
;; generated from MODULE.
|
||||
(defun find-tracking-docstring (module description)
|
||||
(find-docstring (concat docstring-tracking-root
|
||||
"/"
|
||||
(module-to-path module)
|
||||
".texi")
|
||||
module
|
||||
description))
|
||||
|
||||
;; Extract an alist of modules and descriptions from the current
|
||||
;; buffer.
|
||||
(defun make-module-description-list ()
|
||||
(let ((alist nil)
|
||||
(module '(guile)))
|
||||
(save-excursion
|
||||
(goto-char (point-min))
|
||||
(while (re-search-forward "^\\(@c module-for-docstring \\|@deffnx? \\({[^}]+}\\|[^ ]+\\) \\([^ \n]+\\)\\)"
|
||||
nil
|
||||
t)
|
||||
(let ((matched (buffer-substring (match-beginning 1)
|
||||
(match-end 1))))
|
||||
(if (string-equal matched "@c module-for-docstring ")
|
||||
(setq module (read (current-buffer)))
|
||||
(let ((type (buffer-substring (match-beginning 2)
|
||||
(match-end 2))))
|
||||
(if (string-equal type "{C Function}")
|
||||
nil
|
||||
(setq matched
|
||||
(concat type
|
||||
" "
|
||||
(buffer-substring (match-beginning 3)
|
||||
(match-end 3))))
|
||||
(message "Found docstring: %S: %s" module matched)
|
||||
(let ((descriptions (assoc module alist)))
|
||||
(setq alist
|
||||
(cons (cons module (cons matched (cdr-safe descriptions)))
|
||||
(if descriptions
|
||||
(delete descriptions alist)
|
||||
alist))))))))))
|
||||
alist))
|
||||
|
||||
;; missing in some environments?
|
||||
(defun caddr (list)
|
||||
(nth 2 list))
|
||||
|
||||
;; Return the docstring from the specified LOCATION. LOCATION is a
|
||||
;; list of three elements: buffer, start position and end position.
|
||||
(defun location-to-docstring (location)
|
||||
(and location
|
||||
(save-excursion
|
||||
(set-buffer (car location))
|
||||
(buffer-substring (cadr location) (caddr location)))))
|
||||
|
||||
;; Perform a comparison of the specified docstring. MODULE and
|
||||
;; DESCRIPTION are as per usual.
|
||||
(defun docstring-compare (module description)
|
||||
(let* ((manual-location (find-manual-docstring module description))
|
||||
(snarf-location (find-snarfed-docstring module description))
|
||||
(track-location (find-tracking-docstring module description))
|
||||
|
||||
(manual-docstring (location-to-docstring manual-location))
|
||||
(snarf-docstring (location-to-docstring snarf-location))
|
||||
(track-docstring (location-to-docstring track-location))
|
||||
|
||||
action
|
||||
issue)
|
||||
|
||||
;; Decide what to do.
|
||||
(cond ((null snarf-location)
|
||||
(setq action nil
|
||||
issue (if manual-location
|
||||
'consider-removal
|
||||
nil)))
|
||||
|
||||
((null manual-location)
|
||||
(setq action 'add-to-manual issue nil))
|
||||
|
||||
((null track-location)
|
||||
(setq action nil
|
||||
issue (if (string-equal manual-docstring snarf-docstring)
|
||||
nil
|
||||
'check-needed)))
|
||||
|
||||
((string-equal track-docstring snarf-docstring)
|
||||
(setq action nil issue nil))
|
||||
|
||||
((string-equal track-docstring manual-docstring)
|
||||
(setq action 'auto-update-manual issue nil))
|
||||
|
||||
(t
|
||||
(setq action nil issue 'update-needed)))
|
||||
|
||||
;; Return a pair indicating any automatic action that can be
|
||||
;; taken, and any issue for resolution.
|
||||
(cons action issue)))
|
||||
|
||||
;; Add the specified docstring to the manual.
|
||||
(defun docstring-add-to-manual (module description)
|
||||
(let ((buf (find-file-noselect (concat docstring-manual-directory
|
||||
"/"
|
||||
docstring-new-docstrings-file))))
|
||||
(save-excursion
|
||||
(set-buffer buf)
|
||||
(goto-char (point-max))
|
||||
(or (docstring-in-module module nil)
|
||||
(insert "\n@c module-for-docstring " (prin1-to-string module) "\n"))
|
||||
(insert "\n" (location-to-docstring (find-snarfed-docstring module
|
||||
description))))))
|
||||
|
||||
;; Auto-update the specified docstring in the manual.
|
||||
(defun docstring-auto-update-manual (module description)
|
||||
(let ((manual-location (find-manual-docstring module description))
|
||||
(track-location (find-tracking-docstring module description)))
|
||||
(save-excursion
|
||||
(set-buffer (car manual-location))
|
||||
(goto-char (cadr manual-location))
|
||||
(delete-region (cadr manual-location) (caddr manual-location))
|
||||
(insert (location-to-docstring (find-snarfed-docstring module
|
||||
description))))))
|
||||
|
||||
;; Process an alist of modules and descriptions, and produce a summary
|
||||
;; buffer describing actions taken and issues to be resolved.
|
||||
(defun docstring-process-alist (alist)
|
||||
(let (check-needed-list
|
||||
update-needed-list
|
||||
consider-removal-list
|
||||
added-to-manual-list
|
||||
auto-updated-manual-list)
|
||||
|
||||
(mapcar
|
||||
(function (lambda (module-list)
|
||||
(let ((module (car module-list)))
|
||||
(message "Module: %S" module)
|
||||
(mapcar
|
||||
(function (lambda (description)
|
||||
(message "Comparing docstring: %S: %s" module description)
|
||||
(let* ((ai (docstring-compare module description))
|
||||
(action (car ai))
|
||||
(issue (cdr ai)))
|
||||
|
||||
(cond ((eq action 'add-to-manual)
|
||||
(docstring-add-to-manual module description)
|
||||
(setq added-to-manual-list
|
||||
(cons (cons module description)
|
||||
added-to-manual-list)))
|
||||
|
||||
((eq action 'auto-update-manual)
|
||||
(docstring-auto-update-manual module description)
|
||||
(setq auto-updated-manual-list
|
||||
(cons (cons module description)
|
||||
auto-updated-manual-list))))
|
||||
|
||||
(cond ((eq issue 'check-needed)
|
||||
(setq check-needed-list
|
||||
(cons (cons module description)
|
||||
check-needed-list)))
|
||||
|
||||
((eq issue 'update-needed)
|
||||
(setq update-needed-list
|
||||
(cons (cons module description)
|
||||
update-needed-list)))
|
||||
|
||||
((eq issue 'consider-removal)
|
||||
(setq consider-removal-list
|
||||
(cons (cons module description)
|
||||
consider-removal-list)))))))
|
||||
(reverse (cdr module-list))))))
|
||||
alist)
|
||||
|
||||
;; Prepare a buffer describing the results.
|
||||
(set-buffer (get-buffer-create "*Docstring Results*"))
|
||||
(erase-buffer)
|
||||
|
||||
(insert "
|
||||
The following items have been automatically added to the manual in
|
||||
file `" docstring-manual-directory "/" docstring-new-docstrings-file "'.\n\n")
|
||||
(if added-to-manual-list
|
||||
(mapcar (function (lambda (moddesc)
|
||||
(insert (prin1-to-string (car moddesc))
|
||||
": "
|
||||
(cdr moddesc)
|
||||
"\n")))
|
||||
added-to-manual-list)
|
||||
(insert "(none)\n"))
|
||||
|
||||
(insert "
|
||||
The following items have been automatically updated in the manual.\n\n")
|
||||
(if auto-updated-manual-list
|
||||
(mapcar (function (lambda (moddesc)
|
||||
(insert (prin1-to-string (car moddesc))
|
||||
": "
|
||||
(cdr moddesc)
|
||||
"\n")))
|
||||
auto-updated-manual-list)
|
||||
(insert "(none)\n"))
|
||||
|
||||
(insert "
|
||||
The following items are already documented in the manual but are not
|
||||
mentioned in the reference copy of the snarfed docstrings file.
|
||||
You should check that the manual documentation matches the docstring
|
||||
in the current snarfed docstrings file.\n\n")
|
||||
(if check-needed-list
|
||||
(mapcar (function (lambda (moddesc)
|
||||
(insert (prin1-to-string (car moddesc))
|
||||
": "
|
||||
(cdr moddesc)
|
||||
"\n")))
|
||||
check-needed-list)
|
||||
(insert "(none)\n"))
|
||||
|
||||
(insert "
|
||||
The following items have manual documentation that is different from
|
||||
the docstring in the reference copy of the snarfed docstrings file,
|
||||
and the snarfed docstring has changed. You need to update the manual
|
||||
documentation by hand with reference to the snarfed docstring changes.\n\n")
|
||||
(if update-needed-list
|
||||
(mapcar (function (lambda (moddesc)
|
||||
(insert (prin1-to-string (car moddesc))
|
||||
": "
|
||||
(cdr moddesc)
|
||||
"\n")))
|
||||
update-needed-list)
|
||||
(insert "(none)\n"))
|
||||
|
||||
(insert "
|
||||
The following items are documented in the manual but are no longer
|
||||
present in the snarfed docstrings file. You should consider whether
|
||||
the existing manual documentation is still pertinent. If it is, its
|
||||
docstring module comment may need updating, to connect it with a
|
||||
new snarfed docstring file.\n\n")
|
||||
(if consider-removal-list
|
||||
(mapcar (function (lambda (moddesc)
|
||||
(insert (prin1-to-string (car moddesc))
|
||||
": "
|
||||
(cdr moddesc)
|
||||
"\n")))
|
||||
consider-removal-list)
|
||||
(insert "(none)\n"))
|
||||
(insert "\n")
|
||||
|
||||
(goto-char (point-min))
|
||||
(local-set-key "d" 'docstring-ediff-this-line)
|
||||
|
||||
;; Popup the issues buffer.
|
||||
(let ((pop-up-frames t))
|
||||
(set-window-point (display-buffer (current-buffer))
|
||||
(point-min)))))
|
||||
|
||||
(defun docstring-process-current-buffer ()
|
||||
(interactive)
|
||||
(docstring-process-alist (make-module-description-list)))
|
||||
|
||||
(defun docstring-process-current-region (beg end)
|
||||
(interactive "r")
|
||||
(narrow-to-region beg end)
|
||||
(unwind-protect
|
||||
(save-excursion
|
||||
(docstring-process-alist (make-module-description-list)))
|
||||
(widen)))
|
||||
|
||||
(defun docstring-process-module (module)
|
||||
(interactive "xModule: ")
|
||||
(let ((modpath (module-to-path module))
|
||||
(mdlist nil))
|
||||
(mapcar (function (lambda (root)
|
||||
(let ((fn (concat root
|
||||
"/"
|
||||
modpath
|
||||
".texi")))
|
||||
(if (file-exists-p fn)
|
||||
(save-excursion
|
||||
(find-file fn)
|
||||
(message "Getting docstring list from %s" fn)
|
||||
(setq mdlist
|
||||
(append mdlist
|
||||
(make-module-description-list))))))))
|
||||
docstring-snarfed-roots)
|
||||
(docstring-process-alist mdlist)))
|
||||
|
||||
(defun docstring-ediff-this-line ()
|
||||
(interactive)
|
||||
(let (module
|
||||
description)
|
||||
(save-excursion
|
||||
(beginning-of-line)
|
||||
(setq module (read (current-buffer)))
|
||||
(forward-char 2)
|
||||
(setq description (buffer-substring (point)
|
||||
(progn
|
||||
(end-of-line)
|
||||
(point)))))
|
||||
|
||||
(message "Ediff docstring: %S: %s" module description)
|
||||
|
||||
(let ((track-location (or (find-tracking-docstring module description)
|
||||
(docstring-temp-location "No docstring in tracking file")))
|
||||
(snarf-location (or (find-snarfed-docstring module description)
|
||||
(docstring-temp-location "No docstring in snarfed file")))
|
||||
(manual-location (or (find-manual-docstring module description)
|
||||
(docstring-temp-location "No docstring in manual"))))
|
||||
|
||||
(setq docstring-ediff-buffers
|
||||
(list (car track-location)
|
||||
(car snarf-location)
|
||||
(car manual-location)))
|
||||
|
||||
(docstring-narrow-to-location track-location)
|
||||
(docstring-narrow-to-location snarf-location)
|
||||
(docstring-narrow-to-location manual-location)
|
||||
|
||||
(add-hook 'ediff-quit-hook 'docstring-widen-ediff-buffers)
|
||||
|
||||
(ediff-buffers3 (nth 0 docstring-ediff-buffers)
|
||||
(nth 1 docstring-ediff-buffers)
|
||||
(nth 2 docstring-ediff-buffers)))))
|
||||
|
||||
(defun docstring-narrow-to-location (location)
|
||||
(save-excursion
|
||||
(set-buffer (car location))
|
||||
(narrow-to-region (cadr location) (caddr location))))
|
||||
|
||||
(defun docstring-temp-location (str)
|
||||
(let ((buf (generate-new-buffer "*Docstring Temp*")))
|
||||
(save-excursion
|
||||
(set-buffer buf)
|
||||
(erase-buffer)
|
||||
(insert str "\n")
|
||||
(list buf (point-min) (point-max)))))
|
||||
|
||||
(require 'ediff)
|
||||
|
||||
(defvar docstring-ediff-buffers '())
|
||||
|
||||
(defun docstring-widen-ediff-buffers ()
|
||||
(remove-hook 'ediff-quit-hook 'docstring-widen-ediff-buffers)
|
||||
(save-excursion
|
||||
(mapcar (function (lambda (buffer)
|
||||
(set-buffer buffer)
|
||||
(widen)))
|
||||
docstring-ediff-buffers)))
|
||||
|
||||
|
||||
;;; Tests:
|
||||
|
||||
;(find-docstring "/home/neil/Guile/cvs/guile-core/doc/maint/guile.texi" nil "primitive sloppy-assq")
|
||||
;(find-manual-docstring '(guile) "primitive sloppy-assq")
|
||||
;(find-tracking-docstring '(guile) "primitive sloppy-assq")
|
||||
;(find-snarfed-docstring '(guile) "primitive sloppy-assq")
|
||||
|
||||
(defvar docstring-libguile-directory (expand-file-name "libguile"
|
||||
guile-core-dir)
|
||||
"*The directory containing the C source for libguile.")
|
||||
|
||||
(defvar docstring-libguile-build-directory (expand-file-name "libguile"
|
||||
guile-build-dir)
|
||||
"*The directory containing the libguile build directory.")
|
||||
|
||||
(defun docstring-display-location (file line)
|
||||
(let ((buffer (find-file-noselect
|
||||
(expand-file-name file docstring-libguile-directory))))
|
||||
(if buffer
|
||||
(let* ((window (or (get-buffer-window buffer)
|
||||
(display-buffer buffer)))
|
||||
(pos (save-excursion
|
||||
(set-buffer buffer)
|
||||
(goto-line line)
|
||||
(point))))
|
||||
(set-window-point window pos)))))
|
||||
|
||||
(defun docstring-show-source ()
|
||||
"Given that point is sitting in a docstring in one of the Texinfo
|
||||
source files for the Guile manual, and that that docstring may be
|
||||
snarfed automatically from a libguile C file, determine whether the
|
||||
docstring is from libguile and, if it is, display the relevant C file
|
||||
at the line from which the docstring was snarfed.
|
||||
|
||||
Why? When updating snarfed docstrings, you should usually edit the C
|
||||
source rather than the Texinfo source, so that your updates benefit
|
||||
Guile's online help as well. This function locates the C source for a
|
||||
docstring so that it is easy for you to do this."
|
||||
(interactive)
|
||||
(let* ((deffn-line
|
||||
(save-excursion
|
||||
(end-of-line)
|
||||
(or (re-search-backward "^@deffn " nil t)
|
||||
(error "No docstring here!"))
|
||||
(buffer-substring (point)
|
||||
(progn
|
||||
(end-of-line)
|
||||
(point)))))
|
||||
(guile-texi-file
|
||||
(expand-file-name "guile.texi" docstring-libguile-build-directory))
|
||||
(source-location
|
||||
(save-excursion
|
||||
(set-buffer (find-file-noselect guile-texi-file))
|
||||
(save-excursion
|
||||
(goto-char (point-min))
|
||||
(or (re-search-forward (concat "^"
|
||||
(regexp-quote deffn-line)
|
||||
"$")
|
||||
nil t)
|
||||
(error "Docstring not from libguile"))
|
||||
(forward-line -1)
|
||||
(if (looking-at "^@c snarfed from \\([^:]+\\):\\([0-9]+\\)$")
|
||||
(cons (match-string 1)
|
||||
(string-to-int (match-string 2)))
|
||||
(error "Corrupt docstring entry in guile.texi"))))))
|
||||
(docstring-display-location (car source-location)
|
||||
(cdr source-location))))
|
||||
|
||||
|
||||
(provide 'docstring)
|
||||
|
||||
;;; docstring.el ends here
|
11091
doc/maint/guile.texi
11091
doc/maint/guile.texi
File diff suppressed because it is too large
Load diff
|
@ -75,7 +75,6 @@ guile_TEXINFOS = preface.texi \
|
|||
r6rs.texi \
|
||||
match.texi \
|
||||
misc-modules.texi \
|
||||
api-compound.texi \
|
||||
libguile-autoconf.texi \
|
||||
autoconf-macros.texi \
|
||||
tools.texi \
|
||||
|
@ -120,7 +119,7 @@ EXTRA_DIST = ChangeLog-2008 $(PICTURES)
|
|||
|
||||
libguile-autoconf.texi: autoconf-macros.texi
|
||||
autoconf-macros.texi: $(top_srcdir)/meta/guile.m4
|
||||
GUILE_AUTO_COMPILE=0 $(top_builddir)/meta/uninstalled-env guild \
|
||||
GUILE_AUTO_COMPILE=0 $(top_builddir)/meta/build-env guild \
|
||||
snarf-guile-m4-docs $(top_srcdir)/meta/guile.m4 \
|
||||
> $(srcdir)/$@
|
||||
|
||||
|
|
|
@ -93,7 +93,7 @@ Many people end up in a development style of adding and changing
|
|||
definitions at runtime, building out their program without restarting
|
||||
it. (You can do this using @code{reload-module}, the @code{reload} REPL
|
||||
command, the @code{load} procedure, or even just pasting code into a
|
||||
REPL.) If you are one of these people, you will find that sometimes you
|
||||
REPL.) If you are one of these people, you will find that sometimes
|
||||
there are some variables that you @emph{don't} want to redefine all the
|
||||
time. For these, use @code{define-once}.
|
||||
|
||||
|
@ -301,7 +301,7 @@ following case:
|
|||
(define a 1)
|
||||
(define b (+ a a))
|
||||
(+ a b))
|
||||
@end lisp
|
||||
@end lisp
|
||||
|
||||
@noindent
|
||||
Guile decided to follow the R6RS in this regard, and now expands
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -21,6 +21,8 @@ flow of Scheme affects C code.
|
|||
* Exceptions:: Throwing and catching exceptions.
|
||||
* Error Reporting:: Procedures for signaling errors.
|
||||
* Dynamic Wind:: Dealing with non-local entrance/exit.
|
||||
* Fluids and Dynamic States:: Dynamic scope building blocks.
|
||||
* Parameters:: A dynamic scope facility.
|
||||
* Handling Errors:: How to handle errors in C code.
|
||||
* Continuation Barriers:: Protection from non-local control flow.
|
||||
@end menu
|
||||
|
@ -168,7 +170,7 @@ Each @code{cond}-clause must look like this:
|
|||
(@var{test} @var{expression} @dots{})
|
||||
@end lisp
|
||||
|
||||
where @var{test} and @var{expression} are arbitrary expression, or like
|
||||
where @var{test} and @var{expression} are arbitrary expressions, or like
|
||||
this
|
||||
|
||||
@lisp
|
||||
|
@ -178,7 +180,7 @@ this
|
|||
where @var{expression} must evaluate to a procedure.
|
||||
|
||||
The @var{test}s of the clauses are evaluated in order and as soon as one
|
||||
of them evaluates to a true values, the corresponding @var{expression}s
|
||||
of them evaluates to a true value, the corresponding @var{expression}s
|
||||
are evaluated in order and the last value is returned as the value of
|
||||
the @code{cond}-expression. For the @code{=>} clause type,
|
||||
@var{expression} is evaluated and the resulting procedure is applied to
|
||||
|
@ -584,10 +586,8 @@ important efficiency consideration to keep in mind.
|
|||
One example where this optimization matters is @dfn{escape
|
||||
continuations}. Escape continuations are delimited continuations whose
|
||||
only use is to make a non-local exit---i.e., to escape from the current
|
||||
continuation. Such continuations are invoked only once, and for this
|
||||
reason they are sometimes called @dfn{one-shot continuations}. A common
|
||||
use of escape continuations is when throwing an exception
|
||||
(@pxref{Exceptions}).
|
||||
continuation. A common use of escape continuations is when throwing an
|
||||
exception (@pxref{Exceptions}).
|
||||
|
||||
The constructs below are syntactic sugar atop prompts to simplify the
|
||||
use of escape continuations.
|
||||
|
@ -628,6 +628,33 @@ This is equivalent to
|
|||
@code{(call/ec (lambda (@var{k}) @var{body} @dots{}))}.
|
||||
@end deffn
|
||||
|
||||
Additionally there is another helper primitive exported by @code{(ice-9
|
||||
control)}, so load up that module for @code{suspendable-continuation?}:
|
||||
|
||||
@example
|
||||
(use-modules (ice-9 control))
|
||||
@end example
|
||||
|
||||
@deffn {Scheme Procedure} suspendable-continuation? tag
|
||||
Return @code{#t} if a call to @code{abort-to-prompt} with the prompt tag
|
||||
@var{tag} would produce a delimited continuation that could be resumed
|
||||
later.
|
||||
|
||||
Almost all continuations have this property. The exception is where
|
||||
some code between the @code{call-with-prompt} and the
|
||||
@code{abort-to-prompt} recursed through C for some reason, the
|
||||
@code{abort-to-prompt} will succeed but any attempt to resume the
|
||||
continuation (by calling it) would fail. This is because composing a
|
||||
saved continuation with the current continuation involves relocating the
|
||||
stack frames that were saved from the old stack onto a (possibly) new
|
||||
position on the new stack, and Guile can only do this for stack frames
|
||||
that it created for Scheme code, not stack frames created by the C
|
||||
compiler. It's a bit gnarly but if you stick with Scheme, you won't
|
||||
have any problem.
|
||||
|
||||
If no prompt is found with the given tag, this procedure just returns
|
||||
@code{#f}.
|
||||
@end deffn
|
||||
|
||||
@node Shift and Reset
|
||||
@subsubsection Shift, Reset, and All That
|
||||
|
@ -896,7 +923,7 @@ a new values object, and copies into it the @var{n} values starting from
|
|||
@var{base}.
|
||||
|
||||
Currently this creates a list and passes it to @code{scm_values}, but we
|
||||
expect that in the future we will be able to use more a efficient
|
||||
expect that in the future we will be able to use a more efficient
|
||||
representation.
|
||||
@end deftypefn
|
||||
|
||||
|
@ -1660,6 +1687,339 @@ context is exited, whether normally or non-locally.
|
|||
@end deftypefn
|
||||
|
||||
|
||||
@node Fluids and Dynamic States
|
||||
@subsection Fluids and Dynamic States
|
||||
|
||||
@cindex fluids
|
||||
|
||||
A @emph{fluid} is a variable whose value is associated with the dynamic
|
||||
extent of a function call. In the same way that an operating system
|
||||
runs a process with a given set of current input and output ports (or
|
||||
file descriptors), in Guile you can arrange to call a function while
|
||||
binding a fluid to a particular value. That association between fluid
|
||||
and value will exist during the dynamic extent of the function call.
|
||||
|
||||
Fluids are a therefore a building block for implementing dynamically
|
||||
scoped variables. Dynamically scoped variables are useful when you want
|
||||
to set a variable to a value during some dynamic extent in the execution
|
||||
of your program and have them revert to their original value when the
|
||||
control flow is outside of this dynamic extent. See the description of
|
||||
@code{with-fluids} below for details. This association between fluids,
|
||||
values, and dynamic extents is robust to multiple entries (as when a
|
||||
captured continuation is invoked more than once) and early exits (for
|
||||
example, when throwing exceptions).
|
||||
|
||||
Guile uses fluids to implement parameters (@pxref{Parameters}). Usually
|
||||
you just want to use parameters directly. However it can be useful to
|
||||
know what a fluid is and how it works, so that's what this section is
|
||||
about.
|
||||
|
||||
The current set of fluid-value associations can be captured in a
|
||||
@emph{dynamic state} object. A dynamic extent is simply that: a
|
||||
snapshot of the current fluid-value associations. Guile users can
|
||||
capture the current dynamic state with @code{current-dynamic-state} and
|
||||
restore it later via @code{with-dynamic-state} or similar procedures.
|
||||
This facility is especially useful when implementing lightweight
|
||||
thread-like abstractions.
|
||||
|
||||
New fluids are created with @code{make-fluid} and @code{fluid?} is
|
||||
used for testing whether an object is actually a fluid. The values
|
||||
stored in a fluid can be accessed with @code{fluid-ref} and
|
||||
@code{fluid-set!}.
|
||||
|
||||
@xref{Thread Local Variables}, for further notes on fluids, threads,
|
||||
parameters, and dynamic states.
|
||||
|
||||
@deffn {Scheme Procedure} make-fluid [dflt]
|
||||
@deffnx {C Function} scm_make_fluid ()
|
||||
@deffnx {C Function} scm_make_fluid_with_default (dflt)
|
||||
Return a newly created fluid, whose initial value is @var{dflt}, or
|
||||
@code{#f} if @var{dflt} is not given.
|
||||
Fluids are objects that can hold one
|
||||
value per dynamic state. That is, modifications to this value are
|
||||
only visible to code that executes with the same dynamic state as
|
||||
the modifying code. When a new dynamic state is constructed, it
|
||||
inherits the values from its parent. Because each thread normally executes
|
||||
with its own dynamic state, you can use fluids for thread local storage.
|
||||
@end deffn
|
||||
|
||||
@deffn {Scheme Procedure} make-unbound-fluid
|
||||
@deffnx {C Function} scm_make_unbound_fluid ()
|
||||
Return a new fluid that is initially unbound (instead of being
|
||||
implicitly bound to some definite value).
|
||||
@end deffn
|
||||
|
||||
@deffn {Scheme Procedure} fluid? obj
|
||||
@deffnx {C Function} scm_fluid_p (obj)
|
||||
Return @code{#t} if @var{obj} is a fluid; otherwise, return
|
||||
@code{#f}.
|
||||
@end deffn
|
||||
|
||||
@deffn {Scheme Procedure} fluid-ref fluid
|
||||
@deffnx {C Function} scm_fluid_ref (fluid)
|
||||
Return the value associated with @var{fluid} in the current
|
||||
dynamic root. If @var{fluid} has not been set, then return
|
||||
its default value. Calling @code{fluid-ref} on an unbound fluid produces
|
||||
a runtime error.
|
||||
@end deffn
|
||||
|
||||
@deffn {Scheme Procedure} fluid-set! fluid value
|
||||
@deffnx {C Function} scm_fluid_set_x (fluid, value)
|
||||
Set the value associated with @var{fluid} in the current dynamic root.
|
||||
@end deffn
|
||||
|
||||
@deffn {Scheme Procedure} fluid-ref* fluid depth
|
||||
@deffnx {C Function} scm_fluid_ref_star (fluid, depth)
|
||||
Return the @var{depth}th oldest value associated with @var{fluid} in the
|
||||
current thread. If @var{depth} equals or exceeds the number of values
|
||||
that have been assigned to @var{fluid}, return the default value of the
|
||||
fluid. @code{(fluid-ref* f 0)} is equivalent to @code{(fluid-ref f)}.
|
||||
|
||||
@code{fluid-ref*} is useful when you want to maintain a stack-like
|
||||
structure in a fluid, such as the stack of current exception handlers.
|
||||
Using @code{fluid-ref*} instead of an explicit stack allows any partial
|
||||
continuation captured by @code{call-with-prompt} to only capture the
|
||||
bindings made within the limits of the prompt instead of the entire
|
||||
continuation. @xref{Prompts}, for more on delimited continuations.
|
||||
@end deffn
|
||||
|
||||
@deffn {Scheme Procedure} fluid-unset! fluid
|
||||
@deffnx {C Function} scm_fluid_unset_x (fluid)
|
||||
Disassociate the given fluid from any value, making it unbound.
|
||||
@end deffn
|
||||
|
||||
@deffn {Scheme Procedure} fluid-bound? fluid
|
||||
@deffnx {C Function} scm_fluid_bound_p (fluid)
|
||||
Returns @code{#t} if the given fluid is bound to a value, otherwise
|
||||
@code{#f}.
|
||||
@end deffn
|
||||
|
||||
@code{with-fluids*} temporarily changes the values of one or more fluids,
|
||||
so that the given procedure and each procedure called by it access the
|
||||
given values. After the procedure returns, the old values are restored.
|
||||
|
||||
@deffn {Scheme Procedure} with-fluid* fluid value thunk
|
||||
@deffnx {C Function} scm_with_fluid (fluid, value, thunk)
|
||||
Set @var{fluid} to @var{value} temporarily, and call @var{thunk}.
|
||||
@var{thunk} must be a procedure with no argument.
|
||||
@end deffn
|
||||
|
||||
@deffn {Scheme Procedure} with-fluids* fluids values thunk
|
||||
@deffnx {C Function} scm_with_fluids (fluids, values, thunk)
|
||||
Set @var{fluids} to @var{values} temporary, and call @var{thunk}.
|
||||
@var{fluids} must be a list of fluids and @var{values} must be the
|
||||
same number of their values to be applied. Each substitution is done
|
||||
in the order given. @var{thunk} must be a procedure with no argument.
|
||||
It is called inside a @code{dynamic-wind} and the fluids are
|
||||
set/restored when control enter or leaves the established dynamic
|
||||
extent.
|
||||
@end deffn
|
||||
|
||||
@deffn {Scheme Macro} with-fluids ((fluid value) @dots{}) body1 body2 @dots{}
|
||||
Execute body @var{body1} @var{body2} @dots{} while each @var{fluid} is
|
||||
set to the corresponding @var{value}. Both @var{fluid} and @var{value}
|
||||
are evaluated and @var{fluid} must yield a fluid. The body is executed
|
||||
inside a @code{dynamic-wind} and the fluids are set/restored when
|
||||
control enter or leaves the established dynamic extent.
|
||||
@end deffn
|
||||
|
||||
@deftypefn {C Function} SCM scm_c_with_fluids (SCM fluids, SCM vals, SCM (*cproc)(void *), void *data)
|
||||
@deftypefnx {C Function} SCM scm_c_with_fluid (SCM fluid, SCM val, SCM (*cproc)(void *), void *data)
|
||||
The function @code{scm_c_with_fluids} is like @code{scm_with_fluids}
|
||||
except that it takes a C function to call instead of a Scheme thunk.
|
||||
|
||||
The function @code{scm_c_with_fluid} is similar but only allows one
|
||||
fluid to be set instead of a list.
|
||||
@end deftypefn
|
||||
|
||||
@deftypefn {C Function} void scm_dynwind_fluid (SCM fluid, SCM val)
|
||||
This function must be used inside a pair of calls to
|
||||
@code{scm_dynwind_begin} and @code{scm_dynwind_end} (@pxref{Dynamic
|
||||
Wind}). During the dynwind context, the fluid @var{fluid} is set to
|
||||
@var{val}.
|
||||
|
||||
More precisely, the value of the fluid is swapped with a `backup'
|
||||
value whenever the dynwind context is entered or left. The backup
|
||||
value is initialized with the @var{val} argument.
|
||||
@end deftypefn
|
||||
|
||||
@deffn {Scheme Procedure} dynamic-state? obj
|
||||
@deffnx {C Function} scm_dynamic_state_p (obj)
|
||||
Return @code{#t} if @var{obj} is a dynamic state object;
|
||||
return @code{#f} otherwise.
|
||||
@end deffn
|
||||
|
||||
@deftypefn {C Procedure} int scm_is_dynamic_state (SCM obj)
|
||||
Return non-zero if @var{obj} is a dynamic state object;
|
||||
return zero otherwise.
|
||||
@end deftypefn
|
||||
|
||||
@deffn {Scheme Procedure} current-dynamic-state
|
||||
@deffnx {C Function} scm_current_dynamic_state ()
|
||||
Return a snapshot of the current fluid-value associations as a fresh
|
||||
dynamic state object.
|
||||
@end deffn
|
||||
|
||||
@deffn {Scheme Procedure} set-current-dynamic-state state
|
||||
@deffnx {C Function} scm_set_current_dynamic_state (state)
|
||||
Restore the saved fluid-value associations from @var{state}, replacing
|
||||
the current fluid-value associations. Return the current fluid-value
|
||||
associatoins as a dynamic state object, as in
|
||||
@code{current-dynamic-state}.
|
||||
@end deffn
|
||||
|
||||
@deffn {Scheme Procedure} with-dynamic-state state proc
|
||||
@deffnx {C Function} scm_with_dynamic_state (state, proc)
|
||||
Call @var{proc} while the fluid bindings from @var{state} have been made
|
||||
current, saving the current fluid bindings. When control leaves the
|
||||
invocation of @var{proc}, restore the saved bindings, saving instead the
|
||||
fluid bindings from inside the call. If control later re-enters
|
||||
@var{proc}, restore those saved bindings, saving the current bindings,
|
||||
and so on.
|
||||
@end deffn
|
||||
|
||||
@deftypefn {C Procedure} void scm_dynwind_current_dynamic_state (SCM state)
|
||||
Set the current dynamic state to @var{state} for the current dynwind
|
||||
context. Like @code{with-dynamic-state}, but in terms of Guile's
|
||||
``dynwind'' C API.
|
||||
@end deftypefn
|
||||
|
||||
@deftypefn {C Procedure} {void *} scm_c_with_dynamic_state (SCM state, void *(*func)(void *), void *data)
|
||||
Like @code{scm_with_dynamic_state}, but call @var{func} with
|
||||
@var{data}.
|
||||
@end deftypefn
|
||||
|
||||
@node Parameters
|
||||
@subsection Parameters
|
||||
|
||||
@cindex SRFI-39
|
||||
@cindex parameter object
|
||||
@tindex Parameter
|
||||
|
||||
Parameters are Guile's facility for dynamically bound variables.
|
||||
|
||||
On the most basic level, a parameter object is a procedure. Calling it
|
||||
with no arguments returns its value. Calling it with one argument sets
|
||||
the value.
|
||||
|
||||
@example
|
||||
(define my-param (make-parameter 123))
|
||||
(my-param) @result{} 123
|
||||
(my-param 456)
|
||||
(my-param) @result{} 456
|
||||
@end example
|
||||
|
||||
The @code{parameterize} special form establishes new locations for
|
||||
parameters, those new locations having effect within the dynamic extent
|
||||
of the @code{parameterize} body. Leaving restores the previous
|
||||
locations. Re-entering (through a saved continuation) will again use
|
||||
the new locations.
|
||||
|
||||
@example
|
||||
(parameterize ((my-param 789))
|
||||
(my-param)) @result{} 789
|
||||
(my-param) @result{} 456
|
||||
@end example
|
||||
|
||||
Parameters are like dynamically bound variables in other Lisp dialects.
|
||||
They allow an application to establish parameter settings (as the name
|
||||
suggests) just for the execution of a particular bit of code, restoring
|
||||
when done. Examples of such parameters might be case-sensitivity for a
|
||||
search, or a prompt for user input.
|
||||
|
||||
Global variables are not as good as parameter objects for this sort of
|
||||
thing. Changes to them are visible to all threads, but in Guile
|
||||
parameter object locations are per-thread, thereby truly limiting the
|
||||
effect of @code{parameterize} to just its dynamic execution.
|
||||
|
||||
Passing arguments to functions is thread-safe, but that soon becomes
|
||||
tedious when there's more than a few or when they need to pass down
|
||||
through several layers of calls before reaching the point they should
|
||||
affect. Introducing a new setting to existing code is often easier with
|
||||
a parameter object than adding arguments.
|
||||
|
||||
@deffn {Scheme Procedure} make-parameter init [converter]
|
||||
Return a new parameter object, with initial value @var{init}.
|
||||
|
||||
If a @var{converter} is given, then a call @code{(@var{converter}
|
||||
val)} is made for each value set, its return is the value stored.
|
||||
Such a call is made for the @var{init} initial value too.
|
||||
|
||||
A @var{converter} allows values to be validated, or put into a
|
||||
canonical form. For example,
|
||||
|
||||
@example
|
||||
(define my-param (make-parameter 123
|
||||
(lambda (val)
|
||||
(if (not (number? val))
|
||||
(error "must be a number"))
|
||||
(inexact->exact val))))
|
||||
(my-param 0.75)
|
||||
(my-param) @result{} 3/4
|
||||
@end example
|
||||
@end deffn
|
||||
|
||||
@deffn {library syntax} parameterize ((param value) @dots{}) body1 body2 @dots{}
|
||||
Establish a new dynamic scope with the given @var{param}s bound to new
|
||||
locations and set to the given @var{value}s. @var{body1} @var{body2}
|
||||
@dots{} is evaluated in that environment. The value returned is that of
|
||||
last body form.
|
||||
|
||||
Each @var{param} is an expression which is evaluated to get the
|
||||
parameter object. Often this will just be the name of a variable
|
||||
holding the object, but it can be anything that evaluates to a
|
||||
parameter.
|
||||
|
||||
The @var{param} expressions and @var{value} expressions are all
|
||||
evaluated before establishing the new dynamic bindings, and they're
|
||||
evaluated in an unspecified order.
|
||||
|
||||
For example,
|
||||
|
||||
@example
|
||||
(define prompt (make-parameter "Type something: "))
|
||||
(define (get-input)
|
||||
(display (prompt))
|
||||
...)
|
||||
|
||||
(parameterize ((prompt "Type a number: "))
|
||||
(get-input)
|
||||
...)
|
||||
@end example
|
||||
@end deffn
|
||||
|
||||
Parameter objects are implemented using fluids (@pxref{Fluids and
|
||||
Dynamic States}), so each dynamic state has its own parameter
|
||||
locations. That includes the separate locations when outside any
|
||||
@code{parameterize} form. When a parameter is created it gets a
|
||||
separate initial location in each dynamic state, all initialized to the
|
||||
given @var{init} value.
|
||||
|
||||
New code should probably just use parameters instead of fluids, because
|
||||
the interface is better. But for migrating old code or otherwise
|
||||
providing interoperability, Guile provides the @code{fluid->parameter}
|
||||
procedure:
|
||||
|
||||
@deffn {Scheme Procedure} fluid->parameter fluid [conv]
|
||||
Make a parameter that wraps a fluid.
|
||||
|
||||
The value of the parameter will be the same as the value of the fluid.
|
||||
If the parameter is rebound in some dynamic extent, perhaps via
|
||||
@code{parameterize}, the new value will be run through the optional
|
||||
@var{conv} procedure, as with any parameter. Note that unlike
|
||||
@code{make-parameter}, @var{conv} is not applied to the initial value.
|
||||
@end deffn
|
||||
|
||||
As alluded to above, because each thread usually has a separate dynamic
|
||||
state, each thread has its own locations behind parameter objects, and
|
||||
changes in one thread are not visible to any other. When a new dynamic
|
||||
state or thread is created, the values of parameters in the originating
|
||||
context are copied, into new locations.
|
||||
|
||||
@cindex SRFI-39
|
||||
Guile's parameters conform to SRFI-39 (@pxref{SRFI-39}).
|
||||
|
||||
|
||||
@node Handling Errors
|
||||
@subsection How to Handle Errors
|
||||
|
||||
|
@ -1801,8 +2161,8 @@ In @code{scm_wrong_type_arg_msg}, @var{expected} is a C string
|
|||
describing the type of argument that was expected.
|
||||
|
||||
In @code{scm_misc_error}, @var{message} is the error message string,
|
||||
possibly containing @code{simple-format} escapes (@pxref{Writing}), and
|
||||
the corresponding arguments in the @var{args} list.
|
||||
possibly containing @code{simple-format} escapes (@pxref{Simple
|
||||
Output}), and the corresponding arguments in the @var{args} list.
|
||||
@end deftypefn
|
||||
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -177,10 +177,10 @@ Return the previous frame of @var{frame}, or @code{#f} if
|
|||
@var{frame} is the first frame in its stack.
|
||||
@end deffn
|
||||
|
||||
@deffn {Scheme Procedure} frame-procedure frame
|
||||
@deffnx {C Function} scm_frame_procedure (frame)
|
||||
Return the procedure for @var{frame}, or @code{#f} if no
|
||||
procedure is associated with @var{frame}.
|
||||
@deffn {Scheme Procedure} frame-procedure-name frame
|
||||
@deffnx {C Function} scm_frame_procedure_name (frame)
|
||||
Return the name of the procedure being applied in @var{frame}, as a
|
||||
symbol, or @code{#f} if the procedure has no name.
|
||||
@end deffn
|
||||
|
||||
@deffn {Scheme Procedure} frame-arguments frame
|
||||
|
@ -201,16 +201,32 @@ respectively. @xref{VM Concepts}, for more information.
|
|||
@deffnx {Scheme Procedure} frame-mv-return-address frame
|
||||
Accessors for the three saved VM registers in a frame: the previous
|
||||
frame pointer, the single-value return address, and the multiple-value
|
||||
return address. @xref{Stack Layout}, for more information.
|
||||
return address. @xref{Stack Layout}, for more information.
|
||||
@end deffn
|
||||
|
||||
@deffn {Scheme Procedure} frame-num-locals frame
|
||||
@deffnx {Scheme Procedure} frame-local-ref frame i
|
||||
@deffnx {Scheme Procedure} frame-local-set! frame i val
|
||||
Accessors for the temporary values corresponding to @var{frame}'s
|
||||
procedure application. The first local is the first argument given to
|
||||
the procedure. After the arguments, there are the local variables, and
|
||||
after that temporary values. @xref{Stack Layout}, for more information.
|
||||
@deffn {Scheme Procedure} frame-bindings frame
|
||||
Return a list of binding records indicating the local variables that are
|
||||
live in a frame.
|
||||
@end deffn
|
||||
|
||||
@deffn {Scheme Procedure} frame-lookup-binding frame var
|
||||
Fetch the bindings in @var{frame}, and return the first one whose name
|
||||
is @var{var}, or @code{#f} otherwise.
|
||||
@end deffn
|
||||
|
||||
@deffn {Scheme Procedure} binding-index binding
|
||||
@deffnx {Scheme Procedure} binding-name binding
|
||||
@deffnx {Scheme Procedure} binding-slot binding
|
||||
@deffnx {Scheme Procedure} binding-representation binding
|
||||
Accessors for the various fields in a binding. The implicit ``callee''
|
||||
argument is index 0, the first argument is index 1, and so on to the end
|
||||
of the arguments. After that are temporary variables. Note that if a
|
||||
variable is dead, it might not be available.
|
||||
@end deffn
|
||||
|
||||
@deffn {Scheme Procedure} binding-ref binding
|
||||
@deffnx {Scheme Procedure} binding-set! binding val
|
||||
Accessors for the values of local variables in a frame.
|
||||
@end deffn
|
||||
|
||||
@deffn {Scheme Procedure} display-application frame [port [indent]]
|
||||
|
@ -1088,11 +1104,6 @@ separately, we discuss them all together here:
|
|||
@table @code
|
||||
@item #:vm
|
||||
The VM to instrument. Defaults to the current thread's VM.
|
||||
@item #:closure?
|
||||
For traps that depend on the current frame's procedure, this argument
|
||||
specifies whether to trap on the only the specific procedure given, or
|
||||
on any closure that has the given procedure's code. Defaults to
|
||||
@code{#f}.
|
||||
@item #:current-frame
|
||||
For traps that enable more hooks depending on their dynamic context,
|
||||
this argument gives the current frame that the trap is running in.
|
||||
|
@ -1107,12 +1118,12 @@ To have access to these procedures, you'll need to have imported the
|
|||
@end lisp
|
||||
|
||||
@deffn {Scheme Procedure} trap-at-procedure-call proc handler @
|
||||
[#:vm] [#:closure?]
|
||||
[#:vm]
|
||||
A trap that calls @var{handler} when @var{proc} is applied.
|
||||
@end deffn
|
||||
|
||||
@deffn {Scheme Procedure} trap-in-procedure proc @
|
||||
enter-handler exit-handler [#:current-frame] [#:vm] [#:closure?]
|
||||
enter-handler exit-handler [#:current-frame] [#:vm]
|
||||
A trap that calls @var{enter-handler} when control enters @var{proc},
|
||||
and @var{exit-handler} when control leaves @var{proc}.
|
||||
|
||||
|
@ -1140,13 +1151,13 @@ An abort.
|
|||
@end deffn
|
||||
|
||||
@deffn {Scheme Procedure} trap-instructions-in-procedure proc @
|
||||
next-handler exit-handler [#:current-frame] [#:vm] [#:closure?]
|
||||
next-handler exit-handler [#:current-frame] [#:vm]
|
||||
A trap that calls @var{next-handler} for every instruction executed in
|
||||
@var{proc}, and @var{exit-handler} when execution leaves @var{proc}.
|
||||
@end deffn
|
||||
|
||||
@deffn {Scheme Procedure} trap-at-procedure-ip-in-range proc range @
|
||||
handler [#:current-frame] [#:vm] [#:closure?]
|
||||
handler [#:current-frame] [#:vm]
|
||||
A trap that calls @var{handler} when execution enters a range of
|
||||
instructions in @var{proc}. @var{range} is a simple of pairs,
|
||||
@code{((@var{start} . @var{end}) ...)}. The @var{start} addresses are
|
||||
|
@ -1169,7 +1180,7 @@ exit.
|
|||
@end deffn
|
||||
|
||||
@deffn {Scheme Procedure} trap-in-dynamic-extent proc @
|
||||
enter-handler return-handler abort-handler [#:vm] [#:closure?]
|
||||
enter-handler return-handler abort-handler [#:vm]
|
||||
A more traditional dynamic-wind trap, which fires @var{enter-handler}
|
||||
when control enters @var{proc}, @var{return-handler} on a normal return,
|
||||
and @var{abort-handler} on a nonlocal exit.
|
||||
|
@ -1178,14 +1189,14 @@ Note that rewinds are not handled, so there is no rewind handler.
|
|||
@end deffn
|
||||
|
||||
@deffn {Scheme Procedure} trap-calls-in-dynamic-extent proc @
|
||||
apply-handler return-handler [#:current-frame] [#:vm] [#:closure?]
|
||||
apply-handler return-handler [#:current-frame] [#:vm]
|
||||
A trap that calls @var{apply-handler} every time a procedure is applied,
|
||||
and @var{return-handler} for returns, but only during the dynamic extent
|
||||
of an application of @var{proc}.
|
||||
@end deffn
|
||||
|
||||
@deffn {Scheme Procedure} trap-instructions-in-dynamic-extent proc @
|
||||
next-handler [#:current-frame] [#:vm] [#:closure?]
|
||||
next-handler [#:current-frame] [#:vm]
|
||||
A trap that calls @var{next-handler} for all retired instructions within
|
||||
the dynamic extent of a call to @var{proc}.
|
||||
@end deffn
|
||||
|
|
|
@ -22,6 +22,7 @@ loading, evaluating, and compiling Scheme code at run time.
|
|||
* Delayed Evaluation:: Postponing evaluation until it is needed.
|
||||
* Local Evaluation:: Evaluation in a local lexical environment.
|
||||
* Local Inclusion:: Compile-time inclusion of one file in another.
|
||||
* Sandboxed Evaluation:: Evaluation with limited capabilities.
|
||||
* REPL Servers:: Serving a REPL over a socket.
|
||||
* Cooperative REPL Servers:: REPL server for single-threaded applications.
|
||||
@end menu
|
||||
|
@ -136,6 +137,7 @@ an expression to be evaluated and inserted. The comma syntax @code{,}
|
|||
is simply a shorthand for an @code{unquote} form. For example,
|
||||
|
||||
@example
|
||||
`(1 2 (* 9 9) 3 4) @result{} (1 2 (* 9 9) 3 4)
|
||||
`(1 2 ,(* 9 9) 3 4) @result{} (1 2 81 3 4)
|
||||
`(1 (unquote (+ 1 1)) 3) @result{} (1 2 3)
|
||||
`#(1 ,(/ 12 2)) @result{} #(1 6)
|
||||
|
@ -153,8 +155,9 @@ the returned list inserted. @var{expr} must evaluate to a list. The
|
|||
|
||||
@example
|
||||
(define x '(2 3))
|
||||
`(1 ,x 4) @result{} (1 (2 3) 4)
|
||||
`(1 ,@@x 4) @result{} (1 2 3 4)
|
||||
`(1 (unquote-splicing (map 1+ x))) @result{} (1 3 4)
|
||||
`(1 (unquote-splicing (map 1+ x))) @result{} (1 3 4)
|
||||
`#(9 ,@@x 9) @result{} #(9 2 3 9)
|
||||
@end example
|
||||
|
||||
|
@ -1225,6 +1228,270 @@ the source files for a package (as you should!). It makes it possible
|
|||
to evaluate an installed file from source, instead of relying on the
|
||||
@code{.go} file being up to date.
|
||||
|
||||
@node Sandboxed Evaluation
|
||||
@subsection Sandboxed Evaluation
|
||||
|
||||
Sometimes you would like to evaluate code that comes from an untrusted
|
||||
party. The safest way to do this is to buy a new computer, evaluate the
|
||||
code on that computer, then throw the machine away. However if you are
|
||||
unwilling to take this simple approach, Guile does include a limited
|
||||
``sandbox'' facility that can allow untrusted code to be evaluated with
|
||||
some confidence.
|
||||
|
||||
To use the sandboxed evaluator, load its module:
|
||||
|
||||
@example
|
||||
(use-modules (ice-9 sandbox))
|
||||
@end example
|
||||
|
||||
Guile's sandboxing facility starts with the ability to restrict the time
|
||||
and space used by a piece of code.
|
||||
|
||||
@deffn {Scheme Procedure} call-with-time-limit limit thunk limit-reached
|
||||
Call @var{thunk}, but cancel it if @var{limit} seconds of wall-clock
|
||||
time have elapsed. If the computation is cancelled, call
|
||||
@var{limit-reached} in tail position. @var{thunk} must not disable
|
||||
interrupts or prevent an abort via a @code{dynamic-wind} unwind handler.
|
||||
@end deffn
|
||||
|
||||
@deffn {Scheme Procedure} call-with-allocation-limit limit thunk limit-reached
|
||||
Call @var{thunk}, but cancel it if @var{limit} bytes have been
|
||||
allocated. If the computation is cancelled, call @var{limit-reached} in
|
||||
tail position. @var{thunk} must not disable interrupts or prevent an
|
||||
abort via a @code{dynamic-wind} unwind handler.
|
||||
|
||||
This limit applies to both stack and heap allocation. The computation
|
||||
will not be aborted before @var{limit} bytes have been allocated, but
|
||||
for the heap allocation limit, the check may be postponed until the next garbage collection.
|
||||
|
||||
Note that as a current shortcoming, the heap size limit applies to all
|
||||
threads; concurrent allocation by other unrelated threads counts towards
|
||||
the allocation limit.
|
||||
@end deffn
|
||||
|
||||
@deffn {Scheme Procedure} call-with-time-and-allocation-limits time-limit allocation-limit thunk
|
||||
Invoke @var{thunk} in a dynamic extent in which its execution is limited
|
||||
to @var{time-limit} seconds of wall-clock time, and its allocation to
|
||||
@var{allocation-limit} bytes. @var{thunk} must not disable interrupts
|
||||
or prevent an abort via a @code{dynamic-wind} unwind handler.
|
||||
|
||||
If successful, return all values produced by invoking @var{thunk}. Any
|
||||
uncaught exception thrown by the thunk will propagate out. If the time
|
||||
or allocation limit is exceeded, an exception will be thrown to the
|
||||
@code{limit-exceeded} key.
|
||||
@end deffn
|
||||
|
||||
The time limit and stack limit are both very precise, but the heap limit
|
||||
only gets checked asynchronously, after a garbage collection. In
|
||||
particular, if the heap is already very large, the number of allocated
|
||||
bytes between garbage collections will be large, and therefore the
|
||||
precision of the check is reduced.
|
||||
|
||||
Additionally, due to the mechanism used by the allocation limit (the
|
||||
@code{after-gc-hook}), large single allocations like @code{(make-vector
|
||||
#e1e7)} are only detected after the allocation completes, even if the
|
||||
allocation itself causes garbage collection. It's possible therefore
|
||||
for user code to not only exceed the allocation limit set, but also to
|
||||
exhaust all available memory, causing out-of-memory conditions at any
|
||||
allocation site. Failure to allocate memory in Guile itself should be
|
||||
safe and cause an exception to be thrown, but most systems are not
|
||||
designed to handle @code{malloc} failures. An allocation failure may
|
||||
therefore exercise unexpected code paths in your system, so it is a
|
||||
weakness of the sandbox (and therefore an interesting point of attack).
|
||||
|
||||
The main sandbox interface is @code{eval-in-sandbox}.
|
||||
|
||||
@deffn {Scheme Procedure} eval-in-sandbox exp [#:time-limit 0.1] @
|
||||
[#:allocation-limit #e10e6] @
|
||||
[#:bindings all-pure-bindings] @
|
||||
[#:module (make-sandbox-module bindings)] @
|
||||
[#:sever-module? #t]
|
||||
Evaluate the Scheme expression @var{exp} within an isolated
|
||||
"sandbox". Limit its execution to @var{time-limit} seconds of
|
||||
wall-clock time, and limit its allocation to @var{allocation-limit}
|
||||
bytes.
|
||||
|
||||
The evaluation will occur in @var{module}, which defaults to the result
|
||||
of calling @code{make-sandbox-module} on @var{bindings}, which itself
|
||||
defaults to @code{all-pure-bindings}. This is the core of the
|
||||
sandbox: creating a scope for the expression that is @dfn{safe}.
|
||||
|
||||
A safe sandbox module has two characteristics. Firstly, it will not
|
||||
allow the expression being evaluated to avoid being cancelled due to
|
||||
time or allocation limits. This ensures that the expression terminates
|
||||
in a timely fashion.
|
||||
|
||||
Secondly, a safe sandbox module will prevent the evaluation from
|
||||
receiving information from previous evaluations, or from affecting
|
||||
future evaluations. All combinations of binding sets exported by
|
||||
@code{(ice-9 sandbox)} form safe sandbox modules.
|
||||
|
||||
The @var{bindings} should be given as a list of import sets. One import
|
||||
set is a list whose car names an interface, like @code{(ice-9 q)}, and
|
||||
whose cdr is a list of imports. An import is either a bare symbol or a
|
||||
pair of @code{(@var{out} . @var{in})}, where @var{out} and @var{in} are
|
||||
both symbols and denote the name under which a binding is exported from
|
||||
the module, and the name under which to make the binding available,
|
||||
respectively. Note that @var{bindings} is only used as an input to the
|
||||
default initializer for the @var{module} argument; if you pass
|
||||
@code{#:module}, @var{bindings} is unused. If @var{sever-module?} is
|
||||
true (the default), the module will be unlinked from the global module
|
||||
tree after the evaluation returns, to allow @var{mod} to be
|
||||
garbage-collected.
|
||||
|
||||
If successful, return all values produced by @var{exp}. Any uncaught
|
||||
exception thrown by the expression will propagate out. If the time or
|
||||
allocation limit is exceeded, an exception will be thrown to the
|
||||
@code{limit-exceeded} key.
|
||||
@end deffn
|
||||
|
||||
Constructing a safe sandbox module is tricky in general. Guile defines
|
||||
an easy way to construct safe modules from predefined sets of bindings.
|
||||
Before getting to that interface, here are some general notes on safety.
|
||||
|
||||
@enumerate
|
||||
@item The time and allocation limits rely on the ability to interrupt
|
||||
and cancel a computation. For this reason, no binding included in a
|
||||
sandbox module should be able to indefinitely postpone interrupt
|
||||
handling, nor should a binding be able to prevent an abort. In practice
|
||||
this second consideration means that @code{dynamic-wind} should not be
|
||||
included in any binding set.
|
||||
@item The time and allocation limits apply only to the
|
||||
@code{eval-in-sandbox} call. If the call returns a procedure which is
|
||||
later called, no limit is ``automatically'' in place. Users of
|
||||
@code{eval-in-sandbox} have to be very careful to reimpose limits when
|
||||
calling procedures that escape from sandboxes.
|
||||
@item Similarly, the dynamic environment of the @code{eval-in-sandbox}
|
||||
call is not necessarily in place when any procedure that escapes from
|
||||
the sandbox is later called.
|
||||
|
||||
This detail prevents us from exposing @code{primitive-eval} to the
|
||||
sandbox, for two reasons. The first is that it's possible for legacy
|
||||
code to forge references to any binding, if the
|
||||
@code{allow-legacy-syntax-objects?} parameter is true. The default for
|
||||
this parameter is true; @pxref{Syntax Transformer Helpers} for the
|
||||
details. The parameter is bound to @code{#f} for the duration of the
|
||||
@code{eval-in-sandbox} call itself, but that will not be in place during
|
||||
calls to escaped procedures.
|
||||
|
||||
The second reason we don't expose @code{primitive-eval} is that
|
||||
@code{primitive-eval} implicitly works in the current module, which for
|
||||
an escaped procedure will probably be different than the module that is
|
||||
current for the @code{eval-in-sandbox} call itself.
|
||||
|
||||
The common denominator here is that if an interface exposed to the
|
||||
sandbox relies on dynamic environments, it is easy to mistakenly grant
|
||||
the sandboxed procedure additional capabilities in the form of bindings
|
||||
that it should not have access to. For this reason, the default sets of
|
||||
predefined bindings do not depend on any dynamically scoped value.
|
||||
@item Mutation may allow a sandboxed evaluation to break some invariant
|
||||
in users of data supplied to it. A lot of code culturally doesn't
|
||||
expect mutation, but if you hand mutable data to a sandboxed evaluation
|
||||
and you also grant mutating capabilities to that evaluation, then the
|
||||
sandboxed code may indeed mutate that data. The default set of bindings
|
||||
to the sandbox do not include any mutating primitives.
|
||||
|
||||
Relatedly, @code{set!} may allow a sandbox to mutate a primitive,
|
||||
invalidating many system-wide invariants. Guile is currently quite
|
||||
permissive when it comes to imported bindings and mutability. Although
|
||||
@code{set!} to a module-local or lexically bound variable would be fine,
|
||||
we don't currently have an easy way to disallow @code{set!} to an
|
||||
imported binding, so currently no binding set includes @code{set!}.
|
||||
@item Mutation may allow a sandboxed evaluation to keep state, or
|
||||
make a communication mechanism with other code. On the one hand this
|
||||
sounds cool, but on the other hand maybe this is part of your threat
|
||||
model. Again, the default set of bindings doesn't include mutating
|
||||
primitives, preventing sandboxed evaluations from keeping state.
|
||||
@item The sandbox should probably not be able to open a network
|
||||
connection, or write to a file, or open a file from disk. The default
|
||||
binding set includes no interaction with the operating system.
|
||||
@end enumerate
|
||||
|
||||
If you, dear reader, find the above discussion interesting, you will
|
||||
enjoy Jonathan Rees' dissertation, ``A Security Kernel Based on the
|
||||
Lambda Calculus''.
|
||||
|
||||
@defvr {Scheme Variable} all-pure-bindings
|
||||
All ``pure'' bindings that together form a safe subset of those bindings
|
||||
available by default to Guile user code.
|
||||
@end defvr
|
||||
|
||||
@defvr {Scheme Variable} all-pure-and-impure-bindings
|
||||
Like @code{all-pure-bindings}, but additionally including mutating
|
||||
primitives like @code{vector-set!}. This set is still safe in the sense
|
||||
mentioned above, with the caveats about mutation.
|
||||
@end defvr
|
||||
|
||||
The components of these composite sets are as follows:
|
||||
@defvr {Scheme Variable} alist-bindings
|
||||
@defvrx {Scheme Variable} array-bindings
|
||||
@defvrx {Scheme Variable} bit-bindings
|
||||
@defvrx {Scheme Variable} bitvector-bindings
|
||||
@defvrx {Scheme Variable} char-bindings
|
||||
@defvrx {Scheme Variable} char-set-bindings
|
||||
@defvrx {Scheme Variable} clock-bindings
|
||||
@defvrx {Scheme Variable} core-bindings
|
||||
@defvrx {Scheme Variable} error-bindings
|
||||
@defvrx {Scheme Variable} fluid-bindings
|
||||
@defvrx {Scheme Variable} hash-bindings
|
||||
@defvrx {Scheme Variable} iteration-bindings
|
||||
@defvrx {Scheme Variable} keyword-bindings
|
||||
@defvrx {Scheme Variable} list-bindings
|
||||
@defvrx {Scheme Variable} macro-bindings
|
||||
@defvrx {Scheme Variable} nil-bindings
|
||||
@defvrx {Scheme Variable} number-bindings
|
||||
@defvrx {Scheme Variable} pair-bindings
|
||||
@defvrx {Scheme Variable} predicate-bindings
|
||||
@defvrx {Scheme Variable} procedure-bindings
|
||||
@defvrx {Scheme Variable} promise-bindings
|
||||
@defvrx {Scheme Variable} prompt-bindings
|
||||
@defvrx {Scheme Variable} regexp-bindings
|
||||
@defvrx {Scheme Variable} sort-bindings
|
||||
@defvrx {Scheme Variable} srfi-4-bindings
|
||||
@defvrx {Scheme Variable} string-bindings
|
||||
@defvrx {Scheme Variable} symbol-bindings
|
||||
@defvrx {Scheme Variable} unspecified-bindings
|
||||
@defvrx {Scheme Variable} variable-bindings
|
||||
@defvrx {Scheme Variable} vector-bindings
|
||||
@defvrx {Scheme Variable} version-bindings
|
||||
The components of @code{all-pure-bindings}.
|
||||
@end defvr
|
||||
|
||||
@defvr {Scheme Variable} mutating-alist-bindings
|
||||
@defvrx {Scheme Variable} mutating-array-bindings
|
||||
@defvrx {Scheme Variable} mutating-bitvector-bindings
|
||||
@defvrx {Scheme Variable} mutating-fluid-bindings
|
||||
@defvrx {Scheme Variable} mutating-hash-bindings
|
||||
@defvrx {Scheme Variable} mutating-list-bindings
|
||||
@defvrx {Scheme Variable} mutating-pair-bindings
|
||||
@defvrx {Scheme Variable} mutating-sort-bindings
|
||||
@defvrx {Scheme Variable} mutating-srfi-4-bindings
|
||||
@defvrx {Scheme Variable} mutating-string-bindings
|
||||
@defvrx {Scheme Variable} mutating-variable-bindings
|
||||
@defvrx {Scheme Variable} mutating-vector-bindings
|
||||
The additional components of @code{all-pure-and-impure-bindings}.
|
||||
@end defvr
|
||||
|
||||
Finally, what do you do with a binding set? What is a binding set
|
||||
anyway? @code{make-sandbox-module} is here for you.
|
||||
|
||||
@deffn {Scheme Procedure} make-sandbox-module bindings
|
||||
Return a fresh module that only contains @var{bindings}.
|
||||
|
||||
The @var{bindings} should be given as a list of import sets. One import
|
||||
set is a list whose car names an interface, like @code{(ice-9 q)}, and
|
||||
whose cdr is a list of imports. An import is either a bare symbol or a
|
||||
pair of @code{(@var{out} . @var{in})}, where @var{out} and @var{in} are
|
||||
both symbols and denote the name under which a binding is exported from
|
||||
the module, and the name under which to make the binding available,
|
||||
respectively.
|
||||
@end deffn
|
||||
|
||||
So you see that binding sets are just lists, and
|
||||
@code{all-pure-and-impure-bindings} is really just the result of
|
||||
appending all of the component binding sets.
|
||||
|
||||
|
||||
@node REPL Servers
|
||||
@subsection REPL Servers
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
@c -*-texinfo-*-
|
||||
@c This is part of the GNU Guile Reference Manual.
|
||||
@c Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004, 2007, 2008,
|
||||
@c 2009, 2010, 2011, 2012, 2013, 2014 Free Software Foundation, Inc.
|
||||
@c Copyright (C) 1996, 1997, 2000-2004, 2007-2014, 2016-2017
|
||||
@c Free Software Foundation, Inc.
|
||||
@c See the file guile.texi for copying conditions.
|
||||
|
||||
@node Foreign Function Interface
|
||||
|
@ -52,7 +52,7 @@ automatically the next time they are run.
|
|||
|
||||
Now, when all the necessary machinery is there to perform part of the
|
||||
linking at run-time, why not take the next step and allow the programmer
|
||||
to explicitly take advantage of it from within his program? Of course,
|
||||
to explicitly take advantage of it from within their program? Of course,
|
||||
many operating systems that support shared libraries do just that, and
|
||||
chances are that Guile will allow you to access this feature from within
|
||||
your Scheme programs. As you might have guessed already, this feature
|
||||
|
@ -89,6 +89,11 @@ When @var{library} is omitted, a @dfn{global symbol handle} is returned. This
|
|||
handle provides access to the symbols available to the program at run-time,
|
||||
including those exported by the program itself and the shared libraries already
|
||||
loaded.
|
||||
|
||||
Note that on hosts that use dynamic-link libraries (DLLs), the global
|
||||
symbol handle may not be able to provide access to symbols from
|
||||
recursively-loaded DLLs. Only exported symbols from those DLLs directly
|
||||
loaded by the program may be available.
|
||||
@end deffn
|
||||
|
||||
@deffn {Scheme Procedure} dynamic-object? obj
|
||||
|
@ -488,6 +493,8 @@ platform-dependent size:
|
|||
@defvrx {Scheme Variable} unsigned-int
|
||||
@defvrx {Scheme Variable} long
|
||||
@defvrx {Scheme Variable} unsigned-long
|
||||
@defvrx {Scheme Variable} short
|
||||
@defvrx {Scheme Variable} unsigned-short
|
||||
@defvrx {Scheme Variable} size_t
|
||||
@defvrx {Scheme Variable} ssize_t
|
||||
@defvrx {Scheme Variable} ptrdiff_t
|
||||
|
@ -813,8 +820,11 @@ tightly packed structs and unions by hand. See the code for
|
|||
Of course, the land of C is not all nouns and no verbs: there are
|
||||
functions too, and Guile allows you to call them.
|
||||
|
||||
@deffn {Scheme Procedure} pointer->procedure return_type func_ptr arg_types
|
||||
@deffnx {C Procedure} scm_pointer_to_procedure (return_type, func_ptr, arg_types)
|
||||
@deffn {Scheme Procedure} pointer->procedure return_type func_ptr arg_types @
|
||||
[#:return-errno?=#f]
|
||||
@deffnx {C Function} scm_pointer_to_procedure (return_type, func_ptr, arg_types)
|
||||
@deffnx {C Function} scm_pointer_to_procedure_with_errno (return_type, func_ptr, arg_types)
|
||||
|
||||
Make a foreign function.
|
||||
|
||||
Given the foreign void pointer @var{func_ptr}, its argument and
|
||||
|
@ -825,6 +835,10 @@ and return appropriate values.
|
|||
@var{arg_types} should be a list of foreign types.
|
||||
@code{return_type} should be a foreign type. @xref{Foreign Types}, for
|
||||
more information on foreign types.
|
||||
|
||||
If @var{return-errno?} is true, or when calling
|
||||
@code{scm_pointer_to_procedure_with_errno}, the returned procedure will
|
||||
return two values, with @code{errno} as the second value.
|
||||
@end deffn
|
||||
|
||||
Here is a better definition of @code{(math bessel)}:
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
@c -*-texinfo-*-
|
||||
@c This is part of the GNU Guile Reference Manual.
|
||||
@c Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004, 2006, 2007, 2009, 2010
|
||||
@c Free Software Foundation, Inc.
|
||||
@c Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004, 2006, 2007,
|
||||
@c 2009, 2010, 2017 Free Software Foundation, Inc.
|
||||
@c See the file guile.texi for copying conditions.
|
||||
|
||||
@node Internationalization
|
||||
|
@ -263,8 +263,10 @@ Reference Manual}).
|
|||
@deffn {Scheme Procedure} number->locale-string number [fraction-digits [locale]]
|
||||
Convert @var{number} (an inexact) into a string according to the
|
||||
cultural conventions of either @var{locale} (a locale object) or the
|
||||
current locale. Optionally, @var{fraction-digits} may be bound to an
|
||||
integer specifying the number of fractional digits to be displayed.
|
||||
current locale. By default, print as many fractional digits as
|
||||
necessary, up to an upper bound. Optionally, @var{fraction-digits} may
|
||||
be bound to an integer specifying the number of fractional digits to be
|
||||
displayed.
|
||||
@end deffn
|
||||
|
||||
@deffn {Scheme Procedure} monetary-amount->locale-string amount intl? [locale]
|
||||
|
|
2776
doc/ref/api-io.texi
2776
doc/ref/api-io.texi
File diff suppressed because it is too large
Load diff
|
@ -138,7 +138,7 @@ only one bit, and so a test for, for example, @code{#f}-or-@code{nil}
|
|||
may be made very efficiently. See @code{libguile/boolean.h}, for more
|
||||
information.
|
||||
|
||||
@subsubsection Equality
|
||||
@subsubheading Equality
|
||||
|
||||
Since Scheme's @code{equal?} must be transitive, and @code{'()}
|
||||
is not @code{equal?} to @code{#f}, to Scheme @code{nil} is not
|
||||
|
@ -229,7 +229,7 @@ Here are correct versions of the above examples:
|
|||
This problem has a mirror-image case in Elisp:
|
||||
|
||||
@example
|
||||
(deffn my-falsep (x)
|
||||
(defun my-falsep (x)
|
||||
(if (eq x nil)
|
||||
t
|
||||
nil))
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
@c -*-texinfo-*-
|
||||
@c This is part of the GNU Guile Reference Manual.
|
||||
@c Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004, 2009, 2010, 2011,
|
||||
@c 2012, 2013, 2014 Free Software Foundation, Inc.
|
||||
@c Copyright (C) 1996, 1997, 2000-2004, 2009-2015
|
||||
@c Free Software Foundation, Inc.
|
||||
@c See the file guile.texi for copying conditions.
|
||||
|
||||
@node Macros
|
||||
|
@ -618,9 +618,9 @@ won't have access to the binding of @code{it}.
|
|||
|
||||
But they can, if we explicitly introduce a binding via @code{datum->syntax}.
|
||||
|
||||
@deffn {Scheme Procedure} datum->syntax for-syntax datum
|
||||
@deffn {Scheme Procedure} datum->syntax template-id datum
|
||||
Create a syntax object that wraps @var{datum}, within the lexical context
|
||||
corresponding to the syntax object @var{for-syntax}.
|
||||
corresponding to the identifier @var{template-id}.
|
||||
@end deffn
|
||||
|
||||
For completeness, we should mention that it is possible to strip the metadata
|
||||
|
@ -791,6 +791,44 @@ Return the source properties that correspond to the syntax object
|
|||
@var{x}. @xref{Source Properties}, for more information.
|
||||
@end deffn
|
||||
|
||||
And now, a bit of confession time. Guile's syntax expander originates
|
||||
in code from Chez Scheme: a version of the expander in Chez Scheme that
|
||||
was made portable to other Scheme systems. Way back in the mid-1990s,
|
||||
some Scheme systems didn't even have the ability to define new abstract
|
||||
data types. For this reason, the portable expander from Chez Scheme
|
||||
that Guile inherited used tagged vectors as syntax objects: vectors
|
||||
whose first element was the symbol, @code{syntax-object}.
|
||||
|
||||
At the time of this writing it is 2017 and Guile still has support for
|
||||
this strategy. It worked for this long because no one ever puts a
|
||||
literal vector in the operator position:
|
||||
|
||||
@example
|
||||
(#(syntax-object ...) 1 2 3)
|
||||
@end example
|
||||
|
||||
But this state of affairs was an error. Because syntax objects are just
|
||||
vectors, this makes it possible for any Scheme code to forge a syntax
|
||||
object which might cause it to violate abstraction boundaries. You
|
||||
can't build a sandboxing facility that limits the set of bindings in
|
||||
scope when one can always escape that limit just by evaluating a special
|
||||
vector. To fix this problem, Guile 2.2.1 finally migrated to represent
|
||||
syntax objects as a distinct type with a distinct constructor that is
|
||||
unavailable to user code.
|
||||
|
||||
However, Guile still has to support ``legacy'' syntax objects, because
|
||||
it could be that a file compiled with Guile 2.2.0 embeds syntax objects
|
||||
of the vector kind. Whether the expander treats the special tagged
|
||||
vectors as syntax objects is now controllable by the
|
||||
@code{allow-legacy-syntax-objects?} parameter:
|
||||
|
||||
@deffn {Scheme Procedure} allow-legacy-syntax-objects?
|
||||
A parameter that indicates whether the expander should support legacy
|
||||
syntax objects, as described above. For ABI stability reasons, the
|
||||
default is @code{#t}. Use @code{parameterize} to bind it to @code{#f}.
|
||||
@xref{Parameters}.
|
||||
@end deffn
|
||||
|
||||
Guile also offers some more experimental interfaces in a separate
|
||||
module. As was the case with the Large Hadron Collider, it is unclear
|
||||
to our senior macrologists whether adding these interfaces will result
|
||||
|
|
|
@ -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, 2009, 2010, 2012, 2013, 2014
|
||||
@c Copyright (C) 1996, 1997, 2000-2004, 2009, 2010, 2012-2016
|
||||
@c Free Software Foundation, Inc.
|
||||
@c See the file guile.texi for copying conditions.
|
||||
|
||||
|
@ -27,24 +27,26 @@ collection relates to using Guile from C.
|
|||
|
||||
@deffn {Scheme Procedure} gc
|
||||
@deffnx {C Function} scm_gc ()
|
||||
Scans all of SCM objects and reclaims for further use those that are
|
||||
no longer accessible. You normally don't need to call this function
|
||||
explicitly. It is called automatically when appropriate.
|
||||
Finds all of the ``live'' @code{SCM} objects and reclaims for further
|
||||
use those that are no longer accessible. You normally don't need to
|
||||
call this function explicitly. Its functionality is invoked
|
||||
automatically as needed.
|
||||
@end deffn
|
||||
|
||||
@deftypefn {C Function} SCM scm_gc_protect_object (SCM @var{obj})
|
||||
Protects @var{obj} from being freed by the garbage collector, when it
|
||||
otherwise might be. When you are done with the object, call
|
||||
@code{scm_gc_unprotect_object} on the object. Calls to
|
||||
@code{scm_gc_protect}/@code{scm_gc_unprotect_object} can be nested, and
|
||||
@code{scm_gc_protect_object}/@code{scm_gc_unprotect_object} can be nested, and
|
||||
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.}.
|
||||
visited by the garbage collector in the mark phase; 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})
|
||||
|
@ -123,16 +125,18 @@ 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.
|
||||
When garbage collection occurs, Guile will visit the words in memory
|
||||
allocated with @code{scm_gc_malloc}, looking 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} visited by the
|
||||
collector in the mark phase. 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 pointers.
|
||||
|
||||
For memory that is not associated with a Scheme object, you can use
|
||||
@code{scm_malloc} instead of @code{malloc}. Like
|
||||
|
@ -193,9 +197,11 @@ 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.
|
||||
When garbage collection occurs, Guile will visit the words in memory
|
||||
allocated with @code{scm_gc_malloc} or @code{scm_gc_calloc}, looking for
|
||||
pointers to other memory allocations that are managed by the GC. In
|
||||
contrast, memory allocated by @code{scm_gc_malloc_pointerless} is not
|
||||
scanned for pointers.
|
||||
|
||||
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
|
||||
|
@ -309,10 +315,18 @@ Return a weak hash table with @var{size} buckets. As with any
|
|||
hash table, choosing a good size for the table requires some
|
||||
caution.
|
||||
|
||||
You can modify weak hash tables in exactly the same way you
|
||||
would modify regular hash tables. (@pxref{Hash Tables})
|
||||
You can modify weak hash tables in exactly the same way you would modify
|
||||
regular hash tables, with the exception of the routines that act on
|
||||
handles. Weak tables have a different implementation behind the scenes
|
||||
that doesn't have handles. @pxref{Hash Tables}, for more on
|
||||
@code{hashq-ref} et al.
|
||||
@end deffn
|
||||
|
||||
Note that in a weak-key hash table, the reference to the value is
|
||||
strong. This means that if the value references the key, even
|
||||
indirectly, the key will never be collected, which can lead to a memory
|
||||
leak. The reverse is true for weak value tables.
|
||||
|
||||
@deffn {Scheme Procedure} weak-key-hash-table? obj
|
||||
@deffnx {Scheme Procedure} weak-value-hash-table? obj
|
||||
@deffnx {Scheme Procedure} doubly-weak-hash-table? obj
|
||||
|
|
|
@ -171,8 +171,8 @@ of @code{@@} and should only be used as a last resort or for
|
|||
debugging, for example.
|
||||
|
||||
Note that just as with a @code{use-modules} statement, any module that
|
||||
has not yet been loaded yet will be loaded when referenced by a
|
||||
@code{@@} or @code{@@@@} form.
|
||||
has not yet been loaded will be loaded when referenced by a @code{@@} or
|
||||
@code{@@@@} form.
|
||||
|
||||
You can also use the @code{@@} and @code{@@@@} syntaxes as the target
|
||||
of a @code{set!} when the binding refers to a variable.
|
||||
|
|
|
@ -241,7 +241,7 @@ procedures (@pxref{Arrays}).
|
|||
|
||||
@item char-ready?
|
||||
Indicates that the @code{char-ready?} function is available
|
||||
(@pxref{Reading}).
|
||||
(@pxref{Venerable Port Interfaces}).
|
||||
|
||||
@item complex
|
||||
Indicates support for complex numbers.
|
||||
|
@ -284,8 +284,11 @@ Indicates support for POSIX functions: @code{pipe}, @code{getgroups},
|
|||
|
||||
@item fork
|
||||
Indicates support for the POSIX @code{fork} function (@pxref{Processes,
|
||||
@code{primitive-fork}}). This is a prerequisite for the @code{(ice-9
|
||||
popen)} module (@pxref{Pipes}).
|
||||
@code{primitive-fork}}).
|
||||
|
||||
@item popen
|
||||
Indicates support for @code{open-pipe} in the @code{(ice-9 popen)}
|
||||
module (@pxref{Pipes}).
|
||||
|
||||
@item random
|
||||
Indicates availability of random number generation functions:
|
||||
|
|
|
@ -836,7 +836,7 @@ Let us call this new procedure @code{foo}.
|
|||
(define foo (make-procedure-with-setter foo-ref foo-set!))
|
||||
@end lisp
|
||||
|
||||
@code{foo} can from now an be used to either read from the data
|
||||
@code{foo} can from now on be used to either read from the data
|
||||
structure stored in @code{f}, or to write into the structure.
|
||||
|
||||
@lisp
|
||||
|
|
|
@ -14,10 +14,7 @@
|
|||
|
||||
A @dfn{regular expression} (or @dfn{regexp}) is a pattern that
|
||||
describes a whole class of strings. A full description of regular
|
||||
expressions and their syntax is beyond the scope of this manual;
|
||||
an introduction can be found in the Emacs manual (@pxref{Regexps,
|
||||
, Syntax of Regular Expressions, emacs, The GNU Emacs Manual}), or
|
||||
in many general Unix reference books.
|
||||
expressions and their syntax is beyond the scope of this manual.
|
||||
|
||||
If your system does not include a POSIX regular expression library,
|
||||
and you have not linked Guile with a third-party regexp library such
|
||||
|
@ -41,10 +38,11 @@ regex))}.
|
|||
@node Regexp Functions
|
||||
@subsection Regexp Functions
|
||||
|
||||
By default, Guile supports POSIX extended regular expressions.
|
||||
That means that the characters @samp{(}, @samp{)}, @samp{+} and
|
||||
@samp{?} are special, and must be escaped if you wish to match the
|
||||
literal characters.
|
||||
By default, Guile supports POSIX extended regular expressions. That
|
||||
means that the characters @samp{(}, @samp{)}, @samp{+} and @samp{?} are
|
||||
special, and must be escaped if you wish to match the literal characters
|
||||
and there is no support for ``non-greedy'' variants of @samp{*},
|
||||
@samp{+} or @samp{?}.
|
||||
|
||||
This regular expression interface was modeled after that
|
||||
implemented by SCSH, the Scheme Shell. It is intended to be
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -612,20 +612,6 @@ Return 1 if @var{x} is a Scheme-level hook, 0 otherwise.
|
|||
@end deftypefn
|
||||
|
||||
|
||||
@subsubsection Handling Scheme-level hooks from C code
|
||||
|
||||
Here is an example of how to handle Scheme-level hooks from C code using
|
||||
the above functions.
|
||||
|
||||
@example
|
||||
if (scm_is_true (scm_hook_p (obj)))
|
||||
/* handle Scheme-level hook using C functions */
|
||||
scm_reset_hook_x (obj);
|
||||
else
|
||||
/* do something else (obj is not a hook) */
|
||||
@end example
|
||||
|
||||
|
||||
@node C Hooks
|
||||
@subsubsection Hooks For C Code.
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
@c -*-texinfo-*-
|
||||
@c This is part of the GNU Guile Reference Manual.
|
||||
@c Copyright (C) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015
|
||||
@c Copyright (C) 2008-2016
|
||||
@c Free Software Foundation, Inc.
|
||||
@c See the file guile.texi for copying conditions.
|
||||
|
||||
|
@ -363,7 +363,7 @@ Sets a variable in the current procedure's module.
|
|||
@end deftp
|
||||
|
||||
@deftp {Scheme Variable} <toplevel-define> src name exp
|
||||
@deftpx {External Representation} (define (toplevel @var{name}) @var{exp})
|
||||
@deftpx {External Representation} (define @var{name} @var{exp})
|
||||
Defines a new top-level variable in the current procedure's module.
|
||||
@end deftp
|
||||
|
||||
|
@ -513,12 +513,8 @@ Optimization passes performed on Tree-IL currently include:
|
|||
and calls to primitives to primcalls)
|
||||
@item Partial evaluation (comprising inlining, copy propagation, and
|
||||
constant folding)
|
||||
@item Common subexpression elimination (CSE)
|
||||
@end itemize
|
||||
|
||||
In the future, we will move the CSE pass to operate over the lower-level
|
||||
CPS language.
|
||||
|
||||
@node Continuation-Passing Style
|
||||
@subsection Continuation-Passing Style
|
||||
|
||||
|
@ -534,6 +530,7 @@ compiler.
|
|||
* An Introduction to CPS::
|
||||
* CPS in Guile::
|
||||
* Building CPS::
|
||||
* CPS Soup::
|
||||
* Compiling CPS::
|
||||
@end menu
|
||||
|
||||
|
@ -624,12 +621,57 @@ details manifest, and gives them names.
|
|||
@node CPS in Guile
|
||||
@subsubsection CPS in Guile
|
||||
|
||||
Guile's CPS language is composed of @dfn{terms}, @dfn{expressions},
|
||||
and @dfn{continuations}.
|
||||
@cindex continuation, CPS
|
||||
Guile's CPS language is composed of @dfn{continuations}. A continuation
|
||||
is a labelled program point. If you are used to traditional compilers,
|
||||
think of a continuation as a trivial basic block. A program is a
|
||||
``soup'' of continuations, represented as a map from labels to
|
||||
continuations.
|
||||
|
||||
A term can either evaluate an expression and pass the resulting values
|
||||
to some continuation, or it can declare local continuations and contain
|
||||
a sub-term in the scope of those continuations.
|
||||
@cindex term, CPS
|
||||
@cindex expression, CPS
|
||||
Like basic blocks, each continuation belongs to only one function. Some
|
||||
continuations are special, like the continuation corresponding to a
|
||||
function's entry point, or the continuation that represents the tail of
|
||||
a function. Others contain a @dfn{term}. A term contains an
|
||||
@dfn{expression}, which evaluates to zero or more values. The term also
|
||||
records the continuation to which it will pass its values. Some terms,
|
||||
like conditional branches, may continue to one of a number of
|
||||
continuations.
|
||||
|
||||
Continuation labels are small integers. This makes it easy to sort them
|
||||
and to group them into sets. Whenever a term refers to a continuation,
|
||||
it does so by name, simply recording the label of the continuation.
|
||||
Continuation labels are unique among the set of labels in a program.
|
||||
|
||||
Variables are also named by small integers. Variable names are unique
|
||||
among the set of variables in a program.
|
||||
|
||||
For example, a simple continuation that receives two values and adds
|
||||
them together can be matched like this, using the @code{match} form from
|
||||
@code{(ice-9 match)}:
|
||||
|
||||
@smallexample
|
||||
(match cont
|
||||
(($ $kargs (x-name y-name) (x-var y-var)
|
||||
($ $continue k src ($ $primcall '+ (x-var y-var))))
|
||||
(format #t "Add ~a and ~a and pass the result to label ~a"
|
||||
x-var y-var k)))
|
||||
@end smallexample
|
||||
|
||||
Here we see the most common kind of continuation, @code{$kargs}, which
|
||||
binds some number of values to variables and then evaluates a term.
|
||||
|
||||
@deftp {CPS Continuation} $kargs names vars term
|
||||
Bind the incoming values to the variables @var{vars}, with original
|
||||
names @var{names}, and then evaluate @var{term}.
|
||||
@end deftp
|
||||
|
||||
The @var{names} of a @code{$kargs} are just for debugging, and will end
|
||||
up residualized in the object file for use by the debugger.
|
||||
|
||||
The @var{term} in a @code{$kargs} is always a @code{$continue}, which
|
||||
evaluates an expression and continues to a continuation.
|
||||
|
||||
@deftp {CPS Term} $continue k src exp
|
||||
Evaluate the expression @var{exp} and pass the resulting values (if any)
|
||||
|
@ -639,44 +681,33 @@ as in @code{source-properties} or is @code{#f} if there is no associated
|
|||
source.
|
||||
@end deftp
|
||||
|
||||
@deftp {CPS Term} $letk conts body
|
||||
Bind @var{conts}, a list of continuations (@code{$cont} instances), in
|
||||
the scope of the sub-term @var{body}. The continuations are mutually
|
||||
recursive.
|
||||
There are a number of expression kinds. Above you see an example of
|
||||
@code{$primcall}.
|
||||
|
||||
@deftp {CPS Expression} $primcall name args
|
||||
Perform the primitive operation identified by @code{name}, a well-known
|
||||
symbol, passing it the arguments @var{args}, and pass all resulting
|
||||
values to the continuation. The set of available primitives includes
|
||||
all primitives known to Tree-IL and then some more; see the source code
|
||||
for details.
|
||||
@end deftp
|
||||
|
||||
Additionally, the early stages of CPS allow for a set of mutually
|
||||
recursive functions to be declared as a term. This @code{$letrec} type
|
||||
is like Tree-IL's @code{<fix>}. The contification pass will attempt to
|
||||
transform the functions declared in a @code{$letrec} into local
|
||||
continuations. Any remaining functions are later lowered to @code{$fun}
|
||||
expressions.
|
||||
|
||||
@deftp {CPS Term} $letrec names syms funs body
|
||||
Declare the mutually recursive set of functions denoted by @var{names},
|
||||
@var{syms}, and @var{funs} within the sub-term @var{body}. @var{names}
|
||||
and @var{syms} are lists of symbols, and @var{funs} is a list of
|
||||
@code{$fun} values. @var{syms} are globally unique.
|
||||
@end deftp
|
||||
|
||||
A higher-order CPS program is a @code{$cont} containing a @code{$kfun}
|
||||
(see below), and the @code{$kfun} which contains clauses and those
|
||||
clauses contain terms. A first-order CPS program, on the other hand, is
|
||||
the result of closure conversion and does not contain nested functions.
|
||||
Closure conversion lifts code for all functions up to the top, collects
|
||||
their entry continuations as a list of @code{$cont} @code{$kfun}
|
||||
instances and binds them in a @code{$program}.
|
||||
|
||||
@deftp {CPS Term} $program funs
|
||||
A first-order CPS term declaring a recursive scope for first-order
|
||||
functions in a compilation unit. @var{funs} is a list of @code{$cont}
|
||||
@code{$kfun} instances. The first entry in the list is the entry
|
||||
function for the program.
|
||||
@end deftp
|
||||
@cindex dominate, CPS
|
||||
The variables that are used by @code{$primcall}, or indeed by any
|
||||
expression, must be defined before the expression is evaluated. An
|
||||
equivalent way of saying this is that predecessor @code{$kargs}
|
||||
continuation(s) that bind the variables(s) used by the expression must
|
||||
@dfn{dominate} the continuation that uses the expression: definitions
|
||||
dominate uses. This condition is trivially satisfied in our example
|
||||
above, but in general to determine the set of variables that are in
|
||||
``scope'' for a given term, you need to do a flow analysis to see what
|
||||
continuations dominate a term. The variables that are in scope are
|
||||
those variables defined by the continuations that dominate a term.
|
||||
|
||||
Here is an inventory of the kinds of expressions in Guile's CPS
|
||||
language. Recall that all expressions are wrapped in a @code{$continue}
|
||||
term which specifies their continuation.
|
||||
language, besides @code{$primcall} which has already been described.
|
||||
Recall that all expressions are wrapped in a @code{$continue} term which
|
||||
specifies their continuation.
|
||||
|
||||
@deftp {CPS Expression} $const val
|
||||
Continue with the constant value @var{val}.
|
||||
|
@ -687,47 +718,11 @@ Continue with the procedure that implements the primitive operation
|
|||
named by @var{name}.
|
||||
@end deftp
|
||||
|
||||
@deftp {CPS Expression} $fun free body
|
||||
Continue with a procedure. @var{free} is a list of free variables
|
||||
accessed by the procedure. Early CPS uses an empty list for @var{free};
|
||||
only after closure conversion is it correctly populated. Finally,
|
||||
@var{body} is the @code{$kfun} @code{$cont} of the procedure entry.
|
||||
@end deftp
|
||||
|
||||
@code{$fun} is part of higher-level CPS. After closure conversion,
|
||||
@code{$fun} instances are given a concrete representation. By default,
|
||||
a closure is represented as an object built by a @code{$closure}
|
||||
expression
|
||||
|
||||
@deftp {CPS Expression} $closure label nfree
|
||||
Build a closure that joins the code at the continuation named
|
||||
@var{label} with space for @var{nfree} free variables. The variables
|
||||
will be initialized later via @code{free-variable-set!} primcalls.
|
||||
@end deftp
|
||||
|
||||
If the closure can be proven to never escape its scope then other
|
||||
lighter-weight representations can be chosen.
|
||||
|
||||
@deftp {CPS Expression} $call proc args
|
||||
@deftpx {CPS Expression} $callk label proc args
|
||||
Call @var{proc} with the arguments @var{args}, and pass all values to
|
||||
the continuation. @var{proc} and the elements of the @var{args} list
|
||||
should all be variable names. The continuation identified by the term's
|
||||
@var{k} should be a @code{$kreceive} or a @code{$ktail} instance.
|
||||
|
||||
@code{$callk} is for the case where the call target is known to be in
|
||||
the same compilation unit. @var{label} should be some continuation
|
||||
label, though it need not be in scope. In this case the @var{proc} is
|
||||
simply an additional argument, since it is not used to determine the
|
||||
call target at run-time.
|
||||
@end deftp
|
||||
|
||||
@deftp {CPS Expression} $primcall name args
|
||||
Perform the primitive operation identified by @code{name}, a well-known
|
||||
symbol, passing it the arguments @var{args}, and pass all resulting
|
||||
values to the continuation. The set of available primitives includes
|
||||
all primitives known to Tree-IL and then some more; see the source code
|
||||
for details.
|
||||
@end deftp
|
||||
|
||||
@deftp {CPS Expression} $values args
|
||||
|
@ -736,7 +731,8 @@ Pass the values named by the list @var{args} to the continuation.
|
|||
|
||||
@deftp {CPS Expression} $branch kt exp
|
||||
Evaluate the branching expression @var{exp}, and continue to @var{kt}
|
||||
with zero values if the test evaluates to true. Otherwise, in the false
|
||||
with zero values if the test evaluates to true. Otherwise continue to
|
||||
the continuation named in the outer @code{$continue} term.
|
||||
|
||||
Only certain expressions are valid in a @var{$branch}. Compiling a
|
||||
@code{$branch} avoids allocating space for the test variable, so the
|
||||
|
@ -744,9 +740,9 @@ expression should be evaluatable without temporary values. In practice
|
|||
this condition is true for @code{$primcall}s to @code{null?}, @code{=},
|
||||
and similar primitives that have corresponding @code{br-if-@var{foo}} VM
|
||||
operations; see the source code for full details. When in doubt, bind
|
||||
the test expression to a variable, and reference the variable in the
|
||||
@code{$branch} expression. The optimizer should inline the reference if
|
||||
possible.
|
||||
the test expression to a variable, and branch on a @code{$values}
|
||||
expression that references that variable. The optimizer should inline
|
||||
the reference if possible.
|
||||
@end deftp
|
||||
|
||||
@deftp {CPS Expression} $prompt escape? tag handler
|
||||
|
@ -758,30 +754,73 @@ the continuation labelled @var{handler}, which should be a
|
|||
@code{pop-prompt} primcalls.
|
||||
@end deftp
|
||||
|
||||
The remaining element of the CPS language in Guile is the continuation.
|
||||
In CPS, all continuations have unique labels. Since this aspect is
|
||||
common to all continuation types, all continuations are contained in a
|
||||
@code{$cont} instance:
|
||||
@cindex higher-order CPS
|
||||
@cindex CPS, higher-order
|
||||
@cindex first-order CPS
|
||||
@cindex CPS, first-order
|
||||
There are two sub-languages of CPS, @dfn{higher-order CPS} and
|
||||
@dfn{first-order CPS}. The difference is that in higher-order CPS,
|
||||
there are @code{$fun} and @code{$rec} expressions that bind functions or
|
||||
mutually-recursive functions in the implicit scope of their use sites.
|
||||
Guile transforms higher-order CPS into first-order CPS by @dfn{closure
|
||||
conversion}, which chooses representations for all closures and which
|
||||
arranges to access free variables through the implicit closure parameter
|
||||
that is passed to every function call.
|
||||
|
||||
@deftp {CPS Continuation Wrapper} $cont k cont
|
||||
Declare a continuation labelled @var{k}. All references to the
|
||||
continuation will use this label.
|
||||
@deftp {CPS Expression} $fun body
|
||||
Continue with a procedure. @var{body} names the entry point of the
|
||||
function, which should be a @code{$kfun}. This expression kind is only
|
||||
valid in higher-order CPS, which is the CPS language before closure
|
||||
conversion.
|
||||
@end deftp
|
||||
|
||||
The most common kind of continuation binds some number of values, and
|
||||
then evaluates a sub-term. @code{$kargs} is this kind of simple
|
||||
@code{lambda}.
|
||||
|
||||
@deftp {CPS Continuation} $kargs names syms body
|
||||
Bind the incoming values to the variables @var{syms}, with original
|
||||
names @var{names}, and then evaluate the sub-term @var{body}.
|
||||
@deftp {CPS Expression} $rec names vars funs
|
||||
Continue with a set of mutually recursive procedures denoted by
|
||||
@var{names}, @var{vars}, and @var{funs}. @var{names} is a list of
|
||||
symbols, @var{vars} is a list of variable names (unique integers), and
|
||||
@var{funs} is a list of @code{$fun} values. Note that the @code{$kargs}
|
||||
continuation should also define @var{names}/@var{vars} bindings.
|
||||
@end deftp
|
||||
|
||||
Variable names (the names in the @var{syms} of a @code{$kargs}) should
|
||||
be unique among all other variable names. To bind a value to a variable
|
||||
and then evaluate some term, you would continue with the value to a
|
||||
@code{$kargs} that declares one variable. The bound value would then be
|
||||
available for use within the body of the @code{$kargs}.
|
||||
The contification pass will attempt to transform the functions declared
|
||||
in a @code{$rec} into local continuations. Any remaining @code{$fun}
|
||||
instances are later removed by the closure conversion pass. By default,
|
||||
a closure is represented as an object built by a @code{$closure}
|
||||
expression.
|
||||
|
||||
@deftp {CPS Expression} $closure label nfree
|
||||
Build a closure that joins the code at the continuation named
|
||||
@var{label} with space for @var{nfree} free variables. The variables
|
||||
will be initialized later via @code{free-set!} primcalls. This
|
||||
expression kind is part of first-order CPS.
|
||||
@end deftp
|
||||
|
||||
If the closure can be proven to never escape its scope then other
|
||||
lighter-weight representations can be chosen. Additionally, if all call
|
||||
sites are known, closure conversion will hard-wire the calls by lowering
|
||||
@code{$call} to @code{$callk}.
|
||||
|
||||
@deftp {CPS Expression} $callk label proc args
|
||||
Like @code{$call}, but for the case where the call target is known to be
|
||||
in the same compilation unit. @var{label} should denote some
|
||||
@code{$kfun} continuation in the program. In this case the @var{proc}
|
||||
is simply an additional argument, since it is not used to determine the
|
||||
call target at run-time.
|
||||
@end deftp
|
||||
|
||||
At this point we have described terms, expressions, and the most common
|
||||
kind of continuation, @code{$kargs}. @code{$kargs} is used when the
|
||||
predecessors of the continuation can be instructed to pass the values
|
||||
where the continuation wants them. For example, if a @code{$kargs}
|
||||
continuation @var{k} binds a variable @var{v}, and the compiler decides
|
||||
to allocate @var{v} to slot 6, all predecessors of @var{k} should put
|
||||
the value for @var{v} in slot 6 before jumping to @var{k}. One
|
||||
situation in which this isn't possible is receiving values from function
|
||||
calls. Guile has a calling convention for functions which currently
|
||||
places return values on the stack. A continuation of a call must check
|
||||
that the number of values returned from a function matches the expected
|
||||
number of values, and then must shuffle or collect those values to named
|
||||
variables. @code{$kreceive} denotes this kind of continuation.
|
||||
|
||||
@deftp {CPS Continuation} $kreceive arity k
|
||||
Receive values on the stack. Parse them according to @var{arity}, and
|
||||
|
@ -806,18 +845,18 @@ Note that all of these names with the exception of the @var{var}s in the
|
|||
@var{kw} list are source names, not unique variable names.
|
||||
@end deftp
|
||||
|
||||
Additionally, there are three specific kinds of continuations that can
|
||||
only be declared at function entries.
|
||||
Additionally, there are three specific kinds of continuations that are
|
||||
only used in function entries.
|
||||
|
||||
@deftp {CPS Continuation} $kfun src meta self tail clauses
|
||||
Declare a function entry. @var{src} is the source information for the
|
||||
procedure declaration, and @var{meta} is the metadata alist as described
|
||||
above in Tree-IL's @code{<lambda>}. @var{self} is a variable bound to
|
||||
the procedure being called, and which may be used for self-references.
|
||||
@var{tail} declares the @code{$cont} wrapping the @code{$ktail} for this
|
||||
function, corresponding to the function's tail continuation.
|
||||
@var{clause} is the first @code{$kclause} @code{$cont} instance for the
|
||||
first @code{case-lambda} clause in the function, or otherwise @code{#f}.
|
||||
@var{tail} is the label of the @code{$ktail} for this function,
|
||||
corresponding to the function's tail continuation. @var{clause} is the
|
||||
label of the first @code{$kclause} for the first @code{case-lambda}
|
||||
clause in the function, or otherwise @code{#f}.
|
||||
@end deftp
|
||||
|
||||
@deftp {CPS Continuation} $ktail
|
||||
|
@ -826,10 +865,10 @@ A tail continuation.
|
|||
|
||||
@deftp {CPS Continuation} $kclause arity cont alternate
|
||||
A clause of a function with a given arity. Applications of a function
|
||||
with a compatible set of actual arguments will continue to @var{cont}, a
|
||||
@code{$kargs} @code{$cont} instance representing the clause body. If
|
||||
the arguments are incompatible, control proceeds to @var{alternate},
|
||||
which is a @code{$kclause} @code{$cont} for the next clause, or
|
||||
with a compatible set of actual arguments will continue to the
|
||||
continuation labelled @var{cont}, a @code{$kargs} instance representing
|
||||
the clause body. If the arguments are incompatible, control proceeds to
|
||||
@var{alternate}, which is a @code{$kclause} for the next clause, or
|
||||
@code{#f} if there is no next clause.
|
||||
@end deftp
|
||||
|
||||
|
@ -842,41 +881,41 @@ constructors or accessors, or instead of S-expression matching.
|
|||
|
||||
Deconstruction and matching is handled adequately by the @code{match}
|
||||
form from @code{(ice-9 match)}. @xref{Pattern Matching}. Construction
|
||||
is handled by a set of mutually recursive builder macros:
|
||||
@code{build-cps-term}, @code{build-cps-cont}, and @code{build-cps-exp}.
|
||||
is handled by a set of mutually builder macros:
|
||||
@code{build-term}, @code{build-cont}, and @code{build-exp}.
|
||||
|
||||
In the following interface definitions, consider variables containing
|
||||
@code{cont} to be recursively build by @code{build-cps-cont}, and
|
||||
likewise for @code{term} and @code{exp}. Consider any other name to be
|
||||
evaluated as a Scheme expression. Many of these forms recognize
|
||||
@code{unquote} in some contexts, to splice in a previously-built value;
|
||||
see the specifications below for full details.
|
||||
In the following interface definitions, consider @code{term} and
|
||||
@code{exp} to be built by @code{build-term} or @code{build-exp},
|
||||
respectively. Consider any other name to be evaluated as a Scheme
|
||||
expression. Many of these forms recognize @code{unquote} in some
|
||||
contexts, to splice in a previously-built value; see the specifications
|
||||
below for full details.
|
||||
|
||||
@deffn {Scheme Syntax} build-cps-term ,val
|
||||
@deffnx {Scheme Syntax} build-cps-term ($letk (cont ...) term)
|
||||
@deffnx {Scheme Syntax} build-cps-term ($letrec names syms funs term)
|
||||
@deffnx {Scheme Syntax} build-cps-term ($continue k src exp)
|
||||
@deffnx {Scheme Syntax} build-cps-term ($program conts)
|
||||
@deffnx {Scheme Syntax} build-cps-exp ,val
|
||||
@deffnx {Scheme Syntax} build-cps-exp ($const val)
|
||||
@deffnx {Scheme Syntax} build-cps-exp ($prim name)
|
||||
@deffnx {Scheme Syntax} build-cps-exp ($fun src meta free body)
|
||||
@deffnx {Scheme Syntax} build-cps-exp ($call proc (arg ...))
|
||||
@deffnx {Scheme Syntax} build-cps-exp ($call proc args)
|
||||
@deffnx {Scheme Syntax} build-cps-exp ($primcall name (arg ...))
|
||||
@deffnx {Scheme Syntax} build-cps-exp ($primcall name args)
|
||||
@deffnx {Scheme Syntax} build-cps-exp ($values (arg ...))
|
||||
@deffnx {Scheme Syntax} build-cps-exp ($values args)
|
||||
@deffnx {Scheme Syntax} build-cps-exp ($prompt escape? tag handler)
|
||||
@deffnx {Scheme Syntax} build-cps-cont ,val
|
||||
@deffnx {Scheme Syntax} build-cps-cont (k ($kargs (name ...) (sym ...) term))
|
||||
@deffnx {Scheme Syntax} build-cps-cont (k ($kargs names syms term))
|
||||
@deffnx {Scheme Syntax} build-cps-cont (k ($kif kt kf))
|
||||
@deffnx {Scheme Syntax} build-cps-cont (k ($kreceive req rest kargs))
|
||||
@deffnx {Scheme Syntax} build-cps-cont (k ($kentry self tail-cont ,clauses))
|
||||
@deffnx {Scheme Syntax} build-cps-cont (k ($kentry self tail-cont (cont ...)))
|
||||
@deffnx {Scheme Syntax} build-cps-cont (k ($kclause ,arity cont))
|
||||
@deffnx {Scheme Syntax} build-cps-cont (k ($kclause (req opt rest kw aok?) cont))
|
||||
@deffn {Scheme Syntax} build-term ,val
|
||||
@deffnx {Scheme Syntax} build-term ($continue k src exp)
|
||||
@deffnx {Scheme Syntax} build-exp ,val
|
||||
@deffnx {Scheme Syntax} build-exp ($const val)
|
||||
@deffnx {Scheme Syntax} build-exp ($prim name)
|
||||
@deffnx {Scheme Syntax} build-exp ($branch kt exp)
|
||||
@deffnx {Scheme Syntax} build-exp ($fun kentry)
|
||||
@deffnx {Scheme Syntax} build-exp ($rec names syms funs)
|
||||
@deffnx {Scheme Syntax} build-exp ($closure k nfree)
|
||||
@deffnx {Scheme Syntax} build-exp ($call proc (arg ...))
|
||||
@deffnx {Scheme Syntax} build-exp ($call proc args)
|
||||
@deffnx {Scheme Syntax} build-exp ($callk k proc (arg ...))
|
||||
@deffnx {Scheme Syntax} build-exp ($callk k proc args)
|
||||
@deffnx {Scheme Syntax} build-exp ($primcall name (arg ...))
|
||||
@deffnx {Scheme Syntax} build-exp ($primcall name args)
|
||||
@deffnx {Scheme Syntax} build-exp ($values (arg ...))
|
||||
@deffnx {Scheme Syntax} build-exp ($values args)
|
||||
@deffnx {Scheme Syntax} build-exp ($prompt escape? tag handler)
|
||||
@deffnx {Scheme Syntax} build-cont ,val
|
||||
@deffnx {Scheme Syntax} build-cont ($kargs (name ...) (sym ...) term)
|
||||
@deffnx {Scheme Syntax} build-cont ($kargs names syms term)
|
||||
@deffnx {Scheme Syntax} build-cont ($kreceive req rest kargs)
|
||||
@deffnx {Scheme Syntax} build-cont ($kfun src meta self ktail kclause)
|
||||
@deffnx {Scheme Syntax} build-cont ($kclause ,arity kbody kalt)
|
||||
@deffnx {Scheme Syntax} build-cont ($kclause (req opt rest kw aok?) kbody)
|
||||
Construct a CPS term, expression, or continuation.
|
||||
@end deffn
|
||||
|
||||
|
@ -886,19 +925,187 @@ There are a few more miscellaneous interfaces as well.
|
|||
A procedural constructor for @code{$arity} objects.
|
||||
@end deffn
|
||||
|
||||
@deffn {Scheme Syntax} let-gensyms (sym ...) body ...
|
||||
Bind @var{sym...} to fresh names, and evaluate @var{body...}.
|
||||
@end deffn
|
||||
|
||||
@deffn {Scheme Syntax} rewrite-cps-term val (pat term) ...
|
||||
@deffnx {Scheme Syntax} rewrite-cps-exp val (pat exp) ...
|
||||
@deffnx {Scheme Syntax} rewrite-cps-cont val (pat cont) ...
|
||||
@deffn {Scheme Syntax} rewrite-term val (pat term) ...
|
||||
@deffnx {Scheme Syntax} rewrite-exp val (pat exp) ...
|
||||
@deffnx {Scheme Syntax} rewrite-cont val (pat cont) ...
|
||||
Match @var{val} against the series of patterns @var{pat...}, using
|
||||
@code{match}. The body of the matching clause should be a template in
|
||||
the syntax of @code{build-cps-term}, @code{build-cps-exp}, or
|
||||
@code{build-cps-cont}, respectively.
|
||||
the syntax of @code{build-term}, @code{build-exp}, or @code{build-cont},
|
||||
respectively.
|
||||
@end deffn
|
||||
|
||||
@node CPS Soup
|
||||
@subsubsection CPS Soup
|
||||
|
||||
We describe programs in Guile's CPS language as being a kind of ``soup''
|
||||
because all continuations in the program are mixed into the same
|
||||
``pot'', so to speak, without explicit markers as to what function or
|
||||
scope a continuation is in. A program in CPS is a map from continuation
|
||||
labels to continuation values. As discussed in the introduction, a
|
||||
continuation label is an integer. No label may be negative.
|
||||
|
||||
As a matter of convention, label 0 should map to the @code{$kfun}
|
||||
continuation of the entry to the program, which should be a function of
|
||||
no arguments. The body of a function consists of the labelled
|
||||
continuations that are reachable from the function entry. A program can
|
||||
refer to other functions, either via @code{$fun} and @code{$rec} in
|
||||
higher-order CPS, or via @code{$closure} and @code{$callk} in
|
||||
first-order CPS. The program logically contains all continuations of
|
||||
all functions reachable from the entry function. A compiler pass may
|
||||
leave unreachable continuations in a program; subsequent compiler passes
|
||||
should ensure that their transformations and analyses only take
|
||||
reachable continuations into account. It's OK though if transformation
|
||||
runs over all continuations if including the unreachable continuations
|
||||
has no effect on the transformations on the live continuations.
|
||||
|
||||
@cindex intmap
|
||||
The ``soup'' itself is implemented as an @dfn{intmap}, a functional
|
||||
array-mapped trie specialized for integer keys. Intmaps associate
|
||||
integers with values of any kind. Currently intmaps are a private data
|
||||
structure only used by the CPS phase of the compiler. To work with
|
||||
intmaps, load the @code{(language cps intmap)} module:
|
||||
|
||||
@example
|
||||
(use-modules (language cps intmap))
|
||||
@end example
|
||||
|
||||
Intmaps are functional data structures, so there is no constructor as
|
||||
such: one can simply start with the empty intmap and add entries to it.
|
||||
|
||||
@example
|
||||
(intmap? empty-intmap) @result{} #t
|
||||
(define x (intmap-add empty-intmap 42 "hi"))
|
||||
(intmap? x) @result{} #t
|
||||
(intmap-ref x 42) @result{} "hi"
|
||||
(intmap-ref x 43) @result{} @i{error: 43 not present}
|
||||
(intmap-ref x 43 (lambda (k) "yo!")) @result{} "yo"
|
||||
(intmap-add x 42 "hej") @result{} @i{error: 42 already present}
|
||||
@end example
|
||||
|
||||
@code{intmap-ref} and @code{intmap-add} are the core of the intmap
|
||||
interface. There is also @code{intmap-replace}, which replaces the
|
||||
value associated with a given key, requiring that the key was present
|
||||
already, and @code{intmap-remove}, which removes a key from an intmap.
|
||||
|
||||
Intmaps have a tree-like structure that is well-suited to set operations
|
||||
such as union and intersection, so there is are also the binary
|
||||
@code{intmap-union} and @code{intmap-intersect} procedures. If the
|
||||
result is equivalent to either argument, that argument is returned
|
||||
as-is; in that way, one can detect whether the set operation produced a
|
||||
new result simply by checking with @code{eq?}. This makes intmaps
|
||||
useful when computing fixed points.
|
||||
|
||||
If a key is present in both intmaps and the associated values are not
|
||||
the same in the sense of @code{eq?}, the resulting value is determined
|
||||
by a ``meet'' procedure, which is the optional last argument to
|
||||
@code{intmap-union}, @code{intmap-intersect}, and also to
|
||||
@code{intmap-add}, @code{intmap-replace}, and similar functions. The
|
||||
meet procedure will be called with the two values and should return the
|
||||
intersected or unioned value in some domain-specific way. If no meet
|
||||
procedure is given, the default meet procedure will raise an error.
|
||||
|
||||
To traverse over the set of values in an intmap, there are the
|
||||
@code{intmap-next} and @code{intmap-prev} procedures. For example, if
|
||||
intmap @var{x} has one entry mapping 42 to some value, we would have:
|
||||
|
||||
@example
|
||||
(intmap-next x) @result{} 42
|
||||
(intmap-next x 0) @result{} 42
|
||||
(intmap-next x 42) @result{} 42
|
||||
(intmap-next x 43) @result{} #f
|
||||
(intmap-prev x) @result{} 42
|
||||
(intmap-prev x 42) @result{} 42
|
||||
(intmap-prev x 41) @result{} #f
|
||||
@end example
|
||||
|
||||
There is also the @code{intmap-fold} procedure, which folds over keys
|
||||
and values in the intmap from lowest to highest value, and
|
||||
@code{intmap-fold-right} which does so in the opposite direction. These
|
||||
procedures may take up to 3 seed values. The number of values that the
|
||||
fold procedure returns is the number of seed values.
|
||||
|
||||
@example
|
||||
(define q (intmap-add (intmap-add empty-intmap 1 2) 3 4))
|
||||
(intmap-fold acons q '()) @result{} ((3 . 4) (1 . 2))
|
||||
(intmap-fold-right acons q '()) @result{} ((1 . 2) (3 . 4))
|
||||
@end example
|
||||
|
||||
When an entry in an intmap is updated (removed, added, or changed), a
|
||||
new intmap is created that shares structure with the original intmap.
|
||||
This operation ensures that the result of existing computations is not
|
||||
affected by future computations: no mutation is ever visible to user
|
||||
code. This is a great property in a compiler data structure, as it lets
|
||||
us hold a copy of a program before a transformation and use it while we
|
||||
build a post-transformation program. Updating an intmap is O(log
|
||||
@var{n}) in the size of the intmap.
|
||||
|
||||
However, the O(log @var{n}) allocation costs are sometimes too much,
|
||||
especially in cases when we know that we can just update the intmap in
|
||||
place. As an example, say we have an intmap mapping the integers 1 to
|
||||
100 to the integers 42 to 141. Let's say that we want to transform this
|
||||
map by adding 1 to each value. There is already an efficient
|
||||
@code{intmap-map} procedure in the @code{(language cps utils}) module,
|
||||
but if we didn't know about that we might do:
|
||||
|
||||
@example
|
||||
(define (intmap-increment map)
|
||||
(let lp ((k 0) (map map))
|
||||
(let ((k (intmap-next map k)))
|
||||
(if k
|
||||
(let ((v (intmap-ref map k)))
|
||||
(lp (1+ k) (intmap-replace map k (1+ v))))
|
||||
map))))
|
||||
@end example
|
||||
|
||||
@cindex intmap, transient
|
||||
@cindex transient intmaps
|
||||
Observe that the intermediate values created by @code{intmap-replace}
|
||||
are completely invisible to the program -- only the last result of
|
||||
@code{intmap-replace} value is needed. The rest might as well share
|
||||
state with the last one, and we could update in place. Guile allows
|
||||
this kind of interface via @dfn{transient intmaps}, inspired by
|
||||
Clojure's transient interface (@uref{http://clojure.org/transients}).
|
||||
|
||||
The in-place @code{intmap-add!} and @code{intmap-replace!} procedures
|
||||
return transient intmaps. If one of these in-place procedures is called
|
||||
on a normal persistent intmap, a new transient intmap is created. This
|
||||
is an O(1) operation. In all other respects the interface is like their
|
||||
persistent counterparts, @code{intmap-add} and @code{intmap-replace}.
|
||||
If an in-place procedure is called on a transient intmap, the intmap is
|
||||
mutated in-place and the same value is returned.
|
||||
|
||||
If a persistent operation like @code{intmap-add} is called on a
|
||||
transient intmap, the transient's mutable substructure is then marked as
|
||||
persistent, and @code{intmap-add} then runs on a new persistent intmap
|
||||
sharing structure but not state with the original transient. Mutating a
|
||||
transient will cause enough copying to ensure that it can make its
|
||||
change, but if part of its substructure is already ``owned'' by it, no
|
||||
more copying is needed.
|
||||
|
||||
We can use transients to make @code{intmap-increment} more efficient.
|
||||
The two changed elements have been marked @strong{like this}.
|
||||
|
||||
@example
|
||||
(define (intmap-increment map)
|
||||
(let lp ((k 0) (map map))
|
||||
(let ((k (intmap-next map k)))
|
||||
(if k
|
||||
(let ((v (intmap-ref map k)))
|
||||
(lp (1+ k) (@strong{intmap-replace!} map k (1+ v))))
|
||||
(@strong{persistent-intmap} map)))))
|
||||
@end example
|
||||
|
||||
Be sure to tag the result as persistent using the
|
||||
@code{persistent-intmap} procedure to prevent the mutability from
|
||||
leaking to other parts of the program. For added paranoia, you could
|
||||
call @code{persistent-intmap} on the incoming map, to ensure that if it
|
||||
were already transient, that the mutations in the body of
|
||||
@code{intmap-increment} wouldn't affect the incoming value.
|
||||
|
||||
In summary, programs in CPS are intmaps whose values are continuations.
|
||||
See the source code of @code{(language cps utils)} for a number of
|
||||
useful facilities for working with CPS values.
|
||||
|
||||
@node Compiling CPS
|
||||
@subsubsection Compiling CPS
|
||||
|
||||
|
@ -915,16 +1122,18 @@ variables (in Tree-IL, locals that are @code{<lexical-set>}) are
|
|||
converted to being boxed values on the heap. @xref{Variables and the
|
||||
VM}.
|
||||
|
||||
After CPS conversion, Guile runs some optimization passes. The major
|
||||
optimization performed on CPS is contification, in which functions that
|
||||
are always called with the same continuation are incorporated directly
|
||||
into a function's body. This opens up space for more optimizations, and
|
||||
turns procedure calls into @code{goto}. It can also make loops out of
|
||||
recursive function nests.
|
||||
After CPS conversion, Guile runs some optimization passes over the CPS.
|
||||
Most optimization in Guile is done on the CPS language. The one major
|
||||
exception is partial evaluation, which for historic reasons is done on
|
||||
Tree-IL.
|
||||
|
||||
At the time of this writing (2014), most high-level optimization in
|
||||
Guile is done on Tree-IL. We would like to rewrite many of these passes
|
||||
to operate on CPS instead, as it is easier to reason about CPS.
|
||||
The major optimization performed on CPS is contification, in which
|
||||
functions that are always called with the same continuation are
|
||||
incorporated directly into a function's body. This opens up space for
|
||||
more optimizations, and turns procedure calls into @code{goto}. It can
|
||||
also make loops out of recursive function nests. Guile also does dead
|
||||
code elimination, common subexpression elimination, loop peeling and
|
||||
invariant code motion, and range and type inference.
|
||||
|
||||
The rest of the optimization passes are really cleanups and
|
||||
canonicalizations. CPS spans the gap between high-level languages and
|
||||
|
|
|
@ -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, 2010
|
||||
@c Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004, 2010, 2015
|
||||
@c Free Software Foundation, Inc.
|
||||
@c See the file guile.texi for copying conditions.
|
||||
|
||||
|
@ -339,7 +339,7 @@ actually garbage, and should be freed. In practice, this is not a
|
|||
problem. The alternative, an explicitly maintained list of local
|
||||
variable addresses, is effectively much less reliable, due to programmer
|
||||
error. Interested readers should see the BDW-GC web page at
|
||||
@uref{http://www.hpl.hp.com/personal/Hans_Boehm/gc}, for more
|
||||
@uref{http://www.hboehm.info/gc/}, for more
|
||||
information.
|
||||
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
@c -*-texinfo-*-
|
||||
@c This is part of the GNU Guile Reference Manual.
|
||||
@c Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004, 2005, 2010, 2011, 2013, 2014
|
||||
@c Free Software Foundation, Inc.
|
||||
@c Copyright (C) 1996, 1997, 2000-2005, 2010, 2011, 2013, 2014,
|
||||
@c 2016 Free Software Foundation, Inc.
|
||||
@c See the file guile.texi for copying conditions.
|
||||
|
||||
@node Invoking Guile
|
||||
|
@ -102,14 +102,10 @@ that is defined in the script. It can also be of the form @code{(@@
|
|||
@var{module-name} @var{symbol})}, and in that case, the symbol is
|
||||
looked up in the module named @var{module-name}.
|
||||
|
||||
For compatibility with some versions of Guile 1.4, you can also use the
|
||||
form @code{(symbol ...)} (that is, a list of only symbols that doesn't
|
||||
start with @code{@@}), which is equivalent to @code{(@@ (symbol ...)
|
||||
main)}, or @code{(symbol ...) symbol} (that is, a list of only symbols
|
||||
followed by a symbol), which is equivalent to @code{(@@ (symbol ...)
|
||||
symbol)}. We recommend to use the equivalent forms directly since they
|
||||
correspond to the @code{(@@ ...)} read syntax that can be used in
|
||||
normal code. See @ref{Using Guile Modules} and @ref{Scripting
|
||||
As a shorthand you can use the form @code{(symbol ...)}, that is, a list
|
||||
of only symbols that doesn't start with @code{@@}. It is equivalent to
|
||||
@code{(@@ @var{module-name} main)}, where @var{module-name} is
|
||||
@code{(symbol ...)} form. @xref{Using Guile Modules} and @ref{Scripting
|
||||
Examples}.
|
||||
|
||||
@item -ds
|
||||
|
@ -176,7 +172,7 @@ the @file{.guile} file. @xref{Init File}.
|
|||
While this program runs, listen on a local port or a path for REPL
|
||||
clients. If @var{p} starts with a number, it is assumed to be a local
|
||||
port on which to listen. If it starts with a forward slash, it is
|
||||
assumed to be a path to a UNIX domain socket on which to listen.
|
||||
assumed to be the file name of a UNIX domain socket on which to listen.
|
||||
|
||||
If @var{p} is not given, the default is local port 37146. If you look
|
||||
at it upside down, it almost spells ``Guile''. If you have netcat
|
||||
|
@ -184,12 +180,22 @@ installed, you should be able to @kbd{nc localhost 37146} and get a
|
|||
Guile prompt. Alternately you can fire up Emacs and connect to the
|
||||
process; see @ref{Using Guile in Emacs} for more details.
|
||||
|
||||
Note that opening a port allows anyone who can connect to that port---in
|
||||
the TCP case, any local user---to do anything Guile can do, as the user
|
||||
@quotation Note
|
||||
Opening a port allows anyone who can connect to that port to do anything
|
||||
Guile can do, as the user
|
||||
that the Guile process is running as. Do not use @option{--listen} on
|
||||
multi-user machines. Of course, if you do not pass @option{--listen} to
|
||||
Guile, no port will be opened.
|
||||
|
||||
Guile protects against the
|
||||
@uref{https://en.wikipedia.org/wiki/Inter-protocol_exploitation,
|
||||
@dfn{HTTP inter-protocol exploitation attack}}, a scenario whereby an
|
||||
attacker can, @i{via} an HTML page, cause a web browser to send data to
|
||||
TCP servers listening on a loopback interface or private network.
|
||||
Nevertheless, you are advised to use UNIX domain sockets, as in
|
||||
@code{--listen=/some/local/file}, whenever possible.
|
||||
@end quotation
|
||||
|
||||
That said, @option{--listen} is great for interactive debugging and
|
||||
development.
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
This manual documents Guile version @value{VERSION}.
|
||||
|
||||
Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004, 2005, 2009,
|
||||
2010, 2011, 2012, 2013, 2014 Free Software Foundation.
|
||||
2010, 2011, 2012, 2013, 2014, 2015, 2016 Free Software Foundation.
|
||||
|
||||
Permission is granted to copy, distribute and/or modify this document
|
||||
under the terms of the GNU Free Documentation License, Version 1.3 or
|
||||
|
@ -297,8 +297,7 @@ available through both Scheme and C interfaces.
|
|||
* The SCM Type:: The fundamental data type for C code.
|
||||
* Initialization:: Initializing Guile.
|
||||
* Snarfing Macros:: Macros for snarfing initialization actions.
|
||||
* Simple Data Types:: Numbers, strings, booleans and so on.
|
||||
* Compound Data Types:: Data types for holding other data.
|
||||
* Data Types:: Representing values in Guile.
|
||||
* Foreign Objects:: Defining new data types in C.
|
||||
* Smobs:: Use foreign objects instead.
|
||||
* Procedures:: Procedures.
|
||||
|
@ -328,7 +327,6 @@ available through both Scheme and C interfaces.
|
|||
@include api-init.texi
|
||||
@include api-snarf.texi
|
||||
@include api-data.texi
|
||||
@include api-compound.texi
|
||||
@include api-foreign-objects.texi
|
||||
@include api-smobs.texi
|
||||
@include api-procedures.texi
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
@c -*-texinfo-*-
|
||||
@c This is part of the GNU Guile Reference Manual.
|
||||
@c Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004, 2005, 2010,
|
||||
@c 2011, 2013, 2014 Free Software Foundation, Inc.
|
||||
@c Copyright (C) 1996-1997, 2000-2005, 2010-2011, 2013-2016
|
||||
@c Free Software Foundation, Inc.
|
||||
@c See the file guile.texi for copying conditions.
|
||||
|
||||
@node General Libguile Concepts
|
||||
|
@ -197,28 +197,44 @@ sections, function arguments or local variables on the C and Scheme
|
|||
stacks, and values in machine registers. Other references to @code{SCM}
|
||||
objects, such as those in other random data structures in the C heap
|
||||
that contain fields of type @code{SCM}, can be made visible to the
|
||||
garbage collector by calling the functions @code{scm_gc_protect} or
|
||||
garbage collector by calling the functions @code{scm_gc_protect_object} or
|
||||
@code{scm_permanent_object}. Collectively, these values form the ``root
|
||||
set'' of garbage collection; any value on the heap that is referenced
|
||||
directly or indirectly by a member of the root set is preserved, and all
|
||||
other objects are eligible for reclamation.
|
||||
|
||||
The Scheme stack and heap are scanned precisely; that is to say, Guile
|
||||
knows about all inter-object pointers on the Scheme stack and heap.
|
||||
This is not the case, unfortunately, for pointers on the C stack and
|
||||
static data segment. For this reason we have to scan the C stack and
|
||||
static data segment @dfn{conservatively}; any value that looks like a
|
||||
pointer to a GC-managed object is treated as such, whether it actually
|
||||
is a reference or not. Thus, scanning the C stack and static data
|
||||
segment is guaranteed to find all actual references, but it might also
|
||||
find words that only accidentally look like references. These ``false
|
||||
positives'' might keep @code{SCM} objects alive that would otherwise be
|
||||
considered dead. While this might waste memory, keeping an object
|
||||
around longer than it strictly needs to is harmless. This is why this
|
||||
technique is called ``conservative garbage collection''. In practice,
|
||||
the wasted memory seems to be no problem, as the static C root set is
|
||||
almost always finite and small, given that the Scheme stack is separate
|
||||
from the C stack.
|
||||
In Guile, garbage collection has two logical phases: the @dfn{mark
|
||||
phase}, in which the collector discovers the set of all live objects,
|
||||
and the @dfn{sweep phase}, in which the collector reclaims the resources
|
||||
associated with dead objects. The mark phase pauses the program and
|
||||
traces all @code{SCM} object references, starting with the root set.
|
||||
The sweep phase actually runs concurrently with the main program,
|
||||
incrementally reclaiming memory as needed by allocation.
|
||||
|
||||
In the mark phase, the garbage collector traces the Scheme stack and
|
||||
heap @dfn{precisely}. Because the Scheme stack and heap are managed by
|
||||
Guile, Guile can know precisely where in those data structures it might
|
||||
find references to other heap objects. This is not the case,
|
||||
unfortunately, for pointers on the C stack and static data segment.
|
||||
Instead of requiring the user to inform Guile about all variables in C
|
||||
that might point to heap objects, Guile traces the C stack and static
|
||||
data segment @dfn{conservatively}. That is to say, Guile just treats
|
||||
every word on the C stack and every C global variable as a potential
|
||||
reference in to the Scheme heap@footnote{Note that Guile does not scan
|
||||
the C heap for references, so a reference to a @code{SCM} object from a
|
||||
memory segment allocated with @code{malloc} will have to use some other
|
||||
means to keep the @code{SCM} object alive. @xref{Garbage Collection
|
||||
Functions}.}. Any value that looks like a pointer to a GC-managed
|
||||
object is treated as such, whether it actually is a reference or not.
|
||||
Thus, scanning the C stack and static data segment is guaranteed to find
|
||||
all actual references, but it might also find words that only
|
||||
accidentally look like references. These ``false positives'' might keep
|
||||
@code{SCM} objects alive that would otherwise be considered dead. While
|
||||
this might waste memory, keeping an object around longer than it
|
||||
strictly needs to is harmless. This is why this technique is called
|
||||
``conservative garbage collection''. In practice, the wasted memory
|
||||
seems to be no problem, as the static C root set is almost always finite
|
||||
and small, given that the Scheme stack is separate from the C stack.
|
||||
|
||||
The stack of every thread is scanned in this way and the registers of
|
||||
the CPU and all other memory locations where local variables or function
|
||||
|
@ -402,7 +418,7 @@ do such a thing on its own.
|
|||
|
||||
If you do not want to allow the running of asynchronous signal handlers,
|
||||
you can block them temporarily with @code{scm_dynwind_block_asyncs}, for
|
||||
example. See @xref{System asyncs}.
|
||||
example. @xref{Asyncs}.
|
||||
|
||||
Since signal handling in Guile relies on safe points, you need to make
|
||||
sure that your functions do offer enough of them. Normally, calling
|
||||
|
|
|
@ -279,10 +279,10 @@ Note that the finalizer may be invoked in ways and at times you might
|
|||
not expect. In particular, if the user's Guile is built with support
|
||||
for threads, the finalizer may be called from any thread that is running
|
||||
Guile. In Guile 2.0, finalizers are invoked via ``asyncs'', which
|
||||
interleaves them with running Scheme code; @pxref{System asyncs}. In
|
||||
Guile 2.2 there will be a dedicated finalization thread, to ensure that
|
||||
the finalization doesn't run within the critical section of any other
|
||||
thread known to Guile.
|
||||
interleaves them with running Scheme code; @pxref{Asyncs}. In Guile 2.2
|
||||
there will be a dedicated finalization thread, to ensure that the
|
||||
finalization doesn't run within the critical section of any other thread
|
||||
known to Guile.
|
||||
|
||||
In either case, finalizers run concurrently with the main program, and
|
||||
so they need to be async-safe and thread-safe. If for some reason this
|
||||
|
|
|
@ -47,7 +47,7 @@ follows,
|
|||
@table @asis
|
||||
@item @nicode{#:display?} @var{flag}
|
||||
If @var{flag} is true then print using @code{display}. The default is
|
||||
@code{#f} which means use @code{write} style. (@pxref{Writing})
|
||||
@code{#f} which means use @code{write} style. @xref{Scheme Write}.
|
||||
|
||||
@item @nicode{#:per-line-prefix} @var{string}
|
||||
Print the given @var{string} as a prefix on each line. The default is
|
||||
|
@ -55,6 +55,9 @@ no prefix.
|
|||
|
||||
@item @nicode{#:width} @var{columns}
|
||||
Print within the given @var{columns}. The default is 79.
|
||||
|
||||
@item @nicode{#:max-expr-width} @var{columns}
|
||||
The maximum width of an expression. The default is 50.
|
||||
@end table
|
||||
@end deffn
|
||||
|
||||
|
@ -106,7 +109,7 @@ follows,
|
|||
@table @asis
|
||||
@item @nicode{#:display?} @var{flag}
|
||||
If @var{flag} is true then print using @code{display}. The default is
|
||||
@code{#f} which means use @code{write} style. (@pxref{Writing})
|
||||
@code{#f} which means use @code{write} style. @pxref{Scheme Write}.
|
||||
|
||||
@item @nicode{#:width} @var{columns}
|
||||
Print within the given @var{columns}. The default is 79.
|
||||
|
@ -204,7 +207,7 @@ Object output. Parameters: @var{minwidth}, @var{padinc},
|
|||
@var{minpad}, @var{padchar}.
|
||||
|
||||
@nicode{~a} outputs an argument like @code{display}, @nicode{~s}
|
||||
outputs an argument like @code{write} (@pxref{Writing}).
|
||||
outputs an argument like @code{write} (@pxref{Scheme Write}).
|
||||
|
||||
@example
|
||||
(format #t "~a" "foo") @print{} foo
|
||||
|
@ -242,9 +245,9 @@ no minimum or multiple).
|
|||
Character. Parameter: @var{charnum}.
|
||||
|
||||
Output a character. The default is to simply output, as per
|
||||
@code{write-char} (@pxref{Writing}). @nicode{~@@c} prints in
|
||||
@code{write} style. @nicode{~:c} prints control characters (ASCII 0
|
||||
to 31) in @nicode{^X} form.
|
||||
@code{write-char} (@pxref{Venerable Port Interfaces}). @nicode{~@@c}
|
||||
prints in @code{write} style. @nicode{~:c} prints control characters
|
||||
(ASCII 0 to 31) in @nicode{^X} form.
|
||||
|
||||
@example
|
||||
(format #t "~c" #\z) @print{} z
|
||||
|
@ -760,8 +763,9 @@ already so.
|
|||
(format #f "a~3,5'*@@tx") @result{} "a****x"
|
||||
@end example
|
||||
|
||||
@nicode{~t} is implemented using @code{port-column} (@pxref{Reading}),
|
||||
so it works even there has been other output before @code{format}.
|
||||
@nicode{~t} is implemented using @code{port-column} (@pxref{Textual
|
||||
I/O}), so it works even there has been other output before
|
||||
@code{format}.
|
||||
|
||||
@item @nicode{~~}
|
||||
Tilde character. Parameter: @var{n}.
|
||||
|
@ -815,7 +819,7 @@ Output a formfeed character, or @var{n} many if a parameter is given.
|
|||
Force output. No parameters.
|
||||
|
||||
At the end of output, call @code{force-output} to flush any buffers on
|
||||
the destination (@pxref{Writing}). @nicode{~!} can occur anywhere in
|
||||
the destination (@pxref{Buffering}). @nicode{~!} can occur anywhere in
|
||||
the format string, but the force is done at the end of output.
|
||||
|
||||
When output is to a string (destination @code{#f}), @nicode{~!} does
|
||||
|
@ -1112,10 +1116,10 @@ originating format, or similar.
|
|||
@sp 1
|
||||
Guile contains a @code{format} procedure even when the module
|
||||
@code{(ice-9 format)} is not loaded. The default @code{format} is
|
||||
@code{simple-format} (@pxref{Writing}), it doesn't support all escape
|
||||
sequences documented in this section, and will signal an error if you
|
||||
try to use one of them. The reason for two versions is that the full
|
||||
@code{format} is fairly large and requires some time to load.
|
||||
@code{simple-format} (@pxref{Simple Output}), it doesn't support all
|
||||
escape sequences documented in this section, and will signal an error if
|
||||
you try to use one of them. The reason for two versions is that the
|
||||
full @code{format} is fairly large and requires some time to load.
|
||||
@code{simple-format} is often adequate too.
|
||||
|
||||
|
||||
|
@ -1661,10 +1665,10 @@ returned.
|
|||
@end deffn
|
||||
|
||||
@deffn {Scheme Procedure} port->stream port readproc
|
||||
Return a stream which is the values obtained by reading from
|
||||
@var{port} using @var{readproc}. Each read call is
|
||||
@code{(@var{readproc} @var{port})}, and it should return an EOF object
|
||||
(@pxref{Reading}) at the end of input.
|
||||
Return a stream which is the values obtained by reading from @var{port}
|
||||
using @var{readproc}. Each read call is @code{(@var{readproc}
|
||||
@var{port})}, and it should return an EOF object (@pxref{Binary I/O}) at
|
||||
the end of input.
|
||||
|
||||
For example a stream of characters from a file,
|
||||
|
||||
|
|
|
@ -7,6 +7,12 @@
|
|||
@node getopt-long
|
||||
@section The (ice-9 getopt-long) Module
|
||||
|
||||
The @code{(ice-9 getopt-long)} facility is designed to help parse
|
||||
arguments that are passed to Guile programs on the command line, and is
|
||||
modelled after the C library's facility of the same name
|
||||
(@pxref{Getopt,,,libc,The GNU C Library Reference Manual}). For a more
|
||||
low-level interface to command-line argument parsing, @xref{SRFI-37}.
|
||||
|
||||
The @code{(ice-9 getopt-long)} module exports two procedures:
|
||||
@code{getopt-long} and @code{option-ref}.
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
@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 2008, 2009, 2010, 2011, 2012, 2013, 2014 Free Software Foundation, Inc.
|
||||
@c 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2017 Free Software Foundation, Inc.
|
||||
@c See the file guile.texi for copying conditions.
|
||||
|
||||
@node POSIX
|
||||
|
@ -133,18 +133,6 @@ then the return is @code{#f}. For example,
|
|||
|
||||
Conventions generally follow those of scsh, @ref{The Scheme shell (scsh)}.
|
||||
|
||||
File ports are implemented using low-level operating system I/O
|
||||
facilities, with optional buffering to improve efficiency; see
|
||||
@ref{File Ports}.
|
||||
|
||||
Note that some procedures (e.g., @code{recv!}) will accept ports as
|
||||
arguments, but will actually operate directly on the file descriptor
|
||||
underlying the port. Any port buffering is ignored, including the
|
||||
buffer which implements @code{peek-char} and @code{unread-char}.
|
||||
|
||||
The @code{force-output} and @code{drain-input} procedures can be used
|
||||
to clear the buffers.
|
||||
|
||||
Each open file port has an associated operating system file descriptor.
|
||||
File descriptors are generally not useful in Scheme programs; however
|
||||
they may be needed when interfacing with foreign code and the Unix
|
||||
|
@ -181,6 +169,22 @@ initially set to one, so that dropping references to one of these
|
|||
ports will not result in its garbage collection: it could be retrieved
|
||||
with @code{fdopen} or @code{fdes->ports}.
|
||||
|
||||
Guile's ports can be buffered. This means that writing a byte to a file
|
||||
port goes to the internal buffer first, and only when the buffer is full
|
||||
(or the user invokes @code{force-output} on the port) is the data
|
||||
actually written to the file descriptor. Likewise on input, bytes are
|
||||
read in from the file descriptor in blocks and placed in a buffer.
|
||||
Reading a character via @code{read-char} first goes to the buffer,
|
||||
filling it as needed. Usually read buffering is more or less
|
||||
transparent, but write buffering can sometimes cause writes to be
|
||||
delayed unexpectedly, if you forget to call @code{force-output}.
|
||||
@xref{Buffering}, for more on how to control port buffers.
|
||||
|
||||
Note however that some procedures (e.g., @code{recv!}) will accept ports
|
||||
as arguments, but will actually operate directly on the file descriptor
|
||||
underlying the port. Any port buffering is ignored, including the
|
||||
buffer which implements @code{peek-char} and @code{unread-char}.
|
||||
|
||||
@deffn {Scheme Procedure} port-revealed port
|
||||
@deffnx {C Function} scm_port_revealed (port)
|
||||
Return the revealed count for @var{port}.
|
||||
|
@ -299,7 +303,7 @@ a port.
|
|||
|
||||
@deffn {Scheme Procedure} close fd_or_port
|
||||
@deffnx {C Function} scm_close (fd_or_port)
|
||||
Similar to @code{close-port} (@pxref{Closing, close-port}),
|
||||
Similar to @code{close-port} (@pxref{Ports, close-port}),
|
||||
but also works on file descriptors. A side
|
||||
effect of closing a file descriptor is that any ports using that file
|
||||
descriptor are moved to a different file descriptor and have
|
||||
|
@ -314,32 +318,16 @@ the file descriptor will be closed even if a port is using it. The
|
|||
return value is unspecified.
|
||||
@end deffn
|
||||
|
||||
@deffn {Scheme Procedure} unread-char char [port]
|
||||
@deffnx {C Function} scm_unread_char (char, port)
|
||||
Place @var{char} in @var{port} so that it will be read by the next
|
||||
read operation on that port. If called multiple times, the unread
|
||||
characters will be read again in ``last-in, first-out'' order (i.e.@:
|
||||
a stack). If @var{port} is not supplied, the current input port is
|
||||
used.
|
||||
@end deffn
|
||||
|
||||
@deffn {Scheme Procedure} unread-string str port
|
||||
Place the string @var{str} in @var{port} so that its characters will be
|
||||
read in subsequent read operations. If called multiple times, the
|
||||
unread characters will be read again in last-in first-out order. If
|
||||
@var{port} is not supplied, the current-input-port is used.
|
||||
@end deffn
|
||||
|
||||
@deffn {Scheme Procedure} pipe
|
||||
@deffnx {C Function} scm_pipe ()
|
||||
@cindex pipe
|
||||
Return a newly created pipe: a pair of ports which are linked
|
||||
together on the local machine. The @acronym{CAR} is the input
|
||||
port and the @acronym{CDR} is the output port. Data written (and
|
||||
flushed) to the output port can be read from the input port.
|
||||
Pipes are commonly used for communication with a newly forked
|
||||
child process. The need to flush the output port can be
|
||||
avoided by making it unbuffered using @code{setvbuf}.
|
||||
Return a newly created pipe: a pair of ports which are linked together
|
||||
on the local machine. The @acronym{CAR} is the input port and the
|
||||
@acronym{CDR} is the output port. Data written (and flushed) to the
|
||||
output port can be read from the input port. Pipes are commonly used
|
||||
for communication with a newly forked child process. The need to flush
|
||||
the output port can be avoided by making it unbuffered using
|
||||
@code{setvbuf} (@pxref{Buffering}).
|
||||
|
||||
@defvar PIPE_BUF
|
||||
A write of up to @code{PIPE_BUF} many bytes to a pipe is atomic,
|
||||
|
@ -431,13 +419,6 @@ is made to move away ports which are using @var{newfd}.
|
|||
The return value is unspecified.
|
||||
@end deffn
|
||||
|
||||
@deffn {Scheme Procedure} port-mode port
|
||||
Return the port modes associated with the open port @var{port}.
|
||||
These will not necessarily be identical to the modes used when
|
||||
the port was opened, since modes such as ``append'' which are
|
||||
used only during port creation are not retained.
|
||||
@end deffn
|
||||
|
||||
@deffn {Scheme Procedure} port-for-each proc
|
||||
@deffnx {C Function} scm_port_for_each (SCM proc)
|
||||
@deffnx {C Function} scm_c_port_for_each (void (*proc)(void *, SCM), void *data)
|
||||
|
@ -455,26 +436,6 @@ a pointer to a C function and passes along a arbitrary @var{data}
|
|||
cookie.
|
||||
@end deffn
|
||||
|
||||
@deffn {Scheme Procedure} setvbuf port mode [size]
|
||||
@deffnx {C Function} scm_setvbuf (port, mode, size)
|
||||
@cindex port buffering
|
||||
Set the buffering mode for @var{port}. @var{mode} can be:
|
||||
|
||||
@defvar _IONBF
|
||||
non-buffered
|
||||
@end defvar
|
||||
@defvar _IOLBF
|
||||
line buffered
|
||||
@end defvar
|
||||
@defvar _IOFBF
|
||||
block buffered, using a newly allocated buffer of @var{size} bytes.
|
||||
If @var{size} is omitted, a default size will be used.
|
||||
@end defvar
|
||||
|
||||
Only certain types of ports are supported, most importantly
|
||||
file ports.
|
||||
@end deffn
|
||||
|
||||
@deffn {Scheme Procedure} fcntl port/fd cmd [value]
|
||||
@deffnx {C Function} scm_fcntl (object, cmd, value)
|
||||
Apply @var{cmd} on @var{port/fd}, either a port or file descriptor.
|
||||
|
@ -568,10 +529,10 @@ to provide input, accept output, or the existence of
|
|||
exceptional conditions on a collection of ports or file
|
||||
descriptors, or waiting for a timeout to occur.
|
||||
|
||||
When an error occurs, of if it is interrupted by a signal, this
|
||||
procedure throws a @code{system-error} exception
|
||||
(@pxref{Conventions, @code{system-error}}). In case of an
|
||||
interruption, the associated error number is @var{EINTR}.
|
||||
When an error occurs, this procedure throws a @code{system-error}
|
||||
exception (@pxref{Conventions, @code{system-error}}). Note that
|
||||
@code{select} may return early for other reasons, for example due to
|
||||
pending interrupts. @xref{Asyncs}, for more on interrupts.
|
||||
|
||||
@var{reads}, @var{writes} and @var{excepts} can be lists or
|
||||
vectors, with each member a port or a file descriptor.
|
||||
|
@ -598,6 +559,51 @@ Duplicates in the input vectors appear only once in output.
|
|||
An additional @code{select!} interface is provided.
|
||||
@end deffn
|
||||
|
||||
While it is sometimes necessary to operate at the level of file
|
||||
descriptors, this is an operation whose correctness can only be
|
||||
considered as part of a whole program. So for example while the effects
|
||||
of @code{(string-set! x 34 #\y)} are limited to the bits of code that
|
||||
can access @var{x}, @code{(close-fdes 34)} mutates the state of the
|
||||
entire process. In particular if another thread is using file
|
||||
descriptor 34 then their state might be corrupted; and another thread
|
||||
which opens a file might cause file descriptor 34 to be re-used, so that
|
||||
corruption could manifest itself in a strange way.
|
||||
|
||||
@cindex fdes finalizers
|
||||
@cindex file descriptor finalizers
|
||||
@cindex finalizers, file descriptor
|
||||
However when working with file descriptors, it's common to want to
|
||||
associate information with the file descriptor, perhaps in a side table.
|
||||
To support this use case and to allow user code to remove an association
|
||||
when a file descriptor is closed, Guile offers @dfn{fdes finalizers}.
|
||||
|
||||
As the name indicates, fdes finalizers are finalizers -- they can run in
|
||||
response to garbage collection, and they can also run in response to
|
||||
explicit calls to @code{close-port}, @code{close-fdes}, or the like. As
|
||||
such they inherit many of the pitfalls of finalizers: they may be
|
||||
invoked from concurrent threads, or not at all. @xref{Foreign Object
|
||||
Memory Management}, for more on finalizers.
|
||||
|
||||
To use fdes finalizers, import their module;
|
||||
|
||||
@example
|
||||
(use-modules (ice-9 fdes-finalizers))
|
||||
@end example
|
||||
|
||||
@deffn {Scheme Procedure} add-fdes-finalizer! fdes finalizer
|
||||
@deffnx {Scheme Procedure} remove-fdes-finalizer! fdes finalizer
|
||||
Add or remove a finalizer for @var{fdes}. A finalizer is a procedure
|
||||
that is called by Guile when a file descriptor is closed. The file
|
||||
descriptor being closed is passed as the one argument to the finalizer.
|
||||
If a finalizer has been added multiple times to a file descriptor, to
|
||||
remove it would require that number of calls to
|
||||
@code{remove-fdes-finalizer!}.
|
||||
|
||||
The finalizers added to a file descriptor are called by Guile in an
|
||||
unspecified order, and their return values are ignored.
|
||||
@end deffn
|
||||
|
||||
|
||||
@node File System
|
||||
@subsection File System
|
||||
@cindex file system
|
||||
|
@ -864,9 +870,10 @@ Create a symbolic link named @var{newpath} with the value (i.e., pointing to)
|
|||
@deffn {Scheme Procedure} mkdir path [mode]
|
||||
@deffnx {C Function} scm_mkdir (path, mode)
|
||||
Create a new directory named by @var{path}. If @var{mode} is omitted
|
||||
then the permissions of the directory file are set using the current
|
||||
umask (@pxref{Processes}). Otherwise they are set to the decimal
|
||||
value specified with @var{mode}. The return value is unspecified.
|
||||
then the permissions of the directory are set to @code{#o777}
|
||||
masked with the current umask (@pxref{Processes, @code{umask}}).
|
||||
Otherwise they are set to the value specified with @var{mode}.
|
||||
The return value is unspecified.
|
||||
@end deffn
|
||||
|
||||
@deffn {Scheme Procedure} rmdir path
|
||||
|
@ -966,7 +973,7 @@ another name if the file exists (error @code{EEXIST}).
|
|||
@code{mkstemp!} below does that.
|
||||
@end deffn
|
||||
|
||||
@deffn {Scheme Procedure} mkstemp! tmpl
|
||||
@deffn {Scheme Procedure} mkstemp! tmpl [mode]
|
||||
@deffnx {C Function} scm_mkstemp (tmpl)
|
||||
@cindex temporary file
|
||||
Create a new unique file in the file system and return a new buffered
|
||||
|
@ -987,6 +994,10 @@ which is usual for ordinary file creation,
|
|||
(chmod port (logand #o666 (lognot (umask))))
|
||||
...)
|
||||
@end example
|
||||
|
||||
The optional @var{mode} argument specifies a mode with which to open the
|
||||
new file, as a string in the same format that @code{open-file} takes.
|
||||
It defaults to @code{"w+"}.
|
||||
@end deffn
|
||||
|
||||
@deffn {Scheme Procedure} tmpfile
|
||||
|
@ -1966,29 +1977,8 @@ Currently this procedure is only defined on GNU variants
|
|||
GNU C Library Reference Manual}).
|
||||
@end deffn
|
||||
|
||||
@deffn {Scheme Procedure} total-processor-count
|
||||
@deffnx {C Function} scm_total_processor_count ()
|
||||
Return the total number of processors of the machine, which
|
||||
is guaranteed to be at least 1. A ``processor'' here is a
|
||||
thread execution unit, which can be either:
|
||||
|
||||
@itemize
|
||||
@item an execution core in a (possibly multi-core) chip, in a
|
||||
(possibly multi- chip) module, in a single computer, or
|
||||
@item a thread execution unit inside a core in the case of
|
||||
@dfn{hyper-threaded} CPUs.
|
||||
@end itemize
|
||||
|
||||
Which of the two definitions is used, is unspecified.
|
||||
@end deffn
|
||||
|
||||
@deffn {Scheme Procedure} current-processor-count
|
||||
@deffnx {C Function} scm_current_processor_count ()
|
||||
Like @code{total-processor-count}, but return the number of
|
||||
processors available to the current process. See
|
||||
@code{setaffinity} and @code{getaffinity} for more
|
||||
information.
|
||||
@end deffn
|
||||
@xref{Threads}, for information on how get the number of processors
|
||||
available on a system.
|
||||
|
||||
|
||||
@node Signals
|
||||
|
@ -1997,11 +1987,11 @@ information.
|
|||
|
||||
The following procedures raise, handle and wait for signals.
|
||||
|
||||
Scheme code signal handlers are run via a system async (@pxref{System
|
||||
asyncs}), so they're called in the handler's thread at the next safe
|
||||
opportunity. Generally this is after any currently executing
|
||||
primitive procedure finishes (which could be a long time for
|
||||
primitives that wait for an external event).
|
||||
Scheme code signal handlers are run via an async (@pxref{Asyncs}), so
|
||||
they're called in the handler's thread at the next safe opportunity.
|
||||
Generally this is after any currently executing primitive procedure
|
||||
finishes (which could be a long time for primitives that wait for an
|
||||
external event).
|
||||
|
||||
@deffn {Scheme Procedure} kill pid sig
|
||||
@deffnx {C Function} scm_kill (pid, sig)
|
||||
|
@ -2087,6 +2077,22 @@ restart the system call (as opposed to returning an @code{EINTR} error
|
|||
from that call).
|
||||
@end defvar
|
||||
|
||||
Guile handles signals asynchronously. When it receives a signal, the
|
||||
synchronous signal handler just records the fact that a signal was
|
||||
received and sets a flag to tell the relevant Guile thread that it has a
|
||||
pending signal. When the Guile thread checks the pending-interrupt
|
||||
flag, it will arrange to run the asynchronous part of the signal
|
||||
handler, which is the handler attached by @code{sigaction}.
|
||||
|
||||
This strategy has some perhaps-unexpected interactions with the
|
||||
@code{SA_RESTART} flag, though: because the synchronous handler doesn't
|
||||
do very much, and notably it doesn't run the Guile handler, it's
|
||||
impossible to interrupt a thread stuck in a long-running system call via
|
||||
a signal handler that is installed with @code{SA_RESTART}: the
|
||||
synchronous handler just records the pending interrupt, but then the
|
||||
system call resumes and Guile doesn't have a chance to actually check
|
||||
the flag and run the asynchronous handler. That's just how it is.
|
||||
|
||||
The return value is a pair with information about the old handler as
|
||||
described above.
|
||||
|
||||
|
@ -2156,12 +2162,12 @@ expiry will be signalled.
|
|||
A real-time timer, counting down elapsed real time. At zero it raises
|
||||
@code{SIGALRM}. This is like @code{alarm} above, but with a higher
|
||||
resolution period.
|
||||
@end defvar
|
||||
@end defvar
|
||||
|
||||
@defvar ITIMER_VIRTUAL
|
||||
A virtual-time timer, counting down while the current process is
|
||||
actually using CPU. At zero it raises @code{SIGVTALRM}.
|
||||
@end defvar
|
||||
@end defvar
|
||||
|
||||
@defvar ITIMER_PROF
|
||||
A profiling timer, counting down while the process is running (like
|
||||
|
@ -2170,7 +2176,7 @@ process's behalf. At zero it raises a @code{SIGPROF}.
|
|||
|
||||
This timer is intended for profiling where a program is spending its
|
||||
time (by looking where it is when the timer goes off).
|
||||
@end defvar
|
||||
@end defvar
|
||||
|
||||
@code{getitimer} returns the restart timer value and its current value,
|
||||
as a list containing two pairs. Each pair is a time in seconds and
|
||||
|
@ -2190,6 +2196,13 @@ previous setting, in the same form as @code{getitimer} returns.
|
|||
|
||||
Although the timers are programmed in microseconds, the actual
|
||||
accuracy might not be that high.
|
||||
|
||||
Note that @code{ITIMER_PROF} and @code{ITIMER_VIRTUAL} are not
|
||||
functional on all platforms and may always error when called.
|
||||
@code{(provided? 'ITIMER_PROF)} and @code{(provided? 'ITIMER_VIRTUAL)}
|
||||
can be used to test if the those itimers are supported on the given
|
||||
host. @code{ITIMER_REAL} is supported on all platforms that support
|
||||
@code{setitimer}.
|
||||
@end deffn
|
||||
|
||||
|
||||
|
@ -2249,7 +2262,7 @@ controlling terminal. The return value is unspecified.
|
|||
The following procedures are similar to the @code{popen} and
|
||||
@code{pclose} system routines. The code is in a separate ``popen''
|
||||
module@footnote{This module is only available on systems where the
|
||||
@code{fork} feature is provided (@pxref{Common Feature Symbols}).}:
|
||||
@code{popen} feature is provided (@pxref{Common Feature Symbols}).}:
|
||||
|
||||
@lisp
|
||||
(use-modules (ice-9 popen))
|
||||
|
@ -2278,7 +2291,7 @@ For an input pipe, the child's standard output is the pipe and
|
|||
standard input is inherited from @code{current-input-port}. For an
|
||||
output pipe, the child's standard input is the pipe and standard
|
||||
output is inherited from @code{current-output-port}. In all cases
|
||||
cases the child's standard error is inherited from
|
||||
the child's standard error is inherited from
|
||||
@code{current-error-port} (@pxref{Default Ports}).
|
||||
|
||||
If those @code{current-X-ports} are not files of some kind, and hence
|
||||
|
@ -2286,11 +2299,10 @@ don't have file descriptors for the child, then @file{/dev/null} is
|
|||
used instead.
|
||||
|
||||
Care should be taken with @code{OPEN_BOTH}, a deadlock will occur if
|
||||
both parent and child are writing, and waiting until the write
|
||||
completes before doing any reading. Each direction has
|
||||
@code{PIPE_BUF} bytes of buffering (@pxref{Ports and File
|
||||
Descriptors}), which will be enough for small writes, but not for say
|
||||
putting a big file through a filter.
|
||||
both parent and child are writing, and waiting until the write completes
|
||||
before doing any reading. Each direction has @code{PIPE_BUF} bytes of
|
||||
buffering (@pxref{Buffering}), which will be enough for small writes,
|
||||
but not for say putting a big file through a filter.
|
||||
@end deffn
|
||||
|
||||
@deffn {Scheme Procedure} open-input-pipe command
|
||||
|
@ -2333,8 +2345,8 @@ terminate, and return the wait status code. The status is as per
|
|||
it can reap a pipe's child process, causing an error from a subsequent
|
||||
@code{close-pipe}.
|
||||
|
||||
@code{close-port} (@pxref{Closing}) can close a pipe, but it doesn't
|
||||
reap the child process.
|
||||
@code{close-port} (@pxref{Ports}) can close a pipe, but it doesn't reap
|
||||
the child process.
|
||||
|
||||
The garbage collector will close a pipe no longer in use, and reap the
|
||||
child process with @code{waitpid}. If the child hasn't yet terminated
|
||||
|
@ -3057,7 +3069,7 @@ release the returned structure when no longer required.
|
|||
Socket ports can be created using @code{socket} and @code{socketpair}.
|
||||
The ports are initially unbuffered, to make reading and writing to the
|
||||
same port more reliable. A buffer can be added to the port using
|
||||
@code{setvbuf}; see @ref{Ports and File Descriptors}.
|
||||
@code{setvbuf} (@pxref{Buffering}).
|
||||
|
||||
Most systems have limits on how many files and sockets can be open, so
|
||||
it's strongly recommended that socket ports be closed explicitly when
|
||||
|
@ -3191,6 +3203,15 @@ supporting that.
|
|||
@end defvar
|
||||
@end deffn
|
||||
|
||||
For @code{IPPROTO_TCP} level the following @var{optname}s are defined
|
||||
(when provided by the system). For their meaning see @command{man 7
|
||||
tcp}.
|
||||
|
||||
@defvar TCP_NODELAY
|
||||
@defvarx TCP_CORK
|
||||
The @var{value} taken or returned is an integer.
|
||||
@end defvar
|
||||
|
||||
@deffn {Scheme Procedure} shutdown sock how
|
||||
@deffnx {C Function} scm_shutdown (sock, how)
|
||||
Sockets can be closed simply by using @code{close-port}. The
|
||||
|
@ -3217,10 +3238,12 @@ The return value is unspecified.
|
|||
@deffnx {Scheme Procedure} connect sock AF_INET6 ipv6addr port [flowinfo [scopeid]]
|
||||
@deffnx {Scheme Procedure} connect sock AF_UNIX path
|
||||
@deffnx {C Function} scm_connect (sock, fam, address, args)
|
||||
Initiate a connection on socket port @var{sock} to a given address.
|
||||
The destination is either a socket address object, or arguments the
|
||||
same as @code{make-socket-address} would take to make such an object
|
||||
(@pxref{Network Socket Address}). The return value is unspecified.
|
||||
Initiate a connection on socket port @var{sock} to a given address. The
|
||||
destination is either a socket address object, or arguments the same as
|
||||
@code{make-socket-address} would take to make such an object
|
||||
(@pxref{Network Socket Address}). Return true unless the socket was
|
||||
configured as non-blocking and the connection could not be made
|
||||
immediately.
|
||||
|
||||
@example
|
||||
(connect sock AF_INET INADDR_LOOPBACK 23)
|
||||
|
@ -3261,18 +3284,33 @@ the queue.
|
|||
The return value is unspecified.
|
||||
@end deffn
|
||||
|
||||
@deffn {Scheme Procedure} accept sock
|
||||
@deffn {Scheme Procedure} accept sock [flags]
|
||||
@deffnx {C Function} scm_accept (sock)
|
||||
Accept a connection from socket port @var{sock} which has been enabled
|
||||
for listening with @code{listen} above. If there are no incoming
|
||||
connections in the queue, wait until one is available (unless
|
||||
@code{O_NONBLOCK} has been set on the socket, @pxref{Ports and File
|
||||
Descriptors,@code{fcntl}}).
|
||||
for listening with @code{listen} above.
|
||||
|
||||
If there are no incoming connections in the queue, there are two
|
||||
possible behaviors, depending on whether @var{sock} has been configured
|
||||
for non-blocking operation or not:
|
||||
|
||||
@itemize
|
||||
@item
|
||||
If there is no connection waiting and the socket was set to non-blocking
|
||||
mode with the @code{O_NONBLOCK} port option (@pxref{Ports and File
|
||||
Descriptors,@code{fcntl}}), return @code{#f} directly.
|
||||
|
||||
@item
|
||||
Otherwise wait until a connection is available.
|
||||
@end itemize
|
||||
|
||||
The return value is a pair. The @code{car} is a new socket port,
|
||||
connected and ready to communicate. The @code{cdr} is a socket
|
||||
address object (@pxref{Network Socket Address}) which is where the
|
||||
remote connection is from (like @code{getpeername} below).
|
||||
connected and ready to communicate. The @code{cdr} is a socket address
|
||||
object (@pxref{Network Socket Address}) which is where the remote
|
||||
connection is from (like @code{getpeername} below).
|
||||
|
||||
@var{flags}, if given, may include @code{SOCK_CLOEXEC} or
|
||||
@code{SOCK_NONBLOCK}, which like @code{O_CLOEXEC} and @code{O_NONBLOCK}
|
||||
apply to the newly accepted socket.
|
||||
|
||||
All communication takes place using the new socket returned. The
|
||||
given @var{sock} remains bound and listening, and @code{accept} may be
|
||||
|
|
|
@ -97,9 +97,9 @@ The @code{(rnrs io ports)} module is incomplete. Work is
|
|||
ongoing to fix this.
|
||||
|
||||
@item
|
||||
Guile does not prevent use of textual I/O procedures on binary ports.
|
||||
More generally, it does not make a sharp distinction between binary and
|
||||
textual ports (@pxref{R6RS Port Manipulation, binary-port?}).
|
||||
Guile does not prevent use of textual I/O procedures on binary ports, or
|
||||
vice versa. All ports in Guile support both binary and textual I/O.
|
||||
@xref{Encoding}, for full details.
|
||||
|
||||
@item
|
||||
Guile's implementation of @code{equal?} may fail to terminate when
|
||||
|
@ -147,8 +147,10 @@ Language Scheme}).
|
|||
* rnrs exceptions:: Handling exceptional situations.
|
||||
* rnrs conditions:: Data structures for exceptions.
|
||||
|
||||
* I/O Conditions:: Predefined I/O error types.
|
||||
* R6RS I/O Conditions:: Predefined I/O error types.
|
||||
* R6RS Transcoders:: Characters and bytes.
|
||||
* rnrs io ports:: Support for port-based I/O.
|
||||
* R6RS File Ports:: Working with files.
|
||||
* rnrs io simple:: High-level I/O API.
|
||||
|
||||
* rnrs files:: Functions for working with files.
|
||||
|
@ -722,11 +724,15 @@ These procedures are identical to the ones provided by SRFI-1.
|
|||
@xref{SRFI-1 Filtering and Partitioning}, for @code{partition}.
|
||||
@end deffn
|
||||
|
||||
@deffn {Scheme Procedure} fold-right combine nil list1 list2 @dots{}
|
||||
This procedure is identical the @code{fold-right} procedure provided by
|
||||
SRFI-1. @xref{SRFI-1 Fold and Map}, for documentation.
|
||||
@end deffn
|
||||
|
||||
@deffn {Scheme Procedure} fold-left combine nil list1 list2 @dots{}
|
||||
@deffnx {Scheme Procedure} fold-right combine nil list1 list2 @dots{}
|
||||
These procedures are identical to the @code{fold} and @code{fold-right}
|
||||
procedures provided by SRFI-1. @xref{SRFI-1 Fold and Map}, for
|
||||
documentation.
|
||||
This procedure is like @code{fold} from SRFI-1, but @var{combine} is
|
||||
called with the seed as the first argument. @xref{SRFI-1 Fold and Map},
|
||||
for documentation.
|
||||
@end deffn
|
||||
|
||||
@deffn {Scheme Procedure} remp proc list
|
||||
|
@ -1343,7 +1349,7 @@ A subtype of @code{&violation} that indicates a reference to an unbound
|
|||
identifier.
|
||||
@end deffn
|
||||
|
||||
@node I/O Conditions
|
||||
@node R6RS I/O Conditions
|
||||
@subsubsection I/O Conditions
|
||||
|
||||
These condition types are exported by both the
|
||||
|
@ -1420,21 +1426,548 @@ A subtype of @code{&i/o}; represents an error related to an operation on
|
|||
the port @var{port}.
|
||||
@end deffn
|
||||
|
||||
@node R6RS Transcoders
|
||||
@subsubsection Transcoders
|
||||
@cindex codec
|
||||
@cindex end-of-line style
|
||||
@cindex transcoder
|
||||
@cindex binary port
|
||||
@cindex textual port
|
||||
|
||||
The transcoder facilities are exported by @code{(rnrs io ports)}.
|
||||
|
||||
Several different Unicode encoding schemes describe standard ways to
|
||||
encode characters and strings as byte sequences and to decode those
|
||||
sequences. Within this document, a @dfn{codec} is an immutable Scheme
|
||||
object that represents a Unicode or similar encoding scheme.
|
||||
|
||||
An @dfn{end-of-line style} is a symbol that, if it is not @code{none},
|
||||
describes how a textual port transcodes representations of line endings.
|
||||
|
||||
A @dfn{transcoder} is an immutable Scheme object that combines a codec
|
||||
with an end-of-line style and a method for handling decoding errors.
|
||||
Each transcoder represents some specific bidirectional (but not
|
||||
necessarily lossless), possibly stateful translation between byte
|
||||
sequences and Unicode characters and strings. Every transcoder can
|
||||
operate in the input direction (bytes to characters) or in the output
|
||||
direction (characters to bytes). A @var{transcoder} parameter name
|
||||
means that the corresponding argument must be a transcoder.
|
||||
|
||||
A @dfn{binary port} is a port that supports binary I/O, does not have an
|
||||
associated transcoder and does not support textual I/O. A @dfn{textual
|
||||
port} is a port that supports textual I/O, and does not support binary
|
||||
I/O. A textual port may or may not have an associated transcoder.
|
||||
|
||||
@deffn {Scheme Procedure} latin-1-codec
|
||||
@deffnx {Scheme Procedure} utf-8-codec
|
||||
@deffnx {Scheme Procedure} utf-16-codec
|
||||
|
||||
These are predefined codecs for the ISO 8859-1, UTF-8, and UTF-16
|
||||
encoding schemes.
|
||||
|
||||
A call to any of these procedures returns a value that is equal in the
|
||||
sense of @code{eqv?} to the result of any other call to the same
|
||||
procedure.
|
||||
@end deffn
|
||||
|
||||
@deffn {Scheme Syntax} eol-style @var{eol-style-symbol}
|
||||
|
||||
@var{eol-style-symbol} should be a symbol whose name is one of
|
||||
@code{lf}, @code{cr}, @code{crlf}, @code{nel}, @code{crnel}, @code{ls},
|
||||
and @code{none}.
|
||||
|
||||
The form evaluates to the corresponding symbol. If the name of
|
||||
@var{eol-style-symbol} is not one of these symbols, the effect and
|
||||
result are implementation-dependent; in particular, the result may be an
|
||||
eol-style symbol acceptable as an @var{eol-style} argument to
|
||||
@code{make-transcoder}. Otherwise, an exception is raised.
|
||||
|
||||
All eol-style symbols except @code{none} describe a specific
|
||||
line-ending encoding:
|
||||
|
||||
@table @code
|
||||
@item lf
|
||||
linefeed
|
||||
@item cr
|
||||
carriage return
|
||||
@item crlf
|
||||
carriage return, linefeed
|
||||
@item nel
|
||||
next line
|
||||
@item crnel
|
||||
carriage return, next line
|
||||
@item ls
|
||||
line separator
|
||||
@end table
|
||||
|
||||
For a textual port with a transcoder, and whose transcoder has an
|
||||
eol-style symbol @code{none}, no conversion occurs. For a textual input
|
||||
port, any eol-style symbol other than @code{none} means that all of the
|
||||
above line-ending encodings are recognized and are translated into a
|
||||
single linefeed. For a textual output port, @code{none} and @code{lf}
|
||||
are equivalent. Linefeed characters are encoded according to the
|
||||
specified eol-style symbol, and all other characters that participate in
|
||||
possible line endings are encoded as is.
|
||||
|
||||
@quotation Note
|
||||
Only the name of @var{eol-style-symbol} is significant.
|
||||
@end quotation
|
||||
@end deffn
|
||||
|
||||
@deffn {Scheme Procedure} native-eol-style
|
||||
Returns the default end-of-line style of the underlying platform, e.g.,
|
||||
@code{lf} on Unix and @code{crlf} on Windows.
|
||||
@end deffn
|
||||
|
||||
@deffn {Condition Type} &i/o-decoding
|
||||
@deffnx {Scheme Procedure} make-i/o-decoding-error port
|
||||
@deffnx {Scheme Procedure} i/o-decoding-error? obj
|
||||
This condition type could be defined by
|
||||
|
||||
@lisp
|
||||
(define-condition-type &i/o-decoding &i/o-port
|
||||
make-i/o-decoding-error i/o-decoding-error?)
|
||||
@end lisp
|
||||
|
||||
An exception with this type is raised when one of the operations for
|
||||
textual input from a port encounters a sequence of bytes that cannot be
|
||||
translated into a character or string by the input direction of the
|
||||
port's transcoder.
|
||||
|
||||
When such an exception is raised, the port's position is past the
|
||||
invalid encoding.
|
||||
@end deffn
|
||||
|
||||
@deffn {Condition Type} &i/o-encoding
|
||||
@deffnx {Scheme Procedure} make-i/o-encoding-error port char
|
||||
@deffnx {Scheme Procedure} i/o-encoding-error? obj
|
||||
@deffnx {Scheme Procedure} i/o-encoding-error-char condition
|
||||
This condition type could be defined by
|
||||
|
||||
@lisp
|
||||
(define-condition-type &i/o-encoding &i/o-port
|
||||
make-i/o-encoding-error i/o-encoding-error?
|
||||
(char i/o-encoding-error-char))
|
||||
@end lisp
|
||||
|
||||
An exception with this type is raised when one of the operations for
|
||||
textual output to a port encounters a character that cannot be
|
||||
translated into bytes by the output direction of the port's transcoder.
|
||||
@var{char} is the character that could not be encoded.
|
||||
@end deffn
|
||||
|
||||
@deffn {Scheme Syntax} error-handling-mode @var{error-handling-mode-symbol}
|
||||
@var{error-handling-mode-symbol} should be a symbol whose name is one of
|
||||
@code{ignore}, @code{raise}, and @code{replace}. The form evaluates to
|
||||
the corresponding symbol. If @var{error-handling-mode-symbol} is not
|
||||
one of these identifiers, effect and result are
|
||||
implementation-dependent: The result may be an error-handling-mode
|
||||
symbol acceptable as a @var{handling-mode} argument to
|
||||
@code{make-transcoder}. If it is not acceptable as a
|
||||
@var{handling-mode} argument to @code{make-transcoder}, an exception is
|
||||
raised.
|
||||
|
||||
@quotation Note
|
||||
Only the name of @var{error-handling-mode-symbol} is significant.
|
||||
@end quotation
|
||||
|
||||
The error-handling mode of a transcoder specifies the behavior
|
||||
of textual I/O operations in the presence of encoding or decoding
|
||||
errors.
|
||||
|
||||
If a textual input operation encounters an invalid or incomplete
|
||||
character encoding, and the error-handling mode is @code{ignore}, an
|
||||
appropriate number of bytes of the invalid encoding are ignored and
|
||||
decoding continues with the following bytes.
|
||||
|
||||
If the error-handling mode is @code{replace}, the replacement
|
||||
character U+FFFD is injected into the data stream, an appropriate
|
||||
number of bytes are ignored, and decoding
|
||||
continues with the following bytes.
|
||||
|
||||
If the error-handling mode is @code{raise}, an exception with condition
|
||||
type @code{&i/o-decoding} is raised.
|
||||
|
||||
If a textual output operation encounters a character it cannot encode,
|
||||
and the error-handling mode is @code{ignore}, the character is ignored
|
||||
and encoding continues with the next character. If the error-handling
|
||||
mode is @code{replace}, a codec-specific replacement character is
|
||||
emitted by the transcoder, and encoding continues with the next
|
||||
character. The replacement character is U+FFFD for transcoders whose
|
||||
codec is one of the Unicode encodings, but is the @code{?} character
|
||||
for the Latin-1 encoding. If the error-handling mode is @code{raise},
|
||||
an exception with condition type @code{&i/o-encoding} is raised.
|
||||
@end deffn
|
||||
|
||||
@deffn {Scheme Procedure} make-transcoder codec
|
||||
@deffnx {Scheme Procedure} make-transcoder codec eol-style
|
||||
@deffnx {Scheme Procedure} make-transcoder codec eol-style handling-mode
|
||||
@var{codec} must be a codec; @var{eol-style}, if present, an eol-style
|
||||
symbol; and @var{handling-mode}, if present, an error-handling-mode
|
||||
symbol.
|
||||
|
||||
@var{eol-style} may be omitted, in which case it defaults to the native
|
||||
end-of-line style of the underlying platform. @var{handling-mode} may
|
||||
be omitted, in which case it defaults to @code{replace}. The result is
|
||||
a transcoder with the behavior specified by its arguments.
|
||||
@end deffn
|
||||
|
||||
@deffn {Scheme procedure} native-transcoder
|
||||
Returns an implementation-dependent transcoder that represents a
|
||||
possibly locale-dependent ``native'' transcoding.
|
||||
@end deffn
|
||||
|
||||
@deffn {Scheme Procedure} transcoder-codec transcoder
|
||||
@deffnx {Scheme Procedure} transcoder-eol-style transcoder
|
||||
@deffnx {Scheme Procedure} transcoder-error-handling-mode transcoder
|
||||
These are accessors for transcoder objects; when applied to a
|
||||
transcoder returned by @code{make-transcoder}, they return the
|
||||
@var{codec}, @var{eol-style}, and @var{handling-mode} arguments,
|
||||
respectively.
|
||||
@end deffn
|
||||
|
||||
@deffn {Scheme Procedure} bytevector->string bytevector transcoder
|
||||
Returns the string that results from transcoding the
|
||||
@var{bytevector} according to the input direction of the transcoder.
|
||||
@end deffn
|
||||
|
||||
@deffn {Scheme Procedure} string->bytevector string transcoder
|
||||
Returns the bytevector that results from transcoding the
|
||||
@var{string} according to the output direction of the transcoder.
|
||||
@end deffn
|
||||
|
||||
@node rnrs io ports
|
||||
@subsubsection rnrs io ports
|
||||
|
||||
The @code{(rnrs io ports (6))} library provides various procedures and
|
||||
syntactic forms for use in writing to and reading from ports. This
|
||||
functionality is documented in its own section of the manual;
|
||||
(@pxref{R6RS I/O Ports}).
|
||||
@cindex R6RS
|
||||
@cindex R6RS ports
|
||||
Guile's binary and textual port interface was heavily inspired by R6RS,
|
||||
so many R6RS port interfaces are documented elsewhere. Note that R6RS
|
||||
ports are not disjoint from Guile's native ports, so Guile-specific
|
||||
procedures will work on ports created using the R6RS API, and vice
|
||||
versa. Also note that in Guile, all ports are both textual and binary.
|
||||
@xref{Input and Output}, for more on Guile's core port API. The R6RS
|
||||
ports module wraps Guile's I/O routines in a helper that will translate
|
||||
native Guile exceptions to R6RS conditions; @xref{R6RS I/O Conditions},
|
||||
for more. @xref{R6RS File Ports}, for documentation on the R6RS file
|
||||
port interface.
|
||||
|
||||
@c FIXME: Update description when implemented.
|
||||
@emph{Note}: The implementation of this R6RS API is not complete yet.
|
||||
|
||||
@deffn {Scheme Procedure} eof-object? obj
|
||||
@xref{Binary I/O}, for documentation.
|
||||
@end deffn
|
||||
|
||||
@deffn {Scheme Procedure} eof-object
|
||||
Return the end-of-file (EOF) object.
|
||||
|
||||
@lisp
|
||||
(eof-object? (eof-object))
|
||||
@result{} #t
|
||||
@end lisp
|
||||
@end deffn
|
||||
|
||||
@deffn {Scheme Procedure} port? obj
|
||||
@deffnx {Scheme Procedure} input-port? obj
|
||||
@deffnx {Scheme Procedure} output-port? obj
|
||||
@xref{Ports}, for documentation.
|
||||
@end deffn
|
||||
|
||||
@deffn {Scheme Procedure} port-transcoder port
|
||||
Return a transcoder associated with the encoding of @var{port}.
|
||||
@xref{Encoding}, and @xref{R6RS Transcoders}.
|
||||
@end deffn
|
||||
|
||||
@deffn {Scheme Procedure} binary-port? port
|
||||
@deffnx {Scheme Procedure} textual-port? port
|
||||
Return @code{#t}, as all ports in Guile are suitable for binary and
|
||||
textual I/O. @xref{Encoding}, for more details.
|
||||
@end deffn
|
||||
|
||||
@deffn {Scheme Procedure} transcoded-port binary-port transcoder
|
||||
The @code{transcoded-port} procedure
|
||||
returns a new textual port with the specified @var{transcoder}.
|
||||
Otherwise the new textual port's state is largely the same as
|
||||
that of @var{binary-port}.
|
||||
If @var{binary-port} is an input port, the new textual
|
||||
port will be an input port and
|
||||
will transcode the bytes that have not yet been read from
|
||||
@var{binary-port}.
|
||||
If @var{binary-port} is an output port, the new textual
|
||||
port will be an output port and
|
||||
will transcode output characters into bytes that are
|
||||
written to the byte sink represented by @var{binary-port}.
|
||||
|
||||
As a side effect, however, @code{transcoded-port}
|
||||
closes @var{binary-port} in
|
||||
a special way that allows the new textual port to continue to
|
||||
use the byte source or sink represented by @var{binary-port},
|
||||
even though @var{binary-port} itself is closed and cannot
|
||||
be used by the input and output operations described in this
|
||||
chapter.
|
||||
@end deffn
|
||||
|
||||
@deffn {Scheme Procedure} port-position port
|
||||
Equivalent to @code{(seek @var{port} SEEK_CUR 0)}. @xref{Random
|
||||
Access}.
|
||||
@end deffn
|
||||
|
||||
@deffn {Scheme Procedure} port-has-port-position? port
|
||||
Return @code{#t} is @var{port} supports @code{port-position}.
|
||||
@end deffn
|
||||
|
||||
@deffn {Scheme Procedure} set-port-position! port offset
|
||||
Equivalent to @code{(seek @var{port} SEEK_SET @var{offset})}.
|
||||
@xref{Random Access}.
|
||||
@end deffn
|
||||
|
||||
@deffn {Scheme Procedure} port-has-set-port-position!? port
|
||||
Return @code{#t} is @var{port} supports @code{set-port-position!}.
|
||||
@end deffn
|
||||
|
||||
@deffn {Scheme Procedure} call-with-port port proc
|
||||
Call @var{proc}, passing it @var{port} and closing @var{port} upon exit
|
||||
of @var{proc}. Return the return values of @var{proc}.
|
||||
@end deffn
|
||||
|
||||
@deffn {Scheme Procedure} port-eof? input-port
|
||||
Equivalent to @code{(eof-object? (lookahead-u8 @var{input-port}))}.
|
||||
@end deffn
|
||||
|
||||
@deffn {Scheme Procedure} standard-input-port
|
||||
@deffnx {Scheme Procedure} standard-output-port
|
||||
@deffnx {Scheme Procedure} standard-error-port
|
||||
Returns a fresh binary input port connected to standard input, or a
|
||||
binary output port connected to the standard output or standard error,
|
||||
respectively. Whether the port supports the @code{port-position} and
|
||||
@code{set-port-position!} operations is implementation-dependent.
|
||||
@end deffn
|
||||
|
||||
@deffn {Scheme Procedure} current-input-port
|
||||
@deffnx {Scheme Procedure} current-output-port
|
||||
@deffnx {Scheme Procedure} current-error-port
|
||||
@xref{Default Ports}.
|
||||
@end deffn
|
||||
|
||||
@deffn {Scheme Procedure} open-bytevector-input-port bv [transcoder]
|
||||
@deffnx {Scheme Procedure} open-bytevector-output-port [transcoder]
|
||||
@xref{Bytevector Ports}.
|
||||
@end deffn
|
||||
|
||||
@deffn {Scheme Procedure} make-custom-binary-input-port id read! get-position set-position! close
|
||||
@deffnx {Scheme Procedure} make-custom-binary-output-port id write! get-position set-position! close
|
||||
@deffnx {Scheme Procedure} make-custom-binary-input/output-port id read! write! get-position set-position! close
|
||||
@xref{Custom Ports}.
|
||||
@end deffn
|
||||
|
||||
@deffn {Scheme Procedure} get-u8 port
|
||||
@deffnx {Scheme Procedure} lookahead-u8 port
|
||||
@deffnx {Scheme Procedure} get-bytevector-n port count
|
||||
@deffnx {Scheme Procedure} get-bytevector-n! port bv start count
|
||||
@deffnx {Scheme Procedure} get-bytevector-some port
|
||||
@deffnx {Scheme Procedure} get-bytevector-all port
|
||||
@deffnx {Scheme Procedure} put-u8 port octet
|
||||
@deffnx {Scheme Procedure} put-bytevector port bv [start [count]]
|
||||
@xref{Binary I/O}.
|
||||
@end deffn
|
||||
|
||||
@deffn {Scheme Procedure} get-char textual-input-port
|
||||
@deffnx {Scheme Procedure} lookahead-char textual-input-port
|
||||
@deffnx {Scheme Procedure} get-string-n textual-input-port count
|
||||
@deffnx {Scheme Procedure} get-string-n! textual-input-port string start count
|
||||
@deffnx {Scheme Procedure} get-string-all textual-input-port
|
||||
@deffnx {Scheme Procedure} get-line textual-input-port
|
||||
@deffnx {Scheme Procedure} put-char port char
|
||||
@deffnx {Scheme Procedure} put-string port string [start [count]]
|
||||
@xref{Textual I/O}.
|
||||
@end deffn
|
||||
|
||||
@deffn {Scheme Procedure} get-datum textual-input-port count
|
||||
Reads an external representation from @var{textual-input-port} and returns the
|
||||
datum it represents. The @code{get-datum} procedure returns the next
|
||||
datum that can be parsed from the given @var{textual-input-port}, updating
|
||||
@var{textual-input-port} to point exactly past the end of the external
|
||||
representation of the object.
|
||||
|
||||
Any @emph{interlexeme space} (comment or whitespace, @pxref{Scheme
|
||||
Syntax}) in the input is first skipped. If an end of file occurs after
|
||||
the interlexeme space, the end-of-file object is returned.
|
||||
|
||||
If a character inconsistent with an external representation is
|
||||
encountered in the input, an exception with condition types
|
||||
@code{&lexical} and @code{&i/o-read} is raised. Also, if the end of
|
||||
file is encountered after the beginning of an external representation,
|
||||
but the external representation is incomplete and therefore cannot be
|
||||
parsed, an exception with condition types @code{&lexical} and
|
||||
@code{&i/o-read} is raised.
|
||||
@end deffn
|
||||
|
||||
@deffn {Scheme Procedure} put-datum textual-output-port datum
|
||||
@var{datum} should be a datum value. The @code{put-datum} procedure
|
||||
writes an external representation of @var{datum} to
|
||||
@var{textual-output-port}. The specific external representation is
|
||||
implementation-dependent. However, whenever possible, an implementation
|
||||
should produce a representation for which @code{get-datum}, when reading
|
||||
the representation, will return an object equal (in the sense of
|
||||
@code{equal?}) to @var{datum}.
|
||||
|
||||
@quotation Note
|
||||
Not all datums may allow producing an external representation for which
|
||||
@code{get-datum} will produce an object that is equal to the
|
||||
original. Specifically, NaNs contained in @var{datum} may make
|
||||
this impossible.
|
||||
@end quotation
|
||||
|
||||
@quotation Note
|
||||
The @code{put-datum} procedure merely writes the external
|
||||
representation, but no trailing delimiter. If @code{put-datum} is
|
||||
used to write several subsequent external representations to an
|
||||
output port, care should be taken to delimit them properly so they can
|
||||
be read back in by subsequent calls to @code{get-datum}.
|
||||
@end quotation
|
||||
@end deffn
|
||||
|
||||
@deffn {Scheme Procedure} flush-output-port port
|
||||
@xref{Buffering}, for documentation on @code{force-output}.
|
||||
@end deffn
|
||||
|
||||
@node R6RS File Ports
|
||||
@subsubsection R6RS File Ports
|
||||
|
||||
The facilities described in this section are exported by the @code{(rnrs
|
||||
io ports)} module.
|
||||
|
||||
@deffn {Scheme Syntax} buffer-mode @var{buffer-mode-symbol}
|
||||
@var{buffer-mode-symbol} must be a symbol whose name is one of
|
||||
@code{none}, @code{line}, and @code{block}. The result is the
|
||||
corresponding symbol, and specifies the associated buffer mode.
|
||||
@xref{Buffering}, for a discussion of these different buffer modes. To
|
||||
control the amount of buffering, use @code{setvbuf} instead. Note that
|
||||
only the name of @var{buffer-mode-symbol} is significant.
|
||||
|
||||
@xref{Buffering}, for a discussion of port buffering.
|
||||
@end deffn
|
||||
|
||||
@deffn {Scheme Procedure} buffer-mode? obj
|
||||
Returns @code{#t} if the argument is a valid buffer-mode symbol, and
|
||||
returns @code{#f} otherwise.
|
||||
@end deffn
|
||||
|
||||
When opening a file, the various procedures accept a @code{file-options}
|
||||
object that encapsulates flags to specify how the file is to be
|
||||
opened. A @code{file-options} object is an enum-set (@pxref{rnrs enums})
|
||||
over the symbols constituting valid file options.
|
||||
|
||||
A @var{file-options} parameter name means that the corresponding
|
||||
argument must be a file-options object.
|
||||
|
||||
@deffn {Scheme Syntax} file-options @var{file-options-symbol} ...
|
||||
|
||||
Each @var{file-options-symbol} must be a symbol.
|
||||
|
||||
The @code{file-options} syntax returns a file-options object that
|
||||
encapsulates the specified options.
|
||||
|
||||
When supplied to an operation that opens a file for output, the
|
||||
file-options object returned by @code{(file-options)} specifies that the
|
||||
file is created if it does not exist and an exception with condition
|
||||
type @code{&i/o-file-already-exists} is raised if it does exist. The
|
||||
following standard options can be included to modify the default
|
||||
behavior.
|
||||
|
||||
@table @code
|
||||
@item no-create
|
||||
If the file does not already exist, it is not created;
|
||||
instead, an exception with condition type @code{&i/o-file-does-not-exist}
|
||||
is raised.
|
||||
If the file already exists, the exception with condition type
|
||||
@code{&i/o-file-already-exists} is not raised
|
||||
and the file is truncated to zero length.
|
||||
@item no-fail
|
||||
If the file already exists, the exception with condition type
|
||||
@code{&i/o-file-already-exists} is not raised,
|
||||
even if @code{no-create} is not included,
|
||||
and the file is truncated to zero length.
|
||||
@item no-truncate
|
||||
If the file already exists and the exception with condition type
|
||||
@code{&i/o-file-already-exists} has been inhibited by inclusion of
|
||||
@code{no-create} or @code{no-fail}, the file is not truncated, but
|
||||
the port's current position is still set to the beginning of the
|
||||
file.
|
||||
@end table
|
||||
|
||||
These options have no effect when a file is opened only for input.
|
||||
Symbols other than those listed above may be used as
|
||||
@var{file-options-symbol}s; they have implementation-specific meaning,
|
||||
if any.
|
||||
|
||||
@quotation Note
|
||||
Only the name of @var{file-options-symbol} is significant.
|
||||
@end quotation
|
||||
@end deffn
|
||||
|
||||
@deffn {Scheme Procedure} open-file-input-port filename
|
||||
@deffnx {Scheme Procedure} open-file-input-port filename file-options
|
||||
@deffnx {Scheme Procedure} open-file-input-port filename file-options buffer-mode
|
||||
@deffnx {Scheme Procedure} open-file-input-port filename file-options buffer-mode maybe-transcoder
|
||||
@var{maybe-transcoder} must be either a transcoder or @code{#f}.
|
||||
|
||||
The @code{open-file-input-port} procedure returns an
|
||||
input port for the named file. The @var{file-options} and
|
||||
@var{maybe-transcoder} arguments are optional.
|
||||
|
||||
The @var{file-options} argument, which may determine various aspects of
|
||||
the returned port, defaults to the value of @code{(file-options)}.
|
||||
|
||||
The @var{buffer-mode} argument, if supplied,
|
||||
must be one of the symbols that name a buffer mode.
|
||||
The @var{buffer-mode} argument defaults to @code{block}.
|
||||
|
||||
If @var{maybe-transcoder} is a transcoder, it becomes the transcoder associated
|
||||
with the returned port.
|
||||
|
||||
If @var{maybe-transcoder} is @code{#f} or absent,
|
||||
the port will be a binary port and will support the
|
||||
@code{port-position} and @code{set-port-position!} operations.
|
||||
Otherwise the port will be a textual port, and whether it supports
|
||||
the @code{port-position} and @code{set-port-position!} operations
|
||||
is implementation-dependent (and possibly transcoder-dependent).
|
||||
@end deffn
|
||||
|
||||
@deffn {Scheme Procedure} open-file-output-port filename
|
||||
@deffnx {Scheme Procedure} open-file-output-port filename file-options
|
||||
@deffnx {Scheme Procedure} open-file-output-port filename file-options buffer-mode
|
||||
@deffnx {Scheme Procedure} open-file-output-port filename file-options buffer-mode maybe-transcoder
|
||||
@var{maybe-transcoder} must be either a transcoder or @code{#f}.
|
||||
|
||||
The @code{open-file-output-port} procedure returns an output port for the named file.
|
||||
|
||||
The @var{file-options} argument, which may determine various aspects of
|
||||
the returned port, defaults to the value of @code{(file-options)}.
|
||||
|
||||
The @var{buffer-mode} argument, if supplied,
|
||||
must be one of the symbols that name a buffer mode.
|
||||
The @var{buffer-mode} argument defaults to @code{block}.
|
||||
|
||||
If @var{maybe-transcoder} is a transcoder, it becomes the transcoder
|
||||
associated with the port.
|
||||
|
||||
If @var{maybe-transcoder} is @code{#f} or absent,
|
||||
the port will be a binary port and will support the
|
||||
@code{port-position} and @code{set-port-position!} operations.
|
||||
Otherwise the port will be a textual port, and whether it supports
|
||||
the @code{port-position} and @code{set-port-position!} operations
|
||||
is implementation-dependent (and possibly transcoder-dependent).
|
||||
@end deffn
|
||||
|
||||
@node rnrs io simple
|
||||
@subsubsection rnrs io simple
|
||||
|
||||
The @code{(rnrs io simple (6))} library provides convenience functions
|
||||
for performing textual I/O on ports. This library also exports all of
|
||||
the condition types and associated procedures described in (@pxref{I/O
|
||||
Conditions}). In the context of this section, when stating that a
|
||||
the condition types and associated procedures described in (@pxref{R6RS
|
||||
I/O Conditions}). In the context of this section, when stating that a
|
||||
procedure behaves ``identically'' to the corresponding procedure in
|
||||
Guile's core library, this is modulo the behavior wrt. conditions: such
|
||||
procedures raise the appropriate R6RS conditions in case of error, but
|
||||
|
@ -1451,9 +1984,8 @@ appropriate R6RS conditions.
|
|||
|
||||
@deffn {Scheme Procedure} eof-object
|
||||
@deffnx {Scheme Procedure} eof-object? obj
|
||||
These procedures are identical to the ones provided by the
|
||||
@code{(rnrs io ports (6))} library. @xref{R6RS I/O Ports}, for
|
||||
documentation.
|
||||
These procedures are identical to the ones provided by the @code{(rnrs
|
||||
io ports (6))} library. @xref{rnrs io ports}, for documentation.
|
||||
@end deffn
|
||||
|
||||
@deffn {Scheme Procedure} input-port? obj
|
||||
|
@ -1474,8 +2006,8 @@ library. @xref{File Ports}, for documentation.
|
|||
|
||||
@deffn {Scheme Procedure} close-input-port input-port
|
||||
@deffnx {Scheme Procedure} close-output-port output-port
|
||||
These procedures are identical to the ones provided by Guile's core
|
||||
library. @xref{Closing}, for documentation.
|
||||
Closes the given @var{input-port} or @var{output-port}. These are
|
||||
legacy interfaces; just use @code{close-port}.
|
||||
@end deffn
|
||||
|
||||
@deffn {Scheme Procedure} peek-char
|
||||
|
@ -1483,7 +2015,7 @@ library. @xref{Closing}, for documentation.
|
|||
@deffnx {Scheme Procedure} read-char
|
||||
@deffnx {Scheme Procedure} read-char textual-input-port
|
||||
These procedures are identical to the ones provided by Guile's core
|
||||
library. @xref{Reading}, for documentation.
|
||||
library. @xref{Venerable Port Interfaces}, for documentation.
|
||||
@end deffn
|
||||
|
||||
@deffn {Scheme Procedure} read
|
||||
|
@ -1500,8 +2032,9 @@ This procedure is identical to the one provided by Guile's core library.
|
|||
@deffnx {Scheme Procedure} write obj textual-output-port
|
||||
@deffnx {Scheme Procedure} write-char char
|
||||
@deffnx {Scheme Procedure} write-char char textual-output-port
|
||||
These procedures are identical to the ones provided by Guile's core
|
||||
library. @xref{Writing}, for documentation.
|
||||
These procedures are identical to the ones provided by Guile's core
|
||||
library. @xref{Venerable Port Interfaces}, and @xref{Scheme Write}, for
|
||||
documentation.
|
||||
@end deffn
|
||||
|
||||
@node rnrs files
|
||||
|
|
|
@ -108,6 +108,8 @@ history-file yes Use history file.
|
|||
history-length 200 History length.
|
||||
bounce-parens 500 Time (ms) to show matching opening parenthesis
|
||||
(0 = off).
|
||||
bracketed-paste yes Disable interpretation of control characters
|
||||
in pastes.
|
||||
@end smalllisp
|
||||
|
||||
The readline options interface can only be used @emph{after} loading
|
||||
|
|
|
@ -484,7 +484,7 @@ moved to @ref{Curried Definitions}
|
|||
(It could be argued that the alternative @code{define} forms are rather
|
||||
confusing, especially for newcomers to the Scheme language, as they hide
|
||||
both the role of @code{lambda} and the fact that procedures are values
|
||||
that are stored in variables in the some way as any other kind of value.
|
||||
that are stored in variables in the same way as any other kind of value.
|
||||
On the other hand, they are very convenient, and they are also a good
|
||||
example of another of Scheme's powerful features: the ability to specify
|
||||
arbitrary syntactic transformations at run time, which can be applied to
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
Guile's core language is Scheme, which is specified and described in the
|
||||
series of reports known as @dfn{RnRS}. @dfn{RnRS} is shorthand for the
|
||||
@iftex
|
||||
@dfn{Revised$^n$ Report on the Algorithmic Language Scheme}.
|
||||
@dfn{Revised@math{^n} Report on the Algorithmic Language Scheme}.
|
||||
@end iftex
|
||||
@ifnottex
|
||||
@dfn{Revised^n Report on the Algorithmic Language Scheme}.
|
||||
|
|
|
@ -293,6 +293,11 @@ and exit.
|
|||
Load the file @file{/u/jimb/ex4}, and then call the function
|
||||
@code{main}, passing it the list @code{("/u/jimb/ex4" "foo")}.
|
||||
|
||||
@item guile -e '(ex4)' -s /u/jimb/ex4.scm foo
|
||||
Load the file @file{/u/jimb/ex4.scm}, and then call the function
|
||||
@code{main} from the module '(ex4)', passing it the list
|
||||
@code{("/u/jimb/ex4" "foo")}.
|
||||
|
||||
@item guile -l first -ds -l last -s script
|
||||
Load the files @file{first}, @file{script}, and @file{last}, in that
|
||||
order. The @code{-ds} switch says when to process the @code{-s}
|
||||
|
@ -369,6 +374,7 @@ Suppose that we now want to write a script which computes the
|
|||
@code{(choose @var{n} @var{m})} is the number of distinct subsets
|
||||
containing @var{n} objects each. It's easy to write @code{choose} given
|
||||
@code{fact}, so we might write the script this way:
|
||||
|
||||
@example
|
||||
#!/usr/local/bin/guile \
|
||||
-l fact -e main -s
|
||||
|
@ -402,6 +408,79 @@ $ ./choose 50 100
|
|||
100891344545564193334812497256
|
||||
@end example
|
||||
|
||||
To call a specific procedure from a given module, we can use the special
|
||||
form @code{(@@ (@var{module}) @var{procedure})}:
|
||||
|
||||
@example
|
||||
#!/usr/local/bin/guile \
|
||||
-l fact -e (@@ (fac) main) -s
|
||||
!#
|
||||
(define-module (fac)
|
||||
#:export (main))
|
||||
|
||||
(define (choose n m)
|
||||
(/ (fact m) (* (fact (- m n)) (fact n))))
|
||||
|
||||
(define (main args)
|
||||
(let ((n (string->number (cadr args)))
|
||||
(m (string->number (caddr args))))
|
||||
(display (choose n m))
|
||||
(newline)))
|
||||
@end example
|
||||
|
||||
We can use @code{@@@@} to invoke non-exported procedures. For exported
|
||||
procedures, we can simplify this call with the shorthand
|
||||
@code{(@var{module})}:
|
||||
|
||||
@example
|
||||
#!/usr/local/bin/guile \
|
||||
-l fact -e (fac) -s
|
||||
!#
|
||||
(define-module (fac)
|
||||
#:export (main))
|
||||
|
||||
(define (choose n m)
|
||||
(/ (fact m) (* (fact (- m n)) (fact n))))
|
||||
|
||||
(define (main args)
|
||||
(let ((n (string->number (cadr args)))
|
||||
(m (string->number (caddr args))))
|
||||
(display (choose n m))
|
||||
(newline)))
|
||||
@end example
|
||||
|
||||
For maximum portability, we can instead use the shell to execute
|
||||
@command{guile} with specified command line arguments. Here we need to
|
||||
take care to quote the command arguments correctly:
|
||||
|
||||
@example
|
||||
#!/usr/bin/env sh
|
||||
exec guile -l fact -e '(@@ (fac) main)' -s "$0" "$@@"
|
||||
!#
|
||||
(define-module (fac)
|
||||
#:export (main))
|
||||
|
||||
(define (choose n m)
|
||||
(/ (fact m) (* (fact (- m n)) (fact n))))
|
||||
|
||||
(define (main args)
|
||||
(let ((n (string->number (cadr args)))
|
||||
(m (string->number (caddr args))))
|
||||
(display (choose n m))
|
||||
(newline)))
|
||||
@end example
|
||||
|
||||
Finally, seasoned scripters are probably missing a mention of
|
||||
subprocesses. In Bash, for example, most shell scripts run other
|
||||
programs like @code{sed} or the like to do the actual work.
|
||||
|
||||
In Guile it's often possible get everything done within Guile itself, so
|
||||
do give that a try first. But if you just need to run a program and
|
||||
wait for it to finish, use @code{system*}. If you need to run a
|
||||
sub-program and capture its output, or give it input, use
|
||||
@code{open-pipe}. @xref{Processes}, and @xref{Pipes}, for more
|
||||
information.
|
||||
|
||||
|
||||
@c Local Variables:
|
||||
@c TeX-master: "guile.texi"
|
||||
|
|
|
@ -294,8 +294,12 @@ Disassemble a file.
|
|||
Time execution.
|
||||
@end deffn
|
||||
|
||||
@deffn {REPL Command} profile exp
|
||||
Profile execution.
|
||||
@deffn {REPL Command} profile exp [#:hz hz=100] @
|
||||
[#:count-calls? count-calls?=#f] [#:display-style display-style=list]
|
||||
Profile execution of an expression. This command compiled @var{exp} and
|
||||
then runs it within the statprof profiler, passing all keyword options
|
||||
to the @code{statprof} procedure. For more on statprof and on the the
|
||||
options available to this command, @xref{Statprof}.
|
||||
@end deffn
|
||||
|
||||
@deffn {REPL Command} trace exp [#:width w] [#:max-indent i]
|
||||
|
@ -341,10 +345,6 @@ Show the selected frame. With an argument, select a frame by index,
|
|||
then show it.
|
||||
@end deffn
|
||||
|
||||
@deffn {REPL Command} procedure
|
||||
Print the procedure for the selected frame.
|
||||
@end deffn
|
||||
|
||||
@deffn {REPL Command} locals
|
||||
Show local variables.
|
||||
|
||||
|
@ -793,7 +793,7 @@ packages will be
|
|||
|
||||
Note that a @code{.go} file will only be loaded in preference to a
|
||||
@code{.scm} file if it is newer. For that reason, you should install
|
||||
your Scheme files first, and your compiled files second. @code{Load
|
||||
your Scheme files first, and your compiled files second. @xref{Load
|
||||
Paths}, for more on the loading process.
|
||||
|
||||
Finally, although this section is only about Scheme, sometimes you need
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
@c -*-texinfo-*-
|
||||
@c This is part of the GNU Guile Reference Manual.
|
||||
@c Copyright (C) 1996, 1997, 2000-2004, 2006, 2007-2014
|
||||
@c Copyright (C) 1996, 1997, 2000-2004, 2006, 2007-2014, 2017
|
||||
@c Free Software Foundation, Inc.
|
||||
@c See the file guile.texi for copying conditions.
|
||||
|
||||
|
@ -150,6 +150,7 @@ The Guile core has the following features,
|
|||
@example
|
||||
guile
|
||||
guile-2 ;; starting from Guile 2.x
|
||||
guile-2.2 ;; starting from Guile 2.2
|
||||
r5rs
|
||||
srfi-0
|
||||
srfi-4
|
||||
|
@ -1823,8 +1824,8 @@ procedures easier. It is documented in @xref{Multiple Values}.
|
|||
|
||||
This SRFI is a syntax for defining new record types and creating
|
||||
predicate, constructor, and field getter and setter functions. It is
|
||||
documented in the ``Compound Data Types'' section of the manual
|
||||
(@pxref{SRFI-9 Records}).
|
||||
documented in the ``Data Types'' section of the manual (@pxref{SRFI-9
|
||||
Records}).
|
||||
|
||||
|
||||
@node SRFI-10
|
||||
|
@ -1834,9 +1835,9 @@ documented in the ``Compound Data Types'' section of the manual
|
|||
@cindex hash-comma
|
||||
@cindex #,()
|
||||
This SRFI implements a reader extension @code{#,()} called hash-comma.
|
||||
It allows the reader to give new kinds of objects, for use both in
|
||||
data and as constants or literals in source code. This feature is
|
||||
available with
|
||||
It allows the reader to give new kinds of objects, for use both in data
|
||||
and as constants or literals in source code. This feature is available
|
||||
with
|
||||
|
||||
@example
|
||||
(use-modules (srfi srfi-10))
|
||||
|
@ -1894,73 +1895,46 @@ addition,
|
|||
(display #,(sum 123 456)) @print{} 579
|
||||
@end example
|
||||
|
||||
A typical use for @nicode{#,()} is to get a read syntax for objects
|
||||
which don't otherwise have one. For example, the following allows a
|
||||
hash table to be given literally, with tags and values, ready for fast
|
||||
lookup.
|
||||
|
||||
@example
|
||||
(define-reader-ctor 'hash
|
||||
(lambda elems
|
||||
(let ((table (make-hash-table)))
|
||||
(for-each (lambda (elem)
|
||||
(apply hash-set! table elem))
|
||||
elems)
|
||||
table)))
|
||||
|
||||
(define (animal->family animal)
|
||||
(hash-ref '#,(hash ("tiger" "cat")
|
||||
("lion" "cat")
|
||||
("wolf" "dog"))
|
||||
animal))
|
||||
|
||||
(animal->family "lion") @result{} "cat"
|
||||
@end example
|
||||
|
||||
Or for example the following is a syntax for a compiled regular
|
||||
expression (@pxref{Regular Expressions}).
|
||||
|
||||
@example
|
||||
(use-modules (ice-9 regex))
|
||||
|
||||
(define-reader-ctor 'regexp make-regexp)
|
||||
|
||||
(define (extract-angs str)
|
||||
(let ((match (regexp-exec '#,(regexp "<([A-Z0-9]+)>") str)))
|
||||
(and match
|
||||
(match:substring match 1))))
|
||||
|
||||
(extract-angs "foo <BAR> quux") @result{} "BAR"
|
||||
@end example
|
||||
|
||||
@sp 1
|
||||
@nicode{#,()} is somewhat similar to @code{define-macro}
|
||||
(@pxref{Macros}) in that handler code is run to produce a result, but
|
||||
@nicode{#,()} operates at the read stage, so it can appear in data for
|
||||
@code{read} (@pxref{Scheme Read}), not just in code to be executed.
|
||||
|
||||
Because @nicode{#,()} is handled at read-time it has no direct access
|
||||
to variables etc. A symbol in the arguments is just a symbol, not a
|
||||
variable reference. The arguments are essentially constants, though
|
||||
the handler procedure can use them in any complicated way it might
|
||||
want.
|
||||
|
||||
Once @code{(srfi srfi-10)} has loaded, @nicode{#,()} is available
|
||||
globally, there's no need to use @code{(srfi srfi-10)} in later
|
||||
modules. Similarly the tags registered are global and can be used
|
||||
anywhere once registered.
|
||||
|
||||
There's no attempt to record what previous @nicode{#,()} forms have
|
||||
been seen, if two identical forms occur then two calls are made to the
|
||||
handler procedure. The handler might like to maintain a cache or
|
||||
similar to avoid making copies of large objects, depending on expected
|
||||
usage.
|
||||
We do not recommend @nicode{#,()} reader extensions, however, and for
|
||||
three reasons.
|
||||
|
||||
In code the best uses of @nicode{#,()} are generally when there's a
|
||||
lot of objects of a particular kind as literals or constants. If
|
||||
there's just a few then some local variables and initializers are
|
||||
fine, but that becomes tedious and error prone when there's a lot, and
|
||||
the anonymous and compact syntax of @nicode{#,()} is much better.
|
||||
First of all, this SRFI is not modular: the tag is matched by name, not
|
||||
as an identifier within a scope. Defining a reader extension in one
|
||||
part of a program can thus affect unrelated parts of a program because
|
||||
the tag is not scoped.
|
||||
|
||||
Secondly, reader extensions can be hard to manage from a time
|
||||
perspective: when does the reader extension take effect? @xref{Eval
|
||||
When}, for more discussion.
|
||||
|
||||
Finally, reader extensions can easily produce objects that can't be
|
||||
reified to an object file by the compiler. For example if you define a
|
||||
reader extension that makes a hash table (@pxref{Hash Tables}), then it
|
||||
will work fine when run with the interpreter, and you think you have a
|
||||
neat hack. But then if you try to compile your program, after wrangling
|
||||
with the @code{eval-when} concerns mentioned above, the compiler will
|
||||
carp that it doesn't know how to serialize a hash table to disk.
|
||||
|
||||
In the specific case of hash tables, it would be possible for Guile to
|
||||
know how to pack hash tables into compiled files, but this doesn't work
|
||||
in general. What if the object you produce is an instance of a record
|
||||
type? Guile would then have to serialize the record type to disk too,
|
||||
and then what happens if the program independently loads the code that
|
||||
defines the record type? Does it define the same type or a different
|
||||
type? Guile's record types are nominal, not structural, so the answer
|
||||
is not clear at all.
|
||||
|
||||
For all of these reasons we recommend macros over reader extensions.
|
||||
Macros fulfill many of the same needs while preserving modular
|
||||
composition, and their interaction with @code{eval-when} is well-known.
|
||||
If you need brevity, instead use @code{read-hash-extend} and make your
|
||||
reader extension expand to a macro invocation. In that way we preserve
|
||||
scoping as much as possible. @xref{Reader Extensions}.
|
||||
|
||||
|
||||
@node SRFI-11
|
||||
|
@ -2087,14 +2061,12 @@ library. The functions and variables described here are provided by
|
|||
(use-modules (srfi srfi-18))
|
||||
@end example
|
||||
|
||||
As a general rule, the data types and functions in this SRFI-18
|
||||
implementation are compatible with the types and functions in Guile's
|
||||
core threading code. For example, mutexes created with the SRFI-18
|
||||
@code{make-mutex} function can be passed to the built-in Guile
|
||||
function @code{lock-mutex} (@pxref{Mutexes and Condition Variables}),
|
||||
and mutexes created with the built-in Guile function @code{make-mutex}
|
||||
can be passed to the SRFI-18 function @code{mutex-lock!}. Cases in
|
||||
which this does not hold true are noted in the following sections.
|
||||
SRFI-18 defines facilities for threads, mutexes, condition variables,
|
||||
time, and exception handling. Because these facilities are at a higher
|
||||
level than Guile's primitives, they are implemented as a layer on top of
|
||||
what Guile provides. In particular this means that a Guile mutex is not
|
||||
a SRFI-18 mutex, and a Guile thread is not a SRFI-18 thread, and so on.
|
||||
Guile provides a set of primitives and SRFI-18 is one of the systems built in terms of those primitives.
|
||||
|
||||
@menu
|
||||
* SRFI-18 Threads:: Executing code
|
||||
|
@ -2112,8 +2084,10 @@ Guile's built-in thread functions. First, a thread created by SRFI-18
|
|||
@code{make-thread} begins in a blocked state and will not start
|
||||
execution until @code{thread-start!} is called on it. Second, SRFI-18
|
||||
threads are constructed with a top-level exception handler that
|
||||
captures any exceptions that are thrown on thread exit. In all other
|
||||
regards, SRFI-18 threads are identical to normal Guile threads.
|
||||
captures any exceptions that are thrown on thread exit.
|
||||
|
||||
SRFI-18 threads are disjoint from Guile's primitive threads.
|
||||
@xref{Threads}, for more on Guile's primitive facility.
|
||||
|
||||
@defun current-thread
|
||||
Returns the thread that called this function. This is the same
|
||||
|
@ -2206,41 +2180,28 @@ original exception can be retrieved using
|
|||
@node SRFI-18 Mutexes
|
||||
@subsubsection SRFI-18 Mutexes
|
||||
|
||||
The behavior of Guile's built-in mutexes is parameterized via a set of
|
||||
flags passed to the @code{make-mutex} procedure in the core
|
||||
(@pxref{Mutexes and Condition Variables}). To satisfy the requirements
|
||||
for mutexes specified by SRFI-18, the @code{make-mutex} procedure
|
||||
described below sets the following flags:
|
||||
@itemize @bullet
|
||||
@item
|
||||
@code{recursive}: the mutex can be locked recursively
|
||||
@item
|
||||
@code{unchecked-unlock}: attempts to unlock a mutex that is already
|
||||
unlocked will not raise an exception
|
||||
@item
|
||||
@code{allow-external-unlock}: the mutex can be unlocked by any thread,
|
||||
not just the thread that locked it originally
|
||||
@end itemize
|
||||
SRFI-18 mutexes are disjoint from Guile's primitive mutexes.
|
||||
@xref{Mutexes and Condition Variables}, for more on Guile's primitive
|
||||
facility.
|
||||
|
||||
@defun make-mutex [name]
|
||||
Returns a new mutex, optionally assigning it the object name
|
||||
@var{name}, which may be any Scheme object. The returned mutex will be
|
||||
created with the configuration described above. Note that the name
|
||||
@code{make-mutex} conflicts with Guile core function @code{make-mutex}.
|
||||
Applications wanting to use both of these functions will need to refer
|
||||
to them by different names.
|
||||
Returns a new mutex, optionally assigning it the object name @var{name},
|
||||
which may be any Scheme object. The returned mutex will be created with
|
||||
the configuration described above.
|
||||
@end defun
|
||||
|
||||
@defun mutex-name mutex
|
||||
Returns the name assigned to @var{mutex} at the time of its creation,
|
||||
or @code{#f} if it was not given a name.
|
||||
Returns the name assigned to @var{mutex} at the time of its creation, or
|
||||
@code{#f} if it was not given a name.
|
||||
@end defun
|
||||
|
||||
@defun mutex-specific mutex
|
||||
@defunx mutex-specific-set! mutex obj
|
||||
Get or set the ``object-specific'' property of @var{mutex}. In Guile's
|
||||
implementation of SRFI-18, this value is stored as an object property,
|
||||
and will be @code{#f} if not set.
|
||||
Return the ``object-specific'' property of @var{mutex}, or @code{#f} if
|
||||
none is set.
|
||||
@end defun
|
||||
|
||||
@defun mutex-specific-set! mutex obj
|
||||
Set the ``object-specific'' property of @var{mutex}.
|
||||
@end defun
|
||||
|
||||
@defun mutex-state mutex
|
||||
|
@ -2248,8 +2209,8 @@ Returns information about the state of @var{mutex}. Possible values
|
|||
are:
|
||||
@itemize @bullet
|
||||
@item
|
||||
thread @code{T}: the mutex is in the locked/owned state and thread T
|
||||
is the owner of the mutex
|
||||
thread @var{t}: the mutex is in the locked/owned state and thread
|
||||
@var{t} is the owner of the mutex
|
||||
@item
|
||||
symbol @code{not-owned}: the mutex is in the locked/not-owned state
|
||||
@item
|
||||
|
@ -2263,17 +2224,14 @@ unlocked/not-abandoned state
|
|||
@defun mutex-lock! mutex [timeout [thread]]
|
||||
Lock @var{mutex}, optionally specifying a time object @var{timeout}
|
||||
after which to abort the lock attempt and a thread @var{thread} giving
|
||||
a new owner for @var{mutex} different than the current thread. This
|
||||
procedure has the same behavior as the @code{lock-mutex} procedure in
|
||||
the core library.
|
||||
a new owner for @var{mutex} different than the current thread.
|
||||
@end defun
|
||||
|
||||
@defun mutex-unlock! mutex [condition-variable [timeout]]
|
||||
Unlock @var{mutex}, optionally specifying a condition variable
|
||||
@var{condition-variable} on which to wait, either indefinitely or,
|
||||
optionally, until the time object @var{timeout} has passed, to be
|
||||
signalled. This procedure has the same behavior as the
|
||||
@code{unlock-mutex} procedure in the core library.
|
||||
signalled.
|
||||
@end defun
|
||||
|
||||
|
||||
|
@ -2282,20 +2240,20 @@ signalled. This procedure has the same behavior as the
|
|||
|
||||
SRFI-18 does not specify a ``wait'' function for condition variables.
|
||||
Waiting on a condition variable can be simulated using the SRFI-18
|
||||
@code{mutex-unlock!} function described in the previous section, or
|
||||
Guile's built-in @code{wait-condition-variable} procedure can be used.
|
||||
@code{mutex-unlock!} function described in the previous section.
|
||||
|
||||
SRFI-18 condition variables are disjoint from Guile's primitive
|
||||
condition variables. @xref{Mutexes and Condition Variables}, for more
|
||||
on Guile's primitive facility.
|
||||
|
||||
@defun condition-variable? obj
|
||||
Returns @code{#t} if @var{obj} is a condition variable, @code{#f}
|
||||
otherwise. This is the same procedure as the same-named built-in
|
||||
procedure
|
||||
(@pxref{Mutexes and Condition Variables, @code{condition-variable?}}).
|
||||
otherwise.
|
||||
@end defun
|
||||
|
||||
@defun make-condition-variable [name]
|
||||
Returns a new condition variable, optionally assigning it the object
|
||||
name @var{name}, which may be any Scheme object. This procedure
|
||||
replaces a procedure of the same name in the core library.
|
||||
name @var{name}, which may be any Scheme object.
|
||||
@end defun
|
||||
|
||||
@defun condition-variable-name condition-variable
|
||||
|
@ -2304,21 +2262,19 @@ creation, or @code{#f} if it was not given a name.
|
|||
@end defun
|
||||
|
||||
@defun condition-variable-specific condition-variable
|
||||
@defunx condition-variable-specific-set! condition-variable obj
|
||||
Get or set the ``object-specific'' property of
|
||||
@var{condition-variable}. In Guile's implementation of SRFI-18, this
|
||||
value is stored as an object property, and will be @code{#f} if not
|
||||
set.
|
||||
Return the ``object-specific'' property of @var{condition-variable}, or
|
||||
@code{#f} if none is set.
|
||||
@end defun
|
||||
|
||||
@defun condition-variable-specific-set! condition-variable obj
|
||||
Set the ``object-specific'' property of @var{condition-variable}.
|
||||
@end defun
|
||||
|
||||
@defun condition-variable-signal! condition-variable
|
||||
@defunx condition-variable-broadcast! condition-variable
|
||||
Wake up one thread that is waiting for @var{condition-variable}, in
|
||||
the case of @code{condition-variable-signal!}, or all threads waiting
|
||||
for it, in the case of @code{condition-variable-broadcast!}. The
|
||||
behavior of these procedures is equivalent to that of the procedures
|
||||
@code{signal-condition-variable} and
|
||||
@code{broadcast-condition-variable} in the core library.
|
||||
for it, in the case of @code{condition-variable-broadcast!}.
|
||||
@end defun
|
||||
|
||||
|
||||
|
@ -2427,17 +2383,6 @@ functions and variables described here are provided by
|
|||
(use-modules (srfi srfi-19))
|
||||
@end example
|
||||
|
||||
@strong{Caution}: The current code in this module incorrectly extends
|
||||
the Gregorian calendar leap year rule back prior to the introduction
|
||||
of those reforms in 1582 (or the appropriate year in various
|
||||
countries). The Julian calendar was used prior to 1582, and there
|
||||
were 10 days skipped for the reform, but the code doesn't implement
|
||||
that.
|
||||
|
||||
This will be fixed some time. Until then calculations for 1583
|
||||
onwards are correct, but prior to that any day/month/year and day of
|
||||
the week calculations are wrong.
|
||||
|
||||
@menu
|
||||
* SRFI-19 Introduction::
|
||||
* SRFI-19 Time::
|
||||
|
@ -2637,6 +2582,16 @@ The fields are year, month, day, hour, minute, second, nanoseconds and
|
|||
timezone. A date object is immutable, its fields can be read but they
|
||||
cannot be modified once the object is created.
|
||||
|
||||
Historically, the Gregorian calendar was only used from the latter part
|
||||
of the year 1582 onwards, and not until even later in many countries.
|
||||
Prior to that most countries used the Julian calendar. SRFI-19 does
|
||||
not deal with the Julian calendar at all, and so does not reflect this
|
||||
historical calendar reform. Instead it projects the Gregorian calendar
|
||||
back proleptically as far as necessary. When dealing with historical
|
||||
data, especially prior to the British Empire's adoption of the Gregorian
|
||||
calendar in 1752, one should be mindful of which calendar is used in
|
||||
each context, and apply non-SRFI-19 facilities to convert where necessary.
|
||||
|
||||
@defun date? obj
|
||||
Return @code{#t} if @var{obj} is a date object, or @code{#f} if not.
|
||||
@end defun
|
||||
|
@ -3302,8 +3257,8 @@ Insert a newline.
|
|||
Insert a tilde.
|
||||
@end table
|
||||
|
||||
This procedure is the same as calling @code{simple-format} (@pxref{Writing})
|
||||
with @code{#f} as the destination.
|
||||
This procedure is the same as calling @code{simple-format}
|
||||
(@pxref{Simple Output}) with @code{#f} as the destination.
|
||||
@end deffn
|
||||
|
||||
@node SRFI-30
|
||||
|
|
|
@ -1,225 +1,121 @@
|
|||
@c -*-texinfo-*-
|
||||
@c This is part of the GNU Guile Reference Manual.
|
||||
@c Copyright (C) 2013, 2015 Free Software Foundation, Inc.
|
||||
@c Copyright (C) 2013, 2015, 2017 Free Software Foundation, Inc.
|
||||
@c See the file guile.texi for copying conditions.
|
||||
|
||||
@node Statprof
|
||||
@section Statprof
|
||||
|
||||
@code{(statprof)} is a fairly simple statistical profiler for Guile.
|
||||
Statprof is a statistical profiler for Guile.
|
||||
|
||||
A simple use of statprof would look like this:
|
||||
|
||||
@example
|
||||
(statprof-reset 0 50000 #t)
|
||||
(statprof-start)
|
||||
(do-something)
|
||||
(statprof-stop)
|
||||
(statprof-display)
|
||||
@example
|
||||
(use-modules (statprof))
|
||||
(statprof (lambda ()
|
||||
(map 1+ (iota 1000000))
|
||||
#f))
|
||||
@end example
|
||||
|
||||
This would reset statprof, clearing all accumulated statistics, then
|
||||
start profiling, run some code, stop profiling, and finally display a
|
||||
gprof flat-style table of statistics which will look something like
|
||||
this:
|
||||
This would run the thunk with statistical profiling, finally displaying
|
||||
a flat table of statistics which could look something like this:
|
||||
|
||||
@example
|
||||
% cumulative self self total
|
||||
time seconds seconds calls ms/call ms/call name
|
||||
35.29 0.23 0.23 2002 0.11 0.11 -
|
||||
23.53 0.15 0.15 2001 0.08 0.08 positive?
|
||||
23.53 0.15 0.15 2000 0.08 0.08 +
|
||||
11.76 0.23 0.08 2000 0.04 0.11 do-nothing
|
||||
5.88 0.64 0.04 2001 0.02 0.32 loop
|
||||
0.00 0.15 0.00 1 0.00 150.59 do-something
|
||||
...
|
||||
@example
|
||||
% cumulative self
|
||||
time seconds seconds procedure
|
||||
57.14 39769.73 0.07 ice-9/boot-9.scm:249:5:map1
|
||||
28.57 0.04 0.04 ice-9/boot-9.scm:1165:0:iota
|
||||
14.29 0.02 0.02 1+
|
||||
0.00 0.12 0.00 <current input>:2:10
|
||||
---
|
||||
Sample count: 7
|
||||
Total time: 0.123490713 seconds (0.201983993 seconds in GC)
|
||||
@end example
|
||||
|
||||
All of the numerical data with the exception of the calls column is
|
||||
statistically approximate. In the following column descriptions, and in
|
||||
all of statprof, "time" refers to execution time (both user and system),
|
||||
not wall clock time.
|
||||
all of statprof, ``time'' refers to execution time (both user and
|
||||
system), not wall clock time.
|
||||
|
||||
@table @asis
|
||||
@item % time
|
||||
The percent of the time spent inside the procedure itself (not counting
|
||||
children).
|
||||
The @code{% time} column indicates the percentage of the run-time time
|
||||
spent inside the procedure itself (not counting children). It is
|
||||
calculated as @code{self seconds}, measuring the amount of time spent in
|
||||
the procedure, divided by the total run-time.
|
||||
|
||||
@item cumulative seconds
|
||||
The total number of seconds spent in the procedure, including children.
|
||||
@code{cumulative seconds} also counts time spent in children of a
|
||||
function. For recursive functions, this can exceed the total time, as
|
||||
in our example above, because each activation on the stack adds to the
|
||||
cumulative time.
|
||||
|
||||
@item self seconds
|
||||
The total number of seconds spent in the procedure itself (not counting
|
||||
children).
|
||||
Finally, the GC time measures the time spent in the garbage collector.
|
||||
On systems with multiple cores, this time can be larger than the run
|
||||
time, because it counts time spent in all threads, and will run the
|
||||
``marking'' phase of GC in parallel. If GC time is a significant
|
||||
fraction of the run time, that means that most time in your program is
|
||||
spent allocating objects and cleaning up after those allocations. To
|
||||
speed up your program, one good place to start would be to look at how
|
||||
to reduce the allocation rate.
|
||||
|
||||
@item calls
|
||||
The total number of times the procedure was called.
|
||||
Statprof's main mode of operation is as a statistical profiler. However
|
||||
statprof can also run in a ``precise'' mode as well. Pass the
|
||||
@code{#:count-calls? #t} keyword argument to @code{statprof} to record
|
||||
all calls:
|
||||
|
||||
@item self ms/call
|
||||
The average time taken by the procedure itself on each call, in ms.
|
||||
@example
|
||||
(use-modules (statprof))
|
||||
(statprof (lambda ()
|
||||
(map 1+ (iota 1000000))
|
||||
#f)
|
||||
#:count-calls? #t)
|
||||
@end example
|
||||
|
||||
@item total ms/call
|
||||
The average time taken by each call to the procedure, including time
|
||||
spent in child functions.
|
||||
The result has an additional @code{calls} column:
|
||||
|
||||
@item name
|
||||
The name of the procedure.
|
||||
@example
|
||||
% cumulative self
|
||||
time seconds seconds calls procedure
|
||||
82.26 0.73 0.73 1000000 1+
|
||||
11.29 420925.80 0.10 1000001 ice-9/boot-9.scm:249:5:map1
|
||||
4.84 0.06 0.04 1 ice-9/boot-9.scm:1165:0:iota
|
||||
[...]
|
||||
---
|
||||
Sample count: 62
|
||||
Total time: 0.893098065 seconds (1.222796536 seconds in GC)
|
||||
@end example
|
||||
|
||||
@end table
|
||||
As you can see, the profile is perturbed: @code{1+} ends up on top,
|
||||
whereas it was not marked as hot in the earlier profile. This is
|
||||
because the overhead of call-counting unfairly penalizes calls. Still,
|
||||
this precise mode can be useful at times to do algorithmic optimizations
|
||||
based on the precise call counts.
|
||||
|
||||
The profiler uses @code{eq?} and the procedure object itself to identify
|
||||
the procedures, so it won't confuse different procedures with the same
|
||||
name. They will show up as two different rows in the output.
|
||||
@heading Implementation notes
|
||||
|
||||
Right now the profiler is quite simplistic. I cannot provide call-graphs
|
||||
or other higher level information. What you see in the table is pretty
|
||||
much all there is. Patches are welcome :-)
|
||||
|
||||
@section Implementation notes
|
||||
The profiler works by setting the unix profiling signal
|
||||
@code{ITIMER_PROF} to go off after the interval you define in the call
|
||||
to @code{statprof-reset}. When the signal fires, a sampling routine is
|
||||
run which looks at the current procedure that's executing, and then
|
||||
crawls up the stack, and for each procedure encountered, increments that
|
||||
procedure's sample count. Note that if a procedure is encountered
|
||||
multiple times on a given stack, it is only counted once. After the
|
||||
sampling is complete, the profiler resets profiling timer to fire again
|
||||
after the appropriate interval.
|
||||
to @code{statprof-reset}. When the signal fires, a sampling routine
|
||||
runs which crawls up the stack, recording all instruction pointers into
|
||||
a buffer. After the sample is complete, the profiler resets profiling
|
||||
timer to fire again after the appropriate interval.
|
||||
|
||||
Meanwhile, the profiler keeps track, via @code{get-internal-run-time},
|
||||
how much CPU time (system and user -- which is also what
|
||||
@code{ITIMER_PROF} tracks), has elapsed while code has been executing
|
||||
within a statprof-start/stop block.
|
||||
Later, when profiling stops, that log buffer is analyzed to produce the
|
||||
``self seconds'' and ``cumulative seconds'' statistics. A procedure at
|
||||
the top of the stack counts toward ``self'' samples, and everything on
|
||||
the stack counts towards ``cumulative'' samples.
|
||||
|
||||
The profiler also tries to avoid counting or timing its own code as much
|
||||
as possible.
|
||||
While the profiler is running it measures how much CPU time (system and
|
||||
user -- which is also what @code{ITIMER_PROF} tracks) has elapsed while
|
||||
code has been executing within the profiler. Only run time counts
|
||||
towards the profile, not wall-clock time. For example, sleeping and
|
||||
waiting for input or output do not cause the timer clock to advance.
|
||||
|
||||
@section Usage
|
||||
@anchor{statprof statprof-active?}@defun statprof-active?
|
||||
Returns @code{#t} if @code{statprof-start} has been called more times
|
||||
than @code{statprof-stop}, @code{#f} otherwise.
|
||||
@heading Usage
|
||||
|
||||
@end defun
|
||||
|
||||
@anchor{statprof statprof-start}@defun statprof-start
|
||||
Start the profiler.@code{}
|
||||
|
||||
@end defun
|
||||
|
||||
@anchor{statprof statprof-stop}@defun statprof-stop
|
||||
Stop the profiler.@code{}
|
||||
|
||||
@end defun
|
||||
|
||||
@anchor{statprof statprof-reset}@defun statprof-reset sample-seconds sample-microseconds count-calls? [full-stacks?]
|
||||
Reset the statprof sampler interval to @var{sample-seconds} and
|
||||
@var{sample-microseconds}. If @var{count-calls?} is true, arrange to
|
||||
instrument procedure calls as well as collecting statistical profiling
|
||||
data. If @var{full-stacks?} is true, collect all sampled stacks into a
|
||||
list for later analysis.
|
||||
|
||||
Enables traps and debugging as necessary.
|
||||
|
||||
@end defun
|
||||
|
||||
@anchor{statprof statprof-accumulated-time}@defun statprof-accumulated-time
|
||||
Returns the time accumulated during the last statprof run.@code{}
|
||||
|
||||
@end defun
|
||||
|
||||
@anchor{statprof statprof-sample-count}@defun statprof-sample-count
|
||||
Returns the number of samples taken during the last statprof run.@code{}
|
||||
|
||||
@end defun
|
||||
|
||||
@anchor{statprof statprof-fold-call-data}@defun statprof-fold-call-data proc init
|
||||
Fold @var{proc} over the call-data accumulated by statprof. Cannot be
|
||||
called while statprof is active. @var{proc} should take two arguments,
|
||||
@code{(@var{call-data} @var{prior-result})}.
|
||||
|
||||
Note that a given proc-name may appear multiple times, but if it does,
|
||||
it represents different functions with the same name.
|
||||
|
||||
@end defun
|
||||
|
||||
@anchor{statprof statprof-proc-call-data}@defun statprof-proc-call-data proc
|
||||
Returns the call-data associated with @var{proc}, or @code{#f} if none
|
||||
is available.
|
||||
|
||||
@end defun
|
||||
|
||||
@anchor{statprof statprof-call-data-name}@defun statprof-call-data-name cd
|
||||
@end defun
|
||||
|
||||
@anchor{statprof statprof-call-data-calls}@defun statprof-call-data-calls cd
|
||||
@end defun
|
||||
|
||||
@anchor{statprof statprof-call-data-cum-samples}@defun statprof-call-data-cum-samples cd
|
||||
@end defun
|
||||
|
||||
@anchor{statprof statprof-call-data-self-samples}@defun statprof-call-data-self-samples cd
|
||||
@end defun
|
||||
|
||||
@anchor{statprof statprof-call-data->stats}@defun statprof-call-data->stats call-data
|
||||
Returns an object of type @code{statprof-stats}.
|
||||
|
||||
@end defun
|
||||
|
||||
@anchor{statprof statprof-stats-proc-name}@defun statprof-stats-proc-name stats
|
||||
@end defun
|
||||
|
||||
@anchor{statprof statprof-stats-%-time-in-proc}@defun statprof-stats-%-time-in-proc stats
|
||||
@end defun
|
||||
|
||||
@anchor{statprof statprof-stats-cum-secs-in-proc}@defun statprof-stats-cum-secs-in-proc stats
|
||||
@end defun
|
||||
|
||||
@anchor{statprof statprof-stats-self-secs-in-proc}@defun statprof-stats-self-secs-in-proc stats
|
||||
@end defun
|
||||
|
||||
@anchor{statprof statprof-stats-calls}@defun statprof-stats-calls stats
|
||||
@end defun
|
||||
|
||||
@anchor{statprof statprof-stats-self-secs-per-call}@defun statprof-stats-self-secs-per-call stats
|
||||
@end defun
|
||||
|
||||
@anchor{statprof statprof-stats-cum-secs-per-call}@defun statprof-stats-cum-secs-per-call stats
|
||||
@end defun
|
||||
|
||||
@anchor{statprof statprof-display}@defun statprof-display . _
|
||||
Displays a gprof-like summary of the statistics collected. Unless an
|
||||
optional @var{port} argument is passed, uses the current output port.
|
||||
|
||||
@end defun
|
||||
|
||||
@anchor{statprof statprof-display-anomolies}@defun statprof-display-anomolies
|
||||
A sanity check that attempts to detect anomolies in statprof's
|
||||
statistics.@code{}
|
||||
|
||||
@end defun
|
||||
|
||||
@anchor{statprof statprof-fetch-stacks}@defun statprof-fetch-stacks
|
||||
Returns a list of stacks, as they were captured since the last call to
|
||||
@code{statprof-reset}.
|
||||
|
||||
Note that stacks are only collected if the @var{full-stacks?} argument
|
||||
to @code{statprof-reset} is true.
|
||||
|
||||
@end defun
|
||||
|
||||
@anchor{statprof statprof-fetch-call-tree}@defun statprof-fetch-call-tree
|
||||
@verbatim
|
||||
Return a call tree for the previous statprof run.
|
||||
|
||||
The return value is a list of nodes, each of which is of the type:
|
||||
@@code
|
||||
node ::= (@@var@{proc@} @@var@{count@} . @@var@{nodes@})
|
||||
@@end code
|
||||
@end verbatim
|
||||
|
||||
@end defun
|
||||
|
||||
@anchor{statprof statprof}@defun statprof thunk [#:loop] [#:hz] [#:count-calls?] [#:full-stacks?]
|
||||
@deffn {Scheme Procedure} statprof thunk @
|
||||
[#:loop loop=1] [#:hz hz=100] @
|
||||
[#:port port=(current-output-port)] @
|
||||
[#:count-calls? count-calls?=#f] @
|
||||
[#:display-style display-style='flat]
|
||||
Profile the execution of @var{thunk}, and return its return values.
|
||||
|
||||
The stack will be sampled @var{hz} times per second, and the thunk
|
||||
|
@ -228,57 +124,131 @@ itself will be called @var{loop} times.
|
|||
If @var{count-calls?} is true, all procedure calls will be recorded.
|
||||
This operation is somewhat expensive.
|
||||
|
||||
If @var{full-stacks?} is true, at each sample, statprof will store away
|
||||
the whole call tree, for later analysis. Use
|
||||
@code{statprof-fetch-stacks} or @code{statprof-fetch-call-tree} to
|
||||
retrieve the last-stored stacks.
|
||||
After the @var{thunk} has been profiled, print out a profile to
|
||||
@var{port}. If @var{display-style} is @code{flat}, the results will be
|
||||
printed as a flat profile. Otherwise if @var{display-style} is
|
||||
@code{tree}, print the results as a tree profile.
|
||||
|
||||
@end defun
|
||||
Note that @code{statprof} requires a working profiling timer. Some
|
||||
platforms do not support profiling timers. @code{(provided?
|
||||
'ITIMER_PROF)} can be used to check for support of profiling timers.
|
||||
@end deffn
|
||||
|
||||
@anchor{statprof with-statprof}@defspec with-statprof args
|
||||
Profile the expressions in the body, and return the body's return
|
||||
value.
|
||||
Profiling can also be enabled and disabled manually.
|
||||
|
||||
Keyword arguments:
|
||||
@deffn {Scheme Procedure} statprof-active?
|
||||
Returns @code{#t} if @code{statprof-start} has been called more times
|
||||
than @code{statprof-stop}, @code{#f} otherwise.
|
||||
@end deffn
|
||||
|
||||
@deffn {Scheme Procedure} statprof-start
|
||||
@deffnx {Scheme Procedure} statprof-stop
|
||||
Start or stop the profiler.
|
||||
@end deffn
|
||||
|
||||
@deffn {Scheme Procedure} statprof-reset sample-seconds sample-microseconds count-calls?
|
||||
Reset the profiling sample interval to @var{sample-seconds} and
|
||||
@var{sample-microseconds}. If @var{count-calls?} is true, arrange to
|
||||
instrument procedure calls as well as collecting statistical profiling
|
||||
data.
|
||||
@end deffn
|
||||
|
||||
If you use the manual @code{statprof-start}/@code{statprof-stop}
|
||||
interface, an implicit statprof state will persist starting from the
|
||||
last call to @code{statprof-reset}, or the first call to
|
||||
@code{statprof-start}. There are a number of accessors to fetch
|
||||
statistics from this implicit state.
|
||||
|
||||
@deffn {Scheme Procedure} statprof-accumulated-time
|
||||
Returns the time accumulated during the last statprof run.
|
||||
@end deffn
|
||||
|
||||
@deffn {Scheme Procedure} statprof-sample-count
|
||||
Returns the number of samples taken during the last statprof run.
|
||||
@end deffn
|
||||
|
||||
@deffn {Scheme Procedure} statprof-fold-call-data proc init
|
||||
Fold @var{proc} over the call-data accumulated by statprof. This
|
||||
procedure cannot be called while statprof is active.
|
||||
|
||||
@var{proc} will be called with arguments, @var{call-data} and
|
||||
@var{prior-result}.
|
||||
@end deffn
|
||||
|
||||
@deffn {Scheme Procedure} statprof-proc-call-data proc
|
||||
Returns the call-data associated with @var{proc}, or @code{#f} if none
|
||||
is available.
|
||||
@end deffn
|
||||
|
||||
@deffn {Scheme Procedure} statprof-call-data-name cd
|
||||
@deffnx {Scheme Procedure} statprof-call-data-calls cd
|
||||
@deffnx {Scheme Procedure} statprof-call-data-cum-samples cd
|
||||
@deffnx {Scheme Procedure} statprof-call-data-self-samples cd
|
||||
Accessors for the fields in a statprof call-data object.
|
||||
@end deffn
|
||||
|
||||
@deffn {Scheme Procedure} statprof-call-data->stats call-data
|
||||
Returns an object of type @code{statprof-stats}.
|
||||
@end deffn
|
||||
|
||||
@deffn {Scheme Procedure} statprof-stats-proc-name stats
|
||||
@deffnx {Scheme Procedure} statprof-stats-%-time-in-proc stats
|
||||
@deffnx {Scheme Procedure} statprof-stats-cum-secs-in-proc stats
|
||||
@deffnx {Scheme Procedure} statprof-stats-self-secs-in-proc stats
|
||||
@deffnx {Scheme Procedure} statprof-stats-calls stats
|
||||
@deffnx {Scheme Procedure} statprof-stats-self-secs-per-call stats
|
||||
@deffnx {Scheme Procedure} statprof-stats-cum-secs-per-call stats
|
||||
Accessors for the fields in a @code{statprof-stats} object.
|
||||
@end deffn
|
||||
|
||||
@deffn {Scheme Procedure} statprof-display @
|
||||
[port=(current-output-port)] [#:style style=flat]
|
||||
Displays a summary of the statistics collected. Possible values for
|
||||
@var{style} include:
|
||||
|
||||
@table @code
|
||||
@item #:loop
|
||||
Execute the body @var{loop} number of times, or @code{#f} for no looping
|
||||
|
||||
default: @code{#f}
|
||||
|
||||
@item #:hz
|
||||
Sampling rate
|
||||
|
||||
default: @code{20}
|
||||
|
||||
@item #:count-calls?
|
||||
Whether to instrument each function call (expensive)
|
||||
|
||||
default: @code{#f}
|
||||
|
||||
@item #:full-stacks?
|
||||
Whether to collect away all sampled stacks into a list
|
||||
|
||||
default: @code{#f}
|
||||
|
||||
@item flat
|
||||
Display a traditional gprof-style flat profile.
|
||||
@item anomalies
|
||||
Find statistical anomalies in the data.
|
||||
@item tree
|
||||
Display a tree profile.
|
||||
@end table
|
||||
@end deffn
|
||||
|
||||
@end defspec
|
||||
@deffn {Scheme Procedure} statprof-fetch-stacks
|
||||
Returns a list of stacks, as they were captured since the last call to
|
||||
@code{statprof-reset}.
|
||||
@end deffn
|
||||
|
||||
@anchor{statprof gcprof}@defun gcprof thunk [#:loop] [#:full-stacks?]
|
||||
Do an allocation profile of the execution of @var{thunk}.
|
||||
@deffn {Scheme Procedure} statprof-fetch-call-tree [#:precise precise?=#f]
|
||||
@verbatim
|
||||
Return a call tree for the previous statprof run.
|
||||
|
||||
The stack will be sampled soon after every garbage collection, yielding
|
||||
an approximate idea of what is causing allocation in your program.
|
||||
The return value is a list of nodes. A node is a list of the form:
|
||||
@code
|
||||
node ::= (@var{proc} @var{count} . @var{nodes})
|
||||
@end code
|
||||
|
||||
The @var{proc} is a printable representation of a procedure, as a
|
||||
string. If @var{precise?} is false, which is the default, then a node
|
||||
corresponds to a procedure invocation. If it is true, then a node
|
||||
corresponds to a return point in a procedure. Passing @code{#:precise?
|
||||
#t} allows a user to distinguish different source lines in a procedure,
|
||||
but usually it is too much detail, so it is off by default.
|
||||
@end verbatim
|
||||
|
||||
@end deffn
|
||||
|
||||
@deffn {Scheme Procedure} gcprof thunk [#:loop]
|
||||
Like the @code{statprof} procedure, but instead of profiling CPU time,
|
||||
we profile garbage collection.
|
||||
|
||||
The stack will be sampled soon after every garbage collection during the
|
||||
evaluation of @var{thunk}, yielding an approximate idea of what is
|
||||
causing allocation in your program.
|
||||
|
||||
Since GC does not occur very frequently, you may need to use the
|
||||
@var{loop} parameter, to cause @var{thunk} to be called @var{loop}
|
||||
times.
|
||||
|
||||
If @var{full-stacks?} is true, at each sample, statprof will store away
|
||||
the whole call tree, for later analysis. Use
|
||||
@code{statprof-fetch-stacks} or @code{statprof-fetch-call-tree} to
|
||||
retrieve the last-stored stacks.
|
||||
|
||||
@end defun
|
||||
@end deffn
|
||||
|
|
|
@ -147,7 +147,7 @@ expressions which are evaluated if the pattern is successfully match. The
|
|||
example above matches an element @code{e} with an attribute @code{i} and three
|
||||
children.
|
||||
|
||||
Pattern variables are must be ``unquoted'' in the pattern. The above expression
|
||||
Pattern variables must be ``unquoted'' in the pattern. The above expression
|
||||
binds @var{d} to @code{1}, @var{a} to @code{3}, @var{b} to @code{4}, and @var{c}
|
||||
to @code{5}.
|
||||
|
||||
|
|
|
@ -1,8 +1,12 @@
|
|||
@c -*-texinfo-*-
|
||||
@c This is part of the GNU Guile Reference Manual.
|
||||
@c Copyright (C) 2013 Free Software Foundation, Inc.
|
||||
@c Copyright (C) 2013, 2017 Free Software Foundation, Inc.
|
||||
@c See the file guile.texi for copying conditions.
|
||||
|
||||
@c SXPath documentation based on SXPath.scm by Oleg Kiselyov,
|
||||
@c which is in the public domain according to <http://okmij.org/ftp/>
|
||||
@c and <http://ssax.sourceforge.net/>.
|
||||
|
||||
@node SXML
|
||||
@section SXML
|
||||
|
||||
|
@ -17,7 +21,7 @@ fragment:
|
|||
may be represented with the following SXML:
|
||||
|
||||
@example
|
||||
(parrot (@@ (type "African Grey)) (name "Alfie"))
|
||||
(parrot (@@ (type "African Grey")) (name "Alfie"))
|
||||
@end example
|
||||
|
||||
SXML is very general, and is capable of representing all of XML.
|
||||
|
@ -28,14 +32,14 @@ Guile includes several facilities for working with XML and SXML:
|
|||
parsers, serializers, and transformers.
|
||||
|
||||
@menu
|
||||
* SXML Overview:: XML, as it was meant to be
|
||||
* Reading and Writing XML:: Convenient XML parsing and serializing
|
||||
* SSAX:: Custom functional-style XML parsers
|
||||
* Transforming SXML:: Munging SXML with @code{pre-post-order}
|
||||
* SXML Tree Fold:: Fold-based SXML transformations
|
||||
* SXPath:: XPath for SXML
|
||||
* sxml apply-templates:: A more XSLT-like approach to SXML transformations
|
||||
* sxml ssax input-parse:: The SSAX tokenizer, optimized for Guile
|
||||
* SXML Overview:: XML, as it was meant to be
|
||||
* Reading and Writing XML:: Convenient XML parsing and serializing
|
||||
* SSAX:: Custom functional-style XML parsers
|
||||
* Transforming SXML:: Munging SXML with @code{pre-post-order}
|
||||
* SXML Tree Fold:: Fold-based SXML transformations
|
||||
* SXPath:: XPath for SXML
|
||||
* sxml ssax input-parse:: The SSAX tokenizer, optimized for Guile
|
||||
* sxml apply-templates:: A more XSLT-like approach to SXML transformations
|
||||
@end menu
|
||||
|
||||
@node SXML Overview
|
||||
|
@ -250,8 +254,8 @@ internal and external parsed entities, user-controlled handling of
|
|||
whitespace, and validation. This module therefore is intended to be a
|
||||
framework, a set of ``Lego blocks'' you can use to build a parser
|
||||
following any discipline and performing validation to any degree. As an
|
||||
example of the parser construction, this file includes a semi-validating
|
||||
SXML parser.
|
||||
example of the parser construction, the source file includes a
|
||||
semi-validating SXML parser.
|
||||
|
||||
SSAX has a ``sequential'' feel of SAX yet a ``functional style'' of DOM.
|
||||
Like a SAX parser, the framework scans the document only once and
|
||||
|
@ -271,7 +275,7 @@ the middle- and high-level parsers are single-threaded through the
|
|||
the @var{seed} in any way: they simply pass it around as an instance of
|
||||
an opaque datatype. User functions, on the other hand, can use the seed
|
||||
to maintain user's state, to accumulate parsing results, etc. A user
|
||||
can freely mix his own functions with those of the framework. On the
|
||||
can freely mix their own functions with those of the framework. On the
|
||||
other hand, the user may wish to instantiate a high-level parser:
|
||||
@code{SSAX:make-elem-parser} or @code{SSAX:make-parser}. In the latter
|
||||
case, the user must provide functions of specific signatures, which are
|
||||
|
@ -576,7 +580,7 @@ A traversal combinator in the spirit of @code{pre-post-order}.
|
|||
|
||||
@example
|
||||
bindings := (<binding>...)
|
||||
binding := (<tag> <bandler-pair>...)
|
||||
binding := (<tag> <handler-pair>...)
|
||||
| (*default* . <post-handler>)
|
||||
| (*text* . <text-handler>)
|
||||
tag := <symbol>
|
||||
|
@ -725,95 +729,323 @@ location path is a relative path applied to the root node.
|
|||
Similarly to XPath, SXPath defines full and abbreviated notations for
|
||||
location paths. In both cases, the abbreviated notation can be
|
||||
mechanically expanded into the full form by simple rewriting rules. In
|
||||
case of SXPath the corresponding rules are given as comments to a sxpath
|
||||
function, below. The regression test suite at the end of this file shows
|
||||
a representative sample of SXPaths in both notations, juxtaposed with
|
||||
the corresponding XPath expressions. Most of the samples are borrowed
|
||||
literally from the XPath specification, while the others are adjusted
|
||||
for our running example, tree1.
|
||||
the case of SXPath the corresponding rules are given in the
|
||||
documentation of the @code{sxpath} procedure.
|
||||
@xref{sxpath-procedure-docs,,SXPath procedure documentation}.
|
||||
|
||||
The regression test suite at the end of the file @file{SXPATH-old.scm}
|
||||
shows a representative sample of SXPaths in both notations, juxtaposed
|
||||
with the corresponding XPath expressions. Most of the samples are
|
||||
borrowed literally from the XPath specification.
|
||||
|
||||
Much of the following material is taken from the SXPath sources by Oleg
|
||||
Kiselyov et al.
|
||||
|
||||
@subsubsection Basic Converters and Applicators
|
||||
|
||||
A converter is a function mapping a nodeset (or a single node) to another
|
||||
nodeset. Its type can be represented like this:
|
||||
|
||||
@example
|
||||
type Converter = Node|Nodeset -> Nodeset
|
||||
@end example
|
||||
|
||||
A converter can also play the role of a predicate: in that case, if a
|
||||
converter, applied to a node or a nodeset, yields a non-empty nodeset,
|
||||
the converter-predicate is deemed satisfied. Likewise, an empty nodeset
|
||||
is equivalent to @code{#f} in denoting failure.
|
||||
|
||||
@subsubsection Usage
|
||||
@deffn {Scheme Procedure} nodeset? x
|
||||
Return @code{#t} if @var{x} is a nodeset.
|
||||
@end deffn
|
||||
|
||||
@deffn {Scheme Procedure} node-typeof? crit
|
||||
This function implements a 'Node test' as defined in Sec. 2.3 of the
|
||||
XPath document. A node test is one of the components of a location
|
||||
step. It is also a converter-predicate in SXPath.
|
||||
|
||||
The function @code{node-typeof?} takes a type criterion and returns a
|
||||
function, which, when applied to a node, will tell if the node satisfies
|
||||
the test.
|
||||
|
||||
The criterion @var{crit} is a symbol, one of the following:
|
||||
|
||||
@table @code
|
||||
@item id
|
||||
tests if the node has the right name (id)
|
||||
|
||||
@item @@
|
||||
tests if the node is an <attributes-coll>
|
||||
|
||||
@item *
|
||||
tests if the node is an <Element>
|
||||
|
||||
@item *text*
|
||||
tests if the node is a text node
|
||||
|
||||
@item *PI*
|
||||
tests if the node is a PI (processing instruction) node
|
||||
|
||||
@item *any*
|
||||
@code{#t} for any type of node
|
||||
@end table
|
||||
@end deffn
|
||||
|
||||
@deffn {Scheme Procedure} node-eq? other
|
||||
A curried equivalence converter predicate that takes a node @var{other}
|
||||
and returns a function that takes another node. The two nodes are
|
||||
compared using @code{eq?}.
|
||||
@end deffn
|
||||
|
||||
@deffn {Scheme Procedure} node-equal? other
|
||||
A curried equivalence converter predicate that takes a node @var{other}
|
||||
and returns a function that takes another node. The two nodes are
|
||||
compared using @code{equal?}.
|
||||
@end deffn
|
||||
|
||||
@deffn {Scheme Procedure} node-pos n
|
||||
Select the @var{n}'th element of a nodeset and return as a singular
|
||||
nodeset. If the @var{n}'th element does not exist, return an empty
|
||||
nodeset. If @var{n} is a negative number the node is picked from the
|
||||
tail of the list.
|
||||
|
||||
@example
|
||||
((node-pos 1) nodeset) ; return the the head of the nodeset (if exists)
|
||||
((node-pos 2) nodeset) ; return the node after that (if exists)
|
||||
((node-pos -1) nodeset) ; selects the last node of a non-empty nodeset
|
||||
((node-pos -2) nodeset) ; selects the last but one node, if exists.
|
||||
@end example
|
||||
@end deffn
|
||||
|
||||
@deffn {Scheme Procedure} filter pred?
|
||||
@verbatim
|
||||
-- Scheme Procedure: filter pred list
|
||||
Return all the elements of 2nd arg LIST that satisfy predicate
|
||||
PRED. The list is not disordered - elements that appear in the
|
||||
result list occur in the same order as they occur in the argument
|
||||
list. The returned list may share a common tail with the argument
|
||||
list. The dynamic order in which the various applications of pred
|
||||
are made is not specified.
|
||||
|
||||
(filter even? '(0 7 8 8 43 -4)) => (0 8 8 -4)
|
||||
|
||||
|
||||
@end verbatim
|
||||
A filter applicator, which introduces a filtering context. The argument
|
||||
converter @var{pred?} is considered a predicate, with either @code{#f}
|
||||
or @code{nil} meaning failure.
|
||||
@end deffn
|
||||
|
||||
@deffn {Scheme Procedure} take-until pred?
|
||||
@example
|
||||
take-until:: Converter -> Converter, or
|
||||
take-until:: Pred -> Node|Nodeset -> Nodeset
|
||||
@end example
|
||||
|
||||
Given a converter-predicate @var{pred?} and a nodeset, apply the
|
||||
predicate to each element of the nodeset, until the predicate yields
|
||||
anything but @code{#f} or @code{nil}. Return the elements of the input
|
||||
nodeset that have been processed until that moment (that is, which fail
|
||||
the predicate).
|
||||
|
||||
@code{take-until} is a variation of the @code{filter} above:
|
||||
@code{take-until} passes elements of an ordered input set up to (but not
|
||||
including) the first element that satisfies the predicate. The nodeset
|
||||
returned by @code{((take-until (not pred)) nset)} is a subset -- to be
|
||||
more precise, a prefix -- of the nodeset returned by @code{((filter
|
||||
pred) nset)}.
|
||||
@end deffn
|
||||
|
||||
@deffn {Scheme Procedure} take-after pred?
|
||||
@example
|
||||
take-after:: Converter -> Converter, or
|
||||
take-after:: Pred -> Node|Nodeset -> Nodeset
|
||||
@end example
|
||||
|
||||
Given a converter-predicate @var{pred?} and a nodeset, apply the
|
||||
predicate to each element of the nodeset, until the predicate yields
|
||||
anything but @code{#f} or @code{nil}. Return the elements of the input
|
||||
nodeset that have not been processed: that is, return the elements of
|
||||
the input nodeset that follow the first element that satisfied the
|
||||
predicate.
|
||||
|
||||
@code{take-after} along with @code{take-until} partition an input
|
||||
nodeset into three parts: the first element that satisfies a predicate,
|
||||
all preceding elements and all following elements.
|
||||
@end deffn
|
||||
|
||||
@deffn {Scheme Procedure} map-union proc lst
|
||||
Apply @var{proc} to each element of @var{lst} and return the list of results.
|
||||
If @var{proc} returns a nodeset, splice it into the result
|
||||
|
||||
From another point of view, @code{map-union} is a function
|
||||
@code{Converter->Converter}, which places an argument-converter in a joining
|
||||
context.
|
||||
@end deffn
|
||||
|
||||
@deffn {Scheme Procedure} node-reverse node-or-nodeset
|
||||
@example
|
||||
node-reverse :: Converter, or
|
||||
node-reverse:: Node|Nodeset -> Nodeset
|
||||
@end example
|
||||
|
||||
Reverses the order of nodes in the nodeset. This basic converter is
|
||||
needed to implement a reverse document order (see the XPath
|
||||
Recommendation).
|
||||
@end deffn
|
||||
|
||||
@deffn {Scheme Procedure} node-trace title
|
||||
@example
|
||||
node-trace:: String -> Converter
|
||||
@end example
|
||||
|
||||
@code{(node-trace title)} is an identity converter. In addition it
|
||||
prints out the node or nodeset it is applied to, prefixed with the
|
||||
@var{title}. This converter is very useful for debugging.
|
||||
@end deffn
|
||||
|
||||
@subsubsection Converter Combinators
|
||||
|
||||
Combinators are higher-order functions that transmogrify a converter or
|
||||
glue a sequence of converters into a single, non-trivial converter. The
|
||||
goal is to arrive at converters that correspond to XPath location paths.
|
||||
|
||||
From a different point of view, a combinator is a fixed, named
|
||||
@dfn{pattern} of applying converters. Given below is a complete set of
|
||||
such patterns that together implement XPath location path specification.
|
||||
As it turns out, all these combinators can be built from a small number
|
||||
of basic blocks: regular functional composition, @code{map-union} and
|
||||
@code{filter} applicators, and the nodeset union.
|
||||
|
||||
@deffn {Scheme Procedure} select-kids test-pred?
|
||||
@code{select-kids} takes a converter (or a predicate) as an argument and
|
||||
returns another converter. The resulting converter applied to a nodeset
|
||||
returns an ordered subset of its children that satisfy the predicate
|
||||
@var{test-pred?}.
|
||||
@end deffn
|
||||
|
||||
@deffn {Scheme Procedure} node-self pred?
|
||||
@verbatim
|
||||
-- Scheme Procedure: filter pred list
|
||||
Return all the elements of 2nd arg LIST that satisfy predicate
|
||||
PRED. The list is not disordered - elements that appear in the
|
||||
result list occur in the same order as they occur in the argument
|
||||
list. The returned list may share a common tail with the argument
|
||||
list. The dynamic order in which the various applications of pred
|
||||
are made is not specified.
|
||||
|
||||
(filter even? '(0 7 8 8 43 -4)) => (0 8 8 -4)
|
||||
|
||||
|
||||
@end verbatim
|
||||
Similar to @code{select-kids} except that the predicate @var{pred?} is
|
||||
applied to the node itself rather than to its children. The resulting
|
||||
nodeset will contain either one component, or will be empty if the node
|
||||
failed the predicate.
|
||||
@end deffn
|
||||
|
||||
@deffn {Scheme Procedure} node-join . selectors
|
||||
@example
|
||||
node-join:: [LocPath] -> Node|Nodeset -> Nodeset, or
|
||||
node-join:: [Converter] -> Converter
|
||||
@end example
|
||||
|
||||
Join the sequence of location steps or paths as described above.
|
||||
@end deffn
|
||||
|
||||
@deffn {Scheme Procedure} node-reduce . converters
|
||||
@example
|
||||
node-reduce:: [LocPath] -> Node|Nodeset -> Nodeset, or
|
||||
node-reduce:: [Converter] -> Converter
|
||||
@end example
|
||||
|
||||
A regular functional composition of converters. From a different point
|
||||
of view, @code{((apply node-reduce converters) nodeset)} is equivalent
|
||||
to @code{(foldl apply nodeset converters)}, i.e., folding, or reducing,
|
||||
a list of converters with the nodeset as a seed.
|
||||
@end deffn
|
||||
|
||||
@deffn {Scheme Procedure} node-or . converters
|
||||
@example
|
||||
node-or:: [Converter] -> Converter
|
||||
@end example
|
||||
|
||||
This combinator applies all converters to a given node and produces the
|
||||
union of their results. This combinator corresponds to a union
|
||||
(@code{|} operation) for XPath location paths.
|
||||
@end deffn
|
||||
|
||||
@deffn {Scheme Procedure} node-closure test-pred?
|
||||
@example
|
||||
node-closure:: Converter -> Converter
|
||||
@end example
|
||||
|
||||
Select all @emph{descendants} of a node that satisfy a
|
||||
converter-predicate @var{test-pred?}. This combinator is similar to
|
||||
@code{select-kids} but applies to grand... children as well. This
|
||||
combinator implements the @code{descendant::} XPath axis. Conceptually,
|
||||
this combinator can be expressed as
|
||||
|
||||
@example
|
||||
(define (node-closure f)
|
||||
(node-or
|
||||
(select-kids f)
|
||||
(node-reduce (select-kids (node-typeof? '*)) (node-closure f))))
|
||||
@end example
|
||||
|
||||
This definition, as written, looks somewhat like a fixpoint, and it will
|
||||
run forever. It is obvious however that sooner or later
|
||||
@code{(select-kids (node-typeof? '*))} will return an empty nodeset. At
|
||||
this point further iterations will no longer affect the result and can
|
||||
be stopped.
|
||||
@end deffn
|
||||
|
||||
@deffn {Scheme Procedure} node-parent rootnode
|
||||
@example
|
||||
node-parent:: RootNode -> Converter
|
||||
@end example
|
||||
|
||||
@code{(node-parent rootnode)} yields a converter that returns a parent
|
||||
of a node it is applied to. If applied to a nodeset, it returns the
|
||||
list of parents of nodes in the nodeset. The @var{rootnode} does not
|
||||
have to be the root node of the whole SXML tree -- it may be a root node
|
||||
of a branch of interest.
|
||||
|
||||
Given the notation of Philip Wadler's paper on semantics of XSLT,
|
||||
|
||||
@verbatim
|
||||
parent(x) = { y | y=subnode*(root), x=subnode(y) }
|
||||
@end verbatim
|
||||
|
||||
Therefore, @code{node-parent} is not the fundamental converter: it can
|
||||
be expressed through the existing ones. Yet @code{node-parent} is a
|
||||
rather convenient converter. It corresponds to a @code{parent::} axis
|
||||
of SXPath. Note that the @code{parent::} axis can be used with an
|
||||
attribute node as well.
|
||||
@end deffn
|
||||
|
||||
@anchor{sxpath-procedure-docs}
|
||||
@deffn {Scheme Procedure} sxpath path
|
||||
Evaluate an abbreviated SXPath.
|
||||
|
||||
@example
|
||||
sxpath:: AbbrPath -> Converter, or
|
||||
sxpath:: AbbrPath -> Node|Nodeset -> Nodeset
|
||||
@end example
|
||||
|
||||
@var{path} is a list. It is translated to the full SXPath according to
|
||||
the following rewriting rules:
|
||||
|
||||
@example
|
||||
(sxpath '())
|
||||
@result{} (node-join)
|
||||
|
||||
(sxpath '(path-component ...))
|
||||
@result{} (node-join (sxpath1 path-component) (sxpath '(...)))
|
||||
|
||||
(sxpath1 '//)
|
||||
@result{} (node-or
|
||||
(node-self (node-typeof? '*any*))
|
||||
(node-closure (node-typeof? '*any*)))
|
||||
|
||||
(sxpath1 '(equal? x))
|
||||
@result{} (select-kids (node-equal? x))
|
||||
|
||||
(sxpath1 '(eq? x))
|
||||
@result{} (select-kids (node-eq? x))
|
||||
|
||||
(sxpath1 ?symbol)
|
||||
@result{} (select-kids (node-typeof? ?symbol)
|
||||
|
||||
(sxpath1 procedure)
|
||||
@result{} procedure
|
||||
|
||||
(sxpath1 '(?symbol ...))
|
||||
@result{} (sxpath1 '((?symbol) ...))
|
||||
|
||||
(sxpath1 '(path reducer ...))
|
||||
@result{} (node-reduce (sxpath path) (sxpathr reducer) ...)
|
||||
|
||||
(sxpathr number)
|
||||
@result{} (node-pos number)
|
||||
|
||||
(sxpathr path-filter)
|
||||
@result{} (filter (sxpath path-filter))
|
||||
@end example
|
||||
@end deffn
|
||||
|
||||
@node sxml ssax input-parse
|
||||
|
|
791
doc/ref/vm.texi
791
doc/ref/vm.texi
File diff suppressed because it is too large
Load diff
155
doc/ref/web.texi
155
doc/ref/web.texi
|
@ -173,23 +173,13 @@ Guile provides a standard data type for Universal Resource Identifiers
|
|||
The generic URI syntax is as follows:
|
||||
|
||||
@example
|
||||
URI := scheme ":" ["//" [userinfo "@@"] host [":" port]] path \
|
||||
[ "?" query ] [ "#" fragment ]
|
||||
URI-reference := [scheme ":"] ["//" [userinfo "@@"] host [":" port]] path \
|
||||
[ "?" query ] [ "#" fragment ]
|
||||
@end example
|
||||
|
||||
For example, in the URI, @indicateurl{http://www.gnu.org/help/}, the
|
||||
scheme is @code{http}, the host is @code{www.gnu.org}, the path is
|
||||
@code{/help/}, and there is no userinfo, port, query, or fragment. All
|
||||
URIs have a scheme and a path (though the path might be empty). Some
|
||||
URIs have a host, and some of those have ports and userinfo. Any URI
|
||||
might have a query part or a fragment.
|
||||
|
||||
There is also a ``URI-reference'' data type, which is the same as a URI
|
||||
but where the scheme is optional. In this case, the scheme is taken to
|
||||
be relative to some other related URI. A common use of URI references
|
||||
is when you want to be vague regarding the choice of HTTP or HTTPS --
|
||||
serving a web page referring to @code{/foo.css} will use HTTPS if loaded
|
||||
over HTTPS, or HTTP otherwise.
|
||||
@code{/help/}, and there is no userinfo, port, query, or fragment.
|
||||
|
||||
Userinfo is something of an abstraction, as some legacy URI schemes
|
||||
allowed userinfo of the form @code{@var{username}:@var{passwd}}. But
|
||||
|
@ -197,14 +187,6 @@ since passwords do not belong in URIs, the RFC does not want to condone
|
|||
this practice, so it calls anything before the @code{@@} sign
|
||||
@dfn{userinfo}.
|
||||
|
||||
Properly speaking, a fragment is not part of a URI. For example, when a
|
||||
web browser follows a link to @indicateurl{http://example.com/#foo}, it
|
||||
sends a request for @indicateurl{http://example.com/}, then looks in the
|
||||
resulting page for the fragment identified @code{foo} reference. A
|
||||
fragment identifies a part of a resource, not the resource itself. But
|
||||
it is useful to have a fragment field in the URI record itself, so we
|
||||
hope you will forgive the inconsistency.
|
||||
|
||||
@example
|
||||
(use-modules (web uri))
|
||||
@end example
|
||||
|
@ -213,40 +195,36 @@ The following procedures can be found in the @code{(web uri)}
|
|||
module. Load it into your Guile, using a form like the above, to have
|
||||
access to them.
|
||||
|
||||
The most common way to build a URI from Scheme is with the
|
||||
@code{build-uri} function.
|
||||
|
||||
@deffn {Scheme Procedure} build-uri scheme @
|
||||
[#:userinfo=@code{#f}] [#:host=@code{#f}] [#:port=@code{#f}] @
|
||||
[#:path=@code{""}] [#:query=@code{#f}] [#:fragment=@code{#f}] @
|
||||
[#:validate?=@code{#t}]
|
||||
Construct a URI object. @var{scheme} should be a symbol, @var{port}
|
||||
either a positive, exact integer or @code{#f}, and the rest of the
|
||||
fields are either strings or @code{#f}. If @var{validate?} is true,
|
||||
also run some consistency checks to make sure that the constructed URI
|
||||
is valid.
|
||||
Construct a URI. @var{scheme} should be a symbol, @var{port} either a
|
||||
positive, exact integer or @code{#f}, and the rest of the fields are
|
||||
either strings or @code{#f}. If @var{validate?} is true, also run some
|
||||
consistency checks to make sure that the constructed URI is valid.
|
||||
@end deffn
|
||||
|
||||
@deffn {Scheme Procedure} build-uri-reference [#:scheme=@code{#f}]@
|
||||
[#:userinfo=@code{#f}] [#:host=@code{#f}] [#:port=@code{#f}] @
|
||||
[#:path=@code{""}] [#:query=@code{#f}] [#:fragment=@code{#f}] @
|
||||
[#:validate?=@code{#t}]
|
||||
Like @code{build-uri}, but with an optional scheme.
|
||||
@end deffn
|
||||
|
||||
In Guile, both URI and URI reference data types are represented in the
|
||||
same way, as URI objects.
|
||||
|
||||
@deffn {Scheme Procedure} uri? obj
|
||||
@deffnx {Scheme Procedure} uri-scheme uri
|
||||
Return @code{#t} if @var{obj} is a URI.
|
||||
@end deffn
|
||||
|
||||
Guile, URIs are represented as URI records, with a number of associated
|
||||
accessors.
|
||||
|
||||
@deffn {Scheme Procedure} uri-scheme uri
|
||||
@deffnx {Scheme Procedure} uri-userinfo uri
|
||||
@deffnx {Scheme Procedure} uri-host uri
|
||||
@deffnx {Scheme Procedure} uri-port uri
|
||||
@deffnx {Scheme Procedure} uri-path uri
|
||||
@deffnx {Scheme Procedure} uri-query uri
|
||||
@deffnx {Scheme Procedure} uri-fragment uri
|
||||
A predicate and field accessors for the URI record type. The URI scheme
|
||||
will be a symbol, or @code{#f} if the object is a URI reference but not
|
||||
a URI. The port will be either a positive, exact integer or @code{#f},
|
||||
and the rest of the fields will be either strings or @code{#f} if not
|
||||
present.
|
||||
Field accessors for the URI record type. The URI scheme will be a
|
||||
symbol, or @code{#f} if the object is a relative-ref (see below). The
|
||||
port will be either a positive, exact integer or @code{#f}, and the rest
|
||||
of the fields will be either strings or @code{#f} if not present.
|
||||
@end deffn
|
||||
|
||||
@deffn {Scheme Procedure} string->uri string
|
||||
|
@ -254,22 +232,18 @@ Parse @var{string} into a URI object. Return @code{#f} if the string
|
|||
could not be parsed.
|
||||
@end deffn
|
||||
|
||||
@deffn {Scheme Procedure} string->uri-reference string
|
||||
Parse @var{string} into a URI object, while not requiring a scheme.
|
||||
Return @code{#f} if the string could not be parsed.
|
||||
@end deffn
|
||||
|
||||
@deffn {Scheme Procedure} uri->string uri
|
||||
@deffn {Scheme Procedure} uri->string uri [#:include-fragment?=@code{#t}]
|
||||
Serialize @var{uri} to a string. If the URI has a port that is the
|
||||
default port for its scheme, the port is not included in the
|
||||
serialization.
|
||||
serialization. If @var{include-fragment?} is given as false, the
|
||||
resulting string will omit the fragment (if any).
|
||||
@end deffn
|
||||
|
||||
@deffn {Scheme Procedure} declare-default-port! scheme port
|
||||
Declare a default port for the given URI scheme.
|
||||
@end deffn
|
||||
|
||||
@deffn {Scheme Procedure} uri-decode str [#:encoding=@code{"utf-8"}]
|
||||
@deffn {Scheme Procedure} uri-decode str [#:encoding=@code{"utf-8"}] [#:decode-plus-to-space? #t]
|
||||
Percent-decode the given @var{str}, according to @var{encoding}, which
|
||||
should be the name of a character encoding.
|
||||
|
||||
|
@ -286,6 +260,11 @@ decoded bytes are not valid for the given encoding. Pass @code{#f} for
|
|||
@xref{Ports, @code{set-port-encoding!}}, for more information on
|
||||
character encodings.
|
||||
|
||||
If @var{decode-plus-to-space?} is true, which is the default, also
|
||||
replace instances of the plus character @samp{+} with a space character.
|
||||
This is needed when parsing @code{application/x-www-form-urlencoded}
|
||||
data.
|
||||
|
||||
Returns a string of the decoded characters, or a bytevector if
|
||||
@var{encoding} was @code{#f}.
|
||||
@end deffn
|
||||
|
@ -318,6 +297,70 @@ For example, the list @code{("scrambled eggs" "biscuits&gravy")} encodes
|
|||
as @code{"scrambled%20eggs/biscuits%26gravy"}.
|
||||
@end deffn
|
||||
|
||||
@subsubheading Subtypes of URI
|
||||
|
||||
As we noted above, not all URI objects have a scheme. You might have
|
||||
noted in the ``generic URI syntax'' example that the left-hand side of
|
||||
that grammar definition was URI-reference, not URI. A
|
||||
@dfn{URI-reference} is a generalization of a URI where the scheme is
|
||||
optional. If no scheme is specified, it is taken to be relative to some
|
||||
other related URI. A common use of URI references is when you want to
|
||||
be vague regarding the choice of HTTP or HTTPS -- serving a web page
|
||||
referring to @code{/foo.css} will use HTTPS if loaded over HTTPS, or
|
||||
HTTP otherwise.
|
||||
|
||||
@deffn {Scheme Procedure} build-uri-reference [#:scheme=@code{#f}]@
|
||||
[#:userinfo=@code{#f}] [#:host=@code{#f}] [#:port=@code{#f}] @
|
||||
[#:path=@code{""}] [#:query=@code{#f}] [#:fragment=@code{#f}] @
|
||||
[#:validate?=@code{#t}]
|
||||
Like @code{build-uri}, but with an optional scheme.
|
||||
@end deffn
|
||||
@deffn {Scheme Procedure} uri-reference? obj
|
||||
Return @code{#t} if @var{obj} is a URI-reference. This is the most
|
||||
general URI predicate, as it includes not only full URIs that have
|
||||
schemes (those that match @code{uri?}) but also URIs without schemes.
|
||||
@end deffn
|
||||
|
||||
It's also possible to build a @dfn{relative-ref}: a URI-reference that
|
||||
explicitly lacks a scheme.
|
||||
|
||||
@deffn {Scheme Procedure} build-relative-ref @
|
||||
[#:userinfo=@code{#f}] [#:host=@code{#f}] [#:port=@code{#f}] @
|
||||
[#:path=@code{""}] [#:query=@code{#f}] [#:fragment=@code{#f}] @
|
||||
[#:validate?=@code{#t}]
|
||||
Like @code{build-uri}, but with no scheme.
|
||||
@end deffn
|
||||
@deffn {Scheme Procedure} relative-ref? obj
|
||||
Return @code{#t} if @var{obj} is a ``relative-ref'': a URI-reference
|
||||
that has no scheme. Every URI-reference will either match @code{uri?}
|
||||
or @code{relative-ref?} (but not both).
|
||||
@end deffn
|
||||
|
||||
In case it's not clear from the above, the most general of these URI
|
||||
types is the URI-reference, with @code{build-uri-reference} as the most
|
||||
general constructor. @code{build-uri} and @code{build-relative-ref}
|
||||
enforce enforce specific restrictions on the URI-reference. The most
|
||||
generic URI parser is then @code{string->uri-reference}, and there is
|
||||
also a parser for when you know that you want a relative-ref.
|
||||
|
||||
@deffn {Scheme Procedure} string->uri-reference string
|
||||
Parse @var{string} into a URI object, while not requiring a scheme.
|
||||
Return @code{#f} if the string could not be parsed.
|
||||
@end deffn
|
||||
|
||||
@deffn {Scheme Procedure} string->relative-ref string
|
||||
Parse @var{string} into a URI object, while asserting that no scheme is
|
||||
present. Return @code{#f} if the string could not be parsed.
|
||||
@end deffn
|
||||
|
||||
For compatibility reasons, note that @code{uri?} will return @code{#t}
|
||||
for all URI objects, even relative-refs. In contrast, @code{build-uri}
|
||||
and @code{string->uri} require that the resulting URI not be a
|
||||
relative-ref. As a predicate to distinguish relative-refs from proper
|
||||
URIs (in the language of RFC 3986), use something like @code{(and
|
||||
(uri-reference? @var{x}) (not (relative-ref? @var{x})))}.
|
||||
|
||||
|
||||
@node HTTP
|
||||
@subsection The Hyper-Text Transfer Protocol
|
||||
|
||||
|
@ -747,9 +790,9 @@ a resource.
|
|||
@deftypevr {HTTP Header} List content-type
|
||||
The MIME type of a resource, as a symbol, along with any parameters.
|
||||
@example
|
||||
(parse-header 'content-length "text/plain")
|
||||
(parse-header 'content-type "text/plain")
|
||||
@result{} (text/plain)
|
||||
(parse-header 'content-length "text/plain;charset=utf-8")
|
||||
(parse-header 'content-type "text/plain;charset=utf-8")
|
||||
@result{} (text/plain (charset . "utf-8"))
|
||||
@end example
|
||||
Note that the @code{charset} parameter is something is a misnomer, and
|
||||
|
@ -1417,7 +1460,11 @@ the lower-level HTTP, request, and response modules.
|
|||
@end example
|
||||
|
||||
@deffn {Scheme Procedure} open-socket-for-uri uri
|
||||
Return an open input/output port for a connection to URI.
|
||||
Return an open input/output port for a connection to URI. Guile
|
||||
dynamically loads GnuTLS for HTTPS support.
|
||||
@xref{Guile Preparations,
|
||||
how to install the GnuTLS bindings for Guile,, gnutls-guile,
|
||||
GnuTLS-Guile}, for more information.
|
||||
@end deffn
|
||||
|
||||
@deffn {Scheme Procedure} http-get uri arg...
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
#+TITLE: Release Process for GNU Guile 2.0
|
||||
#+TITLE: Release Process for GNU Guile 2.2
|
||||
#+AUTHOR: Ludovic Courtès
|
||||
#+STARTUP: content
|
||||
#+EMAIL: ludo@gnu.org
|
||||
|
||||
This document describes the typical release process for Guile 2.0.
|
||||
This document describes the typical release process for Guile 2.2.
|
||||
|
||||
* Preparing & uploading the tarball
|
||||
|
||||
|
@ -69,17 +69,16 @@ if in doubt.
|
|||
|
||||
`libguile/libguile.map' should also be updated as new public symbols are
|
||||
added. Ideally, new symbols should get under a new version
|
||||
symbol---e.g., `GUILE_2.0.3' for symbols introduced in Guile 2.0.3.
|
||||
However, this has not been done for Guile <= 2.0.2.
|
||||
symbol---e.g., `GUILE_2.2.3' for symbols introduced in Guile 2.2.3.
|
||||
|
||||
** Tag v2.0.x
|
||||
** Tag v2.2.x
|
||||
|
||||
Create a signed Git tag, like this:
|
||||
|
||||
$ git tag -s -u MY-KEY -m "GNU Guile 2.0.X." v2.0.X
|
||||
$ git tag -s -u MY-KEY -m "GNU Guile 2.2.X." v2.2.X
|
||||
|
||||
The tag *must* be `v2.0.X'. For the sake of consistency, always use
|
||||
"GNU Guile 2.0.X." as the tag comment.
|
||||
The tag *must* be `v2.2.X'. For the sake of consistency, always use
|
||||
"GNU Guile 2.2.X." as the tag comment.
|
||||
|
||||
** Push the tag and changes
|
||||
|
||||
|
@ -98,7 +97,7 @@ reports the new version number.
|
|||
|
||||
** Upload
|
||||
|
||||
$ ./build-aux/gnupload --to ftp.gnu.org:guile guile-2.0.X.tar.gz
|
||||
$ ./build-aux/gnupload --to ftp.gnu.org:guile guile-2.2.X.tar.gz
|
||||
|
||||
You'll get an email soon after when the upload is complete.
|
||||
|
||||
|
@ -115,10 +114,10 @@ Make sure the file was uploaded and is available for download as
|
|||
expected:
|
||||
|
||||
$ mkdir t && cd t && \
|
||||
wget ftp.gnu.org/gnu/guile/guile-2.0.X.tar.gz && \
|
||||
wget ftp.gnu.org/gnu/guile/guile-2.0.X.tar.xz
|
||||
$ diff guile-2.0.X.tar.gz ../guile-2.0.X.tar.gz
|
||||
$ diff guile-2.0.X.tar.xz ../guile-2.0.X.tar.xz
|
||||
wget ftp.gnu.org/gnu/guile/guile-2.2.X.tar.gz && \
|
||||
wget ftp.gnu.org/gnu/guile/guile-2.2.X.tar.xz
|
||||
$ diff guile-2.2.X.tar.gz ../guile-2.2.X.tar.gz
|
||||
$ diff guile-2.2.X.tar.xz ../guile-2.2.X.tar.xz
|
||||
|
||||
You're almost done!
|
||||
|
||||
|
@ -138,17 +137,17 @@ Announcements").
|
|||
Use `build-aux/gendocs', add to the manual/ directory of the web site.
|
||||
|
||||
$ cd doc/ref
|
||||
$ ../../build-aux/gendocs.sh guile "GNU Guile 2.0.X Reference Manual"
|
||||
$ ../../build-aux/gendocs.sh guile "GNU Guile 2.2.X Reference Manual"
|
||||
|
||||
** Prepare the email announcement
|
||||
|
||||
$ build-aux/announce-gen --release-type=stable --package-name=guile \
|
||||
--previous-version=2.0.1 --current-version=2.0.2 \
|
||||
--previous-version=2.2.1 --current-version=2.2.2 \
|
||||
--gpg-key-id=MY-KEY --url-directory=ftp://ftp.gnu.org/gnu/guile \
|
||||
--bootstrap-tools=autoconf,automake,libtool,gnulib,makeinfo \
|
||||
--gnulib-version=$( cd ~/src/gnulib ; git describe )
|
||||
|
||||
The subject must be "GNU Guile 2.0.X released". The text should remain
|
||||
The subject must be "GNU Guile 2.2.X released". The text should remain
|
||||
formal and impersonal (it is sent on behalf of the Guile and GNU
|
||||
projects.) It must include a description of what Guile is (not everyone
|
||||
reading info-gnu may know about it.) Use the text of previous
|
||||
|
@ -173,7 +172,7 @@ more informal, with a link to the email announcement for details.
|
|||
|
||||
|
||||
|
||||
Copyright © 2011, 2012, 2013 Free Software Foundation, Inc.
|
||||
Copyright © 2011, 2012, 2013, 2017 Free Software Foundation, Inc.
|
||||
|
||||
Copying and distribution of this file, with or without modification,
|
||||
are permitted in any medium without royalty provided the copyright
|
||||
|
|
|
@ -2,17 +2,19 @@ This patch is being discussed
|
|||
at <http://lists.gnu.org/archive/html/bug-gnulib/2012-07/msg00079.html>.
|
||||
Remove when integrated in Gnulib.
|
||||
|
||||
diff --git a/build-aux/git-version-gen b/build-aux/git-version-gen
|
||||
index bd2c4b6..4458d7d 100755
|
||||
--- a/build-aux/git-version-gen
|
||||
+++ b/build-aux/git-version-gen
|
||||
@@ -86,6 +86,7 @@ Print a version string.
|
||||
Options:
|
||||
|
||||
--prefix prefix of git tags (default 'v')
|
||||
--prefix PREFIX prefix of git tags (default 'v')
|
||||
+ --match pattern for git tags to match (default: '\$prefix*')
|
||||
--fallback fallback version to use if \"git --version\" fails
|
||||
--fallback VERSION
|
||||
fallback version to use if \"git --version\" fails
|
||||
|
||||
--help display this help and exit
|
||||
@@ -96,11 +97,15 @@ Running without arguments will suffice in most cases."
|
||||
@@ -97,11 +98,15 @@ Running without arguments will suffice in most cases."
|
||||
prefix=v
|
||||
fallback=
|
||||
|
||||
|
@ -23,12 +25,12 @@ Remove when integrated in Gnulib.
|
|||
case $1 in
|
||||
--help) echo "$usage"; exit 0;;
|
||||
--version) echo "$version"; exit 0;;
|
||||
--prefix) shift; prefix="$1";;
|
||||
--prefix) shift; prefix=${1?};;
|
||||
+ --match) shift; match="$1";;
|
||||
--fallback) shift; fallback="$1";;
|
||||
--fallback) shift; fallback=${1?};;
|
||||
-*)
|
||||
echo "$0: Unknown option '$1'." >&2
|
||||
@@ -124,6 +129,7 @@ if test "x$tarball_version_file" = x; then
|
||||
@@ -125,6 +130,7 @@ if test "x$tarball_version_file" = x; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
@ -36,7 +38,7 @@ Remove when integrated in Gnulib.
|
|||
tag_sed_script="${tag_sed_script:-s/x/x/}"
|
||||
|
||||
nl='
|
||||
@@ -154,7 +160,7 @@ then
|
||||
@@ -155,7 +161,7 @@ then
|
||||
# directory, and "git describe" output looks sensible, use that to
|
||||
# derive a version string.
|
||||
elif test "`git log -1 --pretty=format:x . 2>&1`" = x \
|
||||
|
|
|
@ -2,17 +2,17 @@
|
|||
|
||||
/* Copyright (C) 1997,1999,2000,2001, 2002, 2003, 2006, 2007, 2008,
|
||||
* 2009, 2010, 2013 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, 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 software; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
|
@ -47,12 +47,14 @@ scm_t_option scm_readline_opts[] = {
|
|||
"History length." },
|
||||
{ SCM_OPTION_INTEGER, "bounce-parens", 500,
|
||||
"Time (ms) to show matching opening parenthesis (0 = off)."},
|
||||
{ SCM_OPTION_BOOLEAN, "bracketed-paste", 1,
|
||||
"Disable interpretation of control characters in pastes." },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
extern void stifle_history (int max);
|
||||
|
||||
SCM_DEFINE (scm_readline_options, "readline-options-interface", 0, 1, 0,
|
||||
SCM_DEFINE (scm_readline_options, "readline-options-interface", 0, 1, 0,
|
||||
(SCM setting),
|
||||
"")
|
||||
#define FUNC_NAME s_scm_readline_options
|
||||
|
@ -60,7 +62,9 @@ SCM_DEFINE (scm_readline_options, "readline-options-interface", 0, 1, 0,
|
|||
SCM ans = scm_options (setting,
|
||||
scm_readline_opts,
|
||||
FUNC_NAME);
|
||||
stifle_history (SCM_HISTORY_LENGTH);
|
||||
if (!SCM_UNBNDP (setting)) {
|
||||
stifle_history (SCM_HISTORY_LENGTH);
|
||||
}
|
||||
return ans;
|
||||
}
|
||||
#undef FUNC_NAME
|
||||
|
@ -107,13 +111,13 @@ void
|
|||
rl_free_line_state ()
|
||||
{
|
||||
register HIST_ENTRY *entry;
|
||||
|
||||
|
||||
free_undo_list ();
|
||||
|
||||
entry = current_history ();
|
||||
if (entry)
|
||||
entry->data = (char *)NULL;
|
||||
|
||||
entry->data = (char *)NULL;
|
||||
|
||||
_rl_kill_kbd_macro ();
|
||||
rl_clear_message ();
|
||||
_rl_init_argument ();
|
||||
|
@ -145,15 +149,15 @@ static void unwind_readline (void *unused);
|
|||
static void reentry_barrier (void);
|
||||
|
||||
|
||||
SCM_DEFINE (scm_readline, "%readline", 0, 4, 0,
|
||||
SCM_DEFINE (scm_readline, "%readline", 0, 4, 0,
|
||||
(SCM text, SCM inp, SCM outp, SCM read_hook),
|
||||
"")
|
||||
#define FUNC_NAME s_scm_readline
|
||||
{
|
||||
SCM ans;
|
||||
|
||||
|
||||
reentry_barrier ();
|
||||
|
||||
|
||||
before_read = SCM_BOOL_F;
|
||||
|
||||
if (!SCM_UNBNDP (text))
|
||||
|
@ -164,7 +168,7 @@ SCM_DEFINE (scm_readline, "%readline", 0, 4, 0,
|
|||
scm_wrong_type_arg (s_scm_readline, SCM_ARG1, text);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (!((SCM_UNBNDP (inp) && SCM_OPINFPORTP (scm_current_input_port ()))
|
||||
|| SCM_OPINFPORTP (inp)))
|
||||
{
|
||||
|
@ -173,7 +177,7 @@ SCM_DEFINE (scm_readline, "%readline", 0, 4, 0,
|
|||
"Input port is not open or not a file port",
|
||||
SCM_EOL);
|
||||
}
|
||||
|
||||
|
||||
if (!((SCM_UNBNDP (outp) && SCM_OPOUTFPORTP (scm_current_output_port ()))
|
||||
|| SCM_OPOUTFPORTP (outp)))
|
||||
{
|
||||
|
@ -197,7 +201,7 @@ SCM_DEFINE (scm_readline, "%readline", 0, 4, 0,
|
|||
|
||||
scm_dynwind_begin (0);
|
||||
scm_dynwind_unwind_handler (unwind_readline, NULL, 0);
|
||||
|
||||
|
||||
ans = internal_readline (text);
|
||||
|
||||
scm_dynwind_end ();
|
||||
|
@ -249,7 +253,7 @@ internal_readline (SCM text)
|
|||
s = readline (prompt);
|
||||
if (s)
|
||||
ret = scm_from_port_string (s, output_port);
|
||||
else
|
||||
else
|
||||
ret = SCM_EOF_VAL;
|
||||
|
||||
if (!SCM_UNBNDP (text))
|
||||
|
@ -287,10 +291,10 @@ scm_readline_init_ports (SCM inp, SCM outp)
|
|||
{
|
||||
if (SCM_UNBNDP (inp))
|
||||
inp = scm_current_input_port ();
|
||||
|
||||
|
||||
if (SCM_UNBNDP (outp))
|
||||
outp = scm_current_output_port ();
|
||||
|
||||
|
||||
if (!SCM_OPINFPORTP (inp)) {
|
||||
scm_misc_error (0,
|
||||
"Input port is not open or not a file port",
|
||||
|
@ -311,7 +315,7 @@ scm_readline_init_ports (SCM inp, SCM outp)
|
|||
|
||||
|
||||
|
||||
SCM_DEFINE (scm_add_history, "add-history", 1, 0, 0,
|
||||
SCM_DEFINE (scm_add_history, "add-history", 1, 0, 0,
|
||||
(SCM text),
|
||||
"")
|
||||
#define FUNC_NAME s_scm_add_history
|
||||
|
@ -327,7 +331,7 @@ SCM_DEFINE (scm_add_history, "add-history", 1, 0, 0,
|
|||
#undef FUNC_NAME
|
||||
|
||||
|
||||
SCM_DEFINE (scm_read_history, "read-history", 1, 0, 0,
|
||||
SCM_DEFINE (scm_read_history, "read-history", 1, 0, 0,
|
||||
(SCM file),
|
||||
"")
|
||||
#define FUNC_NAME s_scm_read_history
|
||||
|
@ -343,7 +347,7 @@ SCM_DEFINE (scm_read_history, "read-history", 1, 0, 0,
|
|||
#undef FUNC_NAME
|
||||
|
||||
|
||||
SCM_DEFINE (scm_write_history, "write-history", 1, 0, 0,
|
||||
SCM_DEFINE (scm_write_history, "write-history", 1, 0, 0,
|
||||
(SCM file),
|
||||
"")
|
||||
#define FUNC_NAME s_scm_write_history
|
||||
|
@ -358,7 +362,7 @@ SCM_DEFINE (scm_write_history, "write-history", 1, 0, 0,
|
|||
}
|
||||
#undef FUNC_NAME
|
||||
|
||||
SCM_DEFINE (scm_clear_history, "clear-history", 0, 0, 0,
|
||||
SCM_DEFINE (scm_clear_history, "clear-history", 0, 0, 0,
|
||||
(),
|
||||
"Clear the history buffer of the readline machinery.")
|
||||
#define FUNC_NAME s_scm_clear_history
|
||||
|
@ -369,7 +373,7 @@ SCM_DEFINE (scm_clear_history, "clear-history", 0, 0, 0,
|
|||
#undef FUNC_NAME
|
||||
|
||||
|
||||
SCM_DEFINE (scm_filename_completion_function, "filename-completion-function", 2, 0, 0,
|
||||
SCM_DEFINE (scm_filename_completion_function, "filename-completion-function", 2, 0, 0,
|
||||
(SCM text, SCM continuep),
|
||||
"")
|
||||
#define FUNC_NAME s_scm_filename_completion_function
|
||||
|
@ -408,10 +412,10 @@ completion_function (char *text, int continuep)
|
|||
SCM t = scm_from_locale_string (text);
|
||||
SCM c = scm_from_bool (continuep);
|
||||
res = scm_apply (compfunc, scm_list_2 (t, c), SCM_EOL);
|
||||
|
||||
|
||||
if (scm_is_false (res))
|
||||
return NULL;
|
||||
|
||||
|
||||
return scm_to_locale_string (res);
|
||||
}
|
||||
}
|
||||
|
@ -525,7 +529,7 @@ scm_init_readline ()
|
|||
rl_getc_function = current_input_getc;
|
||||
#if defined (_RL_FUNCTION_TYPEDEF)
|
||||
rl_completion_entry_function = (rl_compentry_func_t*) completion_function;
|
||||
#else
|
||||
#else
|
||||
rl_completion_entry_function = (Function*) completion_function;
|
||||
#endif
|
||||
rl_basic_word_break_characters = " \t\n\"'`;()";
|
||||
|
@ -535,15 +539,18 @@ scm_init_readline ()
|
|||
#if defined (HAVE_DECL_RL_CATCH_SIGNALS) && HAVE_DECL_RL_CATCH_SIGNALS
|
||||
rl_catch_signals = 0;
|
||||
#endif
|
||||
|
||||
|
||||
/* But let readline handle SIGWINCH. */
|
||||
#if defined (HAVE_DECL_RL_CATCH_SIGWINCH) && HAVE_DECL_RL_CATCH_SIGWINCH
|
||||
rl_catch_sigwinch = 1;
|
||||
#endif
|
||||
|
||||
|
||||
reentry_barrier_mutex = scm_make_mutex ();
|
||||
scm_init_opts (scm_readline_options,
|
||||
scm_readline_opts);
|
||||
scm_readline_opts);
|
||||
rl_variable_bind ("enable-bracketed-paste",
|
||||
SCM_READLINE_BRACKETED_PASTE ? "on" : "off");
|
||||
|
||||
#if HAVE_RL_GET_KEYMAP
|
||||
init_bouncing_parens();
|
||||
#endif
|
||||
|
|
|
@ -39,7 +39,8 @@ SCM_RL_API scm_t_option scm_readline_opts[];
|
|||
#define SCM_HISTORY_FILE_P scm_readline_opts[0].val
|
||||
#define SCM_HISTORY_LENGTH scm_readline_opts[1].val
|
||||
#define SCM_READLINE_BOUNCE_PARENS scm_readline_opts[2].val
|
||||
#define SCM_N_READLINE_OPTIONS 3
|
||||
#define SCM_READLINE_BRACKETED_PASTE scm_readline_opts[3].val
|
||||
#define SCM_N_READLINE_OPTIONS 4
|
||||
|
||||
SCM_RL_API SCM scm_readline_options (SCM setting);
|
||||
SCM_RL_API void scm_readline_init_ports (SCM inp, SCM outp);
|
||||
|
|
337
lib/Makefile.am
337
lib/Makefile.am
|
@ -1,6 +1,6 @@
|
|||
## DO NOT EDIT! GENERATED AUTOMATICALLY!
|
||||
## Process this file with automake to produce Makefile.in.
|
||||
# Copyright (C) 2002-2014 Free Software Foundation, Inc.
|
||||
# Copyright (C) 2002-2017 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
|
@ -21,9 +21,9 @@
|
|||
# the same distribution terms as the rest of that program.
|
||||
#
|
||||
# Generated by gnulib-tool.
|
||||
# Reproduce by: gnulib-tool --import --dir=. --local-dir=gnulib-local --lib=libgnu --source-base=lib --m4-base=m4 --doc-base=doc --tests-base=tests --aux-dir=build-aux --avoid=lock --lgpl=3 --no-conditional-dependencies --libtool --macro-prefix=gl --no-vc-files accept alignof alloca-opt announce-gen autobuild bind byteswap c-strcase canonicalize-lgpl ceil clock-time close connect copysign dirfd duplocale environ extensions flock floor fpieee frexp fstat fsync full-read full-write func gendocs getaddrinfo getlogin getpeername getsockname getsockopt git-version-gen gitlog-to-changelog gnu-web-doc-update gnupload havelib iconv_open-utf inet_ntop inet_pton isfinite isinf isnan ldexp lib-symbol-versions lib-symbol-visibility libunistring link listen localcharset locale log1p lstat maintainer-makefile malloc-gnu malloca mkdir mkstemp nl_langinfo nproc open pipe-posix pipe2 poll putenv readlink recv recvfrom regex rename rmdir select send sendto setenv setsockopt shutdown socket stat-time stdlib strftime striconveh string sys_stat time times trunc unistd verify vsnprintf warnings wchar
|
||||
# Reproduce by: gnulib-tool --import --local-dir=gnulib-local --lib=libgnu --source-base=lib --m4-base=m4 --doc-base=doc --tests-base=tests --aux-dir=build-aux --avoid=lock --avoid=unistr/base --avoid=unistr/u8-mbtouc --avoid=unistr/u8-mbtouc-unsafe --avoid=unistr/u8-mbtoucr --avoid=unistr/u8-prev --avoid=unistr/u8-uctomb --avoid=unitypes --lgpl=3 --conditional-dependencies --libtool --macro-prefix=gl --no-vc-files accept4 alignof alloca-opt announce-gen autobuild bind byteswap c-strcase canonicalize-lgpl ceil clock-time close connect copysign dirfd dirname-lgpl duplocale environ extensions flock floor fpieee frexp fstat fsync full-read full-write func gendocs getaddrinfo getlogin getpeername getsockname getsockopt git-version-gen gitlog-to-changelog gnu-web-doc-update gnupload havelib iconv_open-utf inet_ntop inet_pton isfinite isinf isnan ldexp lib-symbol-versions lib-symbol-visibility libunistring link listen localcharset locale log1p lstat maintainer-makefile malloc-gnu malloca mkdir mkostemp nl_langinfo nproc open pipe-posix pipe2 poll putenv readlink recv recvfrom regex rename rmdir select send sendto setenv setsockopt shutdown socket stat-time stdlib strftime striconveh string sys_stat time times trunc unistd verify vsnprintf warnings wchar
|
||||
|
||||
AUTOMAKE_OPTIONS = 1.9.6 gnits subdir-objects
|
||||
AUTOMAKE_OPTIONS = 1.9.6 gnits
|
||||
|
||||
SUBDIRS =
|
||||
noinst_HEADERS =
|
||||
|
@ -63,6 +63,7 @@ libgnu_la_LDFLAGS += $(ISNANL_LIBM)
|
|||
libgnu_la_LDFLAGS += $(LDEXP_LIBM)
|
||||
libgnu_la_LDFLAGS += $(LIBSOCKET)
|
||||
libgnu_la_LDFLAGS += $(LIB_CLOCK_GETTIME)
|
||||
libgnu_la_LDFLAGS += $(LIB_GETLOGIN)
|
||||
libgnu_la_LDFLAGS += $(LIB_POLL)
|
||||
libgnu_la_LDFLAGS += $(LIB_SELECT)
|
||||
libgnu_la_LDFLAGS += $(LOG1P_LIBM)
|
||||
|
@ -92,6 +93,12 @@ EXTRA_libgnu_la_SOURCES += accept.c
|
|||
|
||||
## end gnulib module accept
|
||||
|
||||
## begin gnulib module accept4
|
||||
|
||||
libgnu_la_SOURCES += accept4.c
|
||||
|
||||
## end gnulib module accept4
|
||||
|
||||
## begin gnulib module alignof
|
||||
|
||||
|
||||
|
@ -101,9 +108,11 @@ EXTRA_DIST += alignof.h
|
|||
|
||||
## begin gnulib module alloca
|
||||
|
||||
if gl_GNULIB_ENABLED_alloca
|
||||
|
||||
libgnu_la_LIBADD += @LTALLOCA@
|
||||
libgnu_la_DEPENDENCIES += @LTALLOCA@
|
||||
endif
|
||||
EXTRA_DIST += alloca.c
|
||||
|
||||
EXTRA_libgnu_la_SOURCES += alloca.c
|
||||
|
@ -176,6 +185,15 @@ EXTRA_DIST += arpa_inet.in.h
|
|||
|
||||
## end gnulib module arpa_inet
|
||||
|
||||
## begin gnulib module assure
|
||||
|
||||
if gl_GNULIB_ENABLED_assure
|
||||
|
||||
endif
|
||||
EXTRA_DIST += assure.h
|
||||
|
||||
## end gnulib module assure
|
||||
|
||||
## begin gnulib module binary-io
|
||||
|
||||
libgnu_la_SOURCES += binary-io.h binary-io.c
|
||||
|
@ -193,7 +211,9 @@ EXTRA_libgnu_la_SOURCES += bind.c
|
|||
|
||||
## begin gnulib module btowc
|
||||
|
||||
if gl_GNULIB_ENABLED_btowc
|
||||
|
||||
endif
|
||||
EXTRA_DIST += btowc.c
|
||||
|
||||
EXTRA_libgnu_la_SOURCES += btowc.c
|
||||
|
@ -406,7 +426,9 @@ EXTRA_DIST += dosname.h
|
|||
|
||||
## begin gnulib module dup2
|
||||
|
||||
if gl_GNULIB_ENABLED_dup2
|
||||
|
||||
endif
|
||||
EXTRA_DIST += dup2.c
|
||||
|
||||
EXTRA_libgnu_la_SOURCES += dup2.c
|
||||
|
@ -493,12 +515,23 @@ EXTRA_DIST += fcntl.in.h
|
|||
|
||||
## begin gnulib module fd-hook
|
||||
|
||||
if gl_GNULIB_ENABLED_43fe87a341d9b4b93c47c3ad819a5239
|
||||
libgnu_la_SOURCES += fd-hook.c
|
||||
|
||||
endif
|
||||
EXTRA_DIST += fd-hook.h
|
||||
|
||||
## end gnulib module fd-hook
|
||||
|
||||
## begin gnulib module flexmember
|
||||
|
||||
if gl_GNULIB_ENABLED_flexmember
|
||||
|
||||
endif
|
||||
EXTRA_DIST += flexmember.h
|
||||
|
||||
## end gnulib module flexmember
|
||||
|
||||
## begin gnulib module float
|
||||
|
||||
BUILT_SOURCES += $(FLOAT_H)
|
||||
|
@ -645,8 +678,10 @@ EXTRA_libgnu_la_SOURCES += getsockopt.c
|
|||
|
||||
## begin gnulib module gettext-h
|
||||
|
||||
if gl_GNULIB_ENABLED_be453cec5eecf5731a274f2de7f2db36
|
||||
libgnu_la_SOURCES += gettext.h
|
||||
|
||||
endif
|
||||
## end gnulib module gettext-h
|
||||
|
||||
## begin gnulib module gettimeofday
|
||||
|
@ -699,9 +734,22 @@ EXTRA_DIST += $(top_srcdir)/build-aux/gnupload
|
|||
## begin gnulib module gperf
|
||||
|
||||
GPERF = gperf
|
||||
V_GPERF = $(V_GPERF_@AM_V@)
|
||||
V_GPERF_ = $(V_GPERF_@AM_DEFAULT_V@)
|
||||
V_GPERF_0 = @echo " GPERF " $@;
|
||||
|
||||
## end gnulib module gperf
|
||||
|
||||
## begin gnulib module hard-locale
|
||||
|
||||
if gl_GNULIB_ENABLED_30838f5439487421042f2225bed3af76
|
||||
libgnu_la_SOURCES += hard-locale.c
|
||||
|
||||
endif
|
||||
EXTRA_DIST += hard-locale.h
|
||||
|
||||
## end gnulib module hard-locale
|
||||
|
||||
## begin gnulib module havelib
|
||||
|
||||
|
||||
|
@ -748,19 +796,19 @@ EXTRA_DIST += iconv.in.h
|
|||
## begin gnulib module iconv_open
|
||||
|
||||
iconv_open-aix.h: iconv_open-aix.gperf
|
||||
$(GPERF) -m 10 $(srcdir)/iconv_open-aix.gperf > $(srcdir)/iconv_open-aix.h-t
|
||||
$(V_GPERF)$(GPERF) -m 10 $(srcdir)/iconv_open-aix.gperf > $(srcdir)/iconv_open-aix.h-t && \
|
||||
mv $(srcdir)/iconv_open-aix.h-t $(srcdir)/iconv_open-aix.h
|
||||
iconv_open-hpux.h: iconv_open-hpux.gperf
|
||||
$(GPERF) -m 10 $(srcdir)/iconv_open-hpux.gperf > $(srcdir)/iconv_open-hpux.h-t
|
||||
$(V_GPERF)$(GPERF) -m 10 $(srcdir)/iconv_open-hpux.gperf > $(srcdir)/iconv_open-hpux.h-t && \
|
||||
mv $(srcdir)/iconv_open-hpux.h-t $(srcdir)/iconv_open-hpux.h
|
||||
iconv_open-irix.h: iconv_open-irix.gperf
|
||||
$(GPERF) -m 10 $(srcdir)/iconv_open-irix.gperf > $(srcdir)/iconv_open-irix.h-t
|
||||
$(V_GPERF)$(GPERF) -m 10 $(srcdir)/iconv_open-irix.gperf > $(srcdir)/iconv_open-irix.h-t && \
|
||||
mv $(srcdir)/iconv_open-irix.h-t $(srcdir)/iconv_open-irix.h
|
||||
iconv_open-osf.h: iconv_open-osf.gperf
|
||||
$(GPERF) -m 10 $(srcdir)/iconv_open-osf.gperf > $(srcdir)/iconv_open-osf.h-t
|
||||
$(V_GPERF)$(GPERF) -m 10 $(srcdir)/iconv_open-osf.gperf > $(srcdir)/iconv_open-osf.h-t && \
|
||||
mv $(srcdir)/iconv_open-osf.h-t $(srcdir)/iconv_open-osf.h
|
||||
iconv_open-solaris.h: iconv_open-solaris.gperf
|
||||
$(GPERF) -m 10 $(srcdir)/iconv_open-solaris.gperf > $(srcdir)/iconv_open-solaris.h-t
|
||||
$(V_GPERF)$(GPERF) -m 10 $(srcdir)/iconv_open-solaris.gperf > $(srcdir)/iconv_open-solaris.h-t && \
|
||||
mv $(srcdir)/iconv_open-solaris.h-t $(srcdir)/iconv_open-solaris.h
|
||||
BUILT_SOURCES += iconv_open-aix.h iconv_open-hpux.h iconv_open-irix.h iconv_open-osf.h iconv_open-solaris.h
|
||||
MOSTLYCLEANFILES += iconv_open-aix.h-t iconv_open-hpux.h-t iconv_open-irix.h-t iconv_open-osf.h-t iconv_open-solaris.h-t
|
||||
|
@ -791,6 +839,15 @@ EXTRA_libgnu_la_SOURCES += inet_pton.c
|
|||
|
||||
## end gnulib module inet_pton
|
||||
|
||||
## begin gnulib module intprops
|
||||
|
||||
if gl_GNULIB_ENABLED_intprops
|
||||
|
||||
endif
|
||||
EXTRA_DIST += intprops.h
|
||||
|
||||
## end gnulib module intprops
|
||||
|
||||
## begin gnulib module isfinite
|
||||
|
||||
|
||||
|
@ -820,7 +877,9 @@ EXTRA_libgnu_la_SOURCES += isnan.c isnand.c
|
|||
|
||||
## begin gnulib module isnand-nolibm
|
||||
|
||||
if gl_GNULIB_ENABLED_b1df7117b479d2da59d76deba468ee21
|
||||
|
||||
endif
|
||||
EXTRA_DIST += float+.h isnan.c isnand-nolibm.h isnand.c
|
||||
|
||||
EXTRA_libgnu_la_SOURCES += isnan.c isnand.c
|
||||
|
@ -838,7 +897,9 @@ EXTRA_libgnu_la_SOURCES += isnan.c isnanf.c
|
|||
|
||||
## begin gnulib module isnanf-nolibm
|
||||
|
||||
if gl_GNULIB_ENABLED_3f0e593033d1fc2c127581960f641b66
|
||||
|
||||
endif
|
||||
EXTRA_DIST += float+.h isnan.c isnanf-nolibm.h isnanf.c
|
||||
|
||||
EXTRA_libgnu_la_SOURCES += isnan.c isnanf.c
|
||||
|
@ -856,7 +917,9 @@ EXTRA_libgnu_la_SOURCES += isnan.c isnanl.c
|
|||
|
||||
## begin gnulib module isnanl-nolibm
|
||||
|
||||
if gl_GNULIB_ENABLED_dbdf22868a5367f28bf18e0013ac6f8f
|
||||
|
||||
endif
|
||||
EXTRA_DIST += float+.h isnan.c isnanl-nolibm.h isnanl.c
|
||||
|
||||
EXTRA_libgnu_la_SOURCES += isnan.c isnanl.c
|
||||
|
@ -913,6 +976,34 @@ EXTRA_DIST += libunistring.valgrind
|
|||
|
||||
## end gnulib module libunistring
|
||||
|
||||
## begin gnulib module limits-h
|
||||
|
||||
BUILT_SOURCES += $(LIMITS_H)
|
||||
|
||||
# We need the following in order to create <limits.h> when the system
|
||||
# doesn't have one that is compatible with GNU.
|
||||
if GL_GENERATE_LIMITS_H
|
||||
limits.h: limits.in.h $(top_builddir)/config.status
|
||||
$(AM_V_GEN)rm -f $@-t $@ && \
|
||||
{ echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */' && \
|
||||
sed -e 's|@''GUARD_PREFIX''@|GL|g' \
|
||||
-e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \
|
||||
-e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \
|
||||
-e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \
|
||||
-e 's|@''NEXT_LIMITS_H''@|$(NEXT_LIMITS_H)|g' \
|
||||
< $(srcdir)/limits.in.h; \
|
||||
} > $@-t && \
|
||||
mv $@-t $@
|
||||
else
|
||||
limits.h: $(top_builddir)/config.status
|
||||
rm -f $@
|
||||
endif
|
||||
MOSTLYCLEANFILES += limits.h limits.h-t
|
||||
|
||||
EXTRA_DIST += limits.in.h
|
||||
|
||||
## end gnulib module limits-h
|
||||
|
||||
## begin gnulib module link
|
||||
|
||||
|
||||
|
@ -1042,7 +1133,9 @@ EXTRA_DIST += locale.in.h
|
|||
|
||||
## begin gnulib module localeconv
|
||||
|
||||
if gl_GNULIB_ENABLED_localeconv
|
||||
|
||||
endif
|
||||
EXTRA_DIST += localeconv.c
|
||||
|
||||
EXTRA_libgnu_la_SOURCES += localeconv.c
|
||||
|
@ -1051,7 +1144,9 @@ EXTRA_libgnu_la_SOURCES += localeconv.c
|
|||
|
||||
## begin gnulib module log
|
||||
|
||||
if gl_GNULIB_ENABLED_log
|
||||
|
||||
endif
|
||||
EXTRA_DIST += log.c
|
||||
|
||||
EXTRA_libgnu_la_SOURCES += log.c
|
||||
|
@ -1317,11 +1412,18 @@ math.h: math.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H) $(
|
|||
-e 's|@''HAVE_DECL_TRUNCF''@|$(HAVE_DECL_TRUNCF)|g' \
|
||||
-e 's|@''HAVE_DECL_TRUNCL''@|$(HAVE_DECL_TRUNCL)|g' \
|
||||
| \
|
||||
sed -e 's|@''REPLACE_CBRTF''@|$(REPLACE_CBRTF)|g' \
|
||||
sed -e 's|@''REPLACE_ACOSF''@|$(REPLACE_ACOSF)|g' \
|
||||
-e 's|@''REPLACE_ASINF''@|$(REPLACE_ASINF)|g' \
|
||||
-e 's|@''REPLACE_ATANF''@|$(REPLACE_ATANF)|g' \
|
||||
-e 's|@''REPLACE_ATAN2F''@|$(REPLACE_ATAN2F)|g' \
|
||||
-e 's|@''REPLACE_CBRTF''@|$(REPLACE_CBRTF)|g' \
|
||||
-e 's|@''REPLACE_CBRTL''@|$(REPLACE_CBRTL)|g' \
|
||||
-e 's|@''REPLACE_CEIL''@|$(REPLACE_CEIL)|g' \
|
||||
-e 's|@''REPLACE_CEILF''@|$(REPLACE_CEILF)|g' \
|
||||
-e 's|@''REPLACE_CEILL''@|$(REPLACE_CEILL)|g' \
|
||||
-e 's|@''REPLACE_COSF''@|$(REPLACE_COSF)|g' \
|
||||
-e 's|@''REPLACE_COSHF''@|$(REPLACE_COSHF)|g' \
|
||||
-e 's|@''REPLACE_EXPF''@|$(REPLACE_EXPF)|g' \
|
||||
-e 's|@''REPLACE_EXPM1''@|$(REPLACE_EXPM1)|g' \
|
||||
-e 's|@''REPLACE_EXPM1F''@|$(REPLACE_EXPM1F)|g' \
|
||||
-e 's|@''REPLACE_EXP2''@|$(REPLACE_EXP2)|g' \
|
||||
|
@ -1377,7 +1479,12 @@ math.h: math.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H) $(
|
|||
-e 's|@''REPLACE_ROUNDL''@|$(REPLACE_ROUNDL)|g' \
|
||||
-e 's|@''REPLACE_SIGNBIT''@|$(REPLACE_SIGNBIT)|g' \
|
||||
-e 's|@''REPLACE_SIGNBIT_USING_GCC''@|$(REPLACE_SIGNBIT_USING_GCC)|g' \
|
||||
-e 's|@''REPLACE_SINF''@|$(REPLACE_SINF)|g' \
|
||||
-e 's|@''REPLACE_SINHF''@|$(REPLACE_SINHF)|g' \
|
||||
-e 's|@''REPLACE_SQRTF''@|$(REPLACE_SQRTF)|g' \
|
||||
-e 's|@''REPLACE_SQRTL''@|$(REPLACE_SQRTL)|g' \
|
||||
-e 's|@''REPLACE_TANF''@|$(REPLACE_TANF)|g' \
|
||||
-e 's|@''REPLACE_TANHF''@|$(REPLACE_TANHF)|g' \
|
||||
-e 's|@''REPLACE_TRUNC''@|$(REPLACE_TRUNC)|g' \
|
||||
-e 's|@''REPLACE_TRUNCF''@|$(REPLACE_TRUNCF)|g' \
|
||||
-e 's|@''REPLACE_TRUNCL''@|$(REPLACE_TRUNCL)|g' \
|
||||
|
@ -1394,7 +1501,9 @@ EXTRA_DIST += math.in.h
|
|||
|
||||
## begin gnulib module mbrtowc
|
||||
|
||||
if gl_GNULIB_ENABLED_mbrtowc
|
||||
|
||||
endif
|
||||
EXTRA_DIST += mbrtowc.c
|
||||
|
||||
EXTRA_libgnu_la_SOURCES += mbrtowc.c
|
||||
|
@ -1403,7 +1512,9 @@ EXTRA_libgnu_la_SOURCES += mbrtowc.c
|
|||
|
||||
## begin gnulib module mbsinit
|
||||
|
||||
if gl_GNULIB_ENABLED_mbsinit
|
||||
|
||||
endif
|
||||
EXTRA_DIST += mbsinit.c
|
||||
|
||||
EXTRA_libgnu_la_SOURCES += mbsinit.c
|
||||
|
@ -1412,7 +1523,9 @@ EXTRA_libgnu_la_SOURCES += mbsinit.c
|
|||
|
||||
## begin gnulib module mbtowc
|
||||
|
||||
if gl_GNULIB_ENABLED_mbtowc
|
||||
|
||||
endif
|
||||
EXTRA_DIST += mbtowc-impl.h mbtowc.c
|
||||
|
||||
EXTRA_libgnu_la_SOURCES += mbtowc.c
|
||||
|
@ -1421,7 +1534,9 @@ EXTRA_libgnu_la_SOURCES += mbtowc.c
|
|||
|
||||
## begin gnulib module memchr
|
||||
|
||||
if gl_GNULIB_ENABLED_memchr
|
||||
|
||||
endif
|
||||
EXTRA_DIST += memchr.c memchr.valgrind
|
||||
|
||||
EXTRA_libgnu_la_SOURCES += memchr.c
|
||||
|
@ -1437,14 +1552,36 @@ EXTRA_libgnu_la_SOURCES += mkdir.c
|
|||
|
||||
## end gnulib module mkdir
|
||||
|
||||
## begin gnulib module mkstemp
|
||||
## begin gnulib module mkostemp
|
||||
|
||||
|
||||
EXTRA_DIST += mkstemp.c
|
||||
EXTRA_DIST += mkostemp.c
|
||||
|
||||
EXTRA_libgnu_la_SOURCES += mkstemp.c
|
||||
EXTRA_libgnu_la_SOURCES += mkostemp.c
|
||||
|
||||
## end gnulib module mkstemp
|
||||
## end gnulib module mkostemp
|
||||
|
||||
## begin gnulib module mktime
|
||||
|
||||
if gl_GNULIB_ENABLED_mktime
|
||||
|
||||
endif
|
||||
EXTRA_DIST += mktime-internal.h mktime.c
|
||||
|
||||
EXTRA_libgnu_la_SOURCES += mktime.c
|
||||
|
||||
## end gnulib module mktime
|
||||
|
||||
## begin gnulib module mktime-internal
|
||||
|
||||
if gl_GNULIB_ENABLED_5264294aa0a5557541b53c8c741f7f31
|
||||
|
||||
endif
|
||||
EXTRA_DIST += mktime-internal.h mktime.c
|
||||
|
||||
EXTRA_libgnu_la_SOURCES += mktime.c
|
||||
|
||||
## end gnulib module mktime-internal
|
||||
|
||||
## begin gnulib module msvc-inval
|
||||
|
||||
|
@ -1557,7 +1694,9 @@ EXTRA_libgnu_la_SOURCES += open.c
|
|||
|
||||
## begin gnulib module pathmax
|
||||
|
||||
if gl_GNULIB_ENABLED_pathmax
|
||||
|
||||
endif
|
||||
EXTRA_DIST += pathmax.h
|
||||
|
||||
## end gnulib module pathmax
|
||||
|
@ -1626,7 +1765,9 @@ EXTRA_libgnu_la_SOURCES += putenv.c
|
|||
|
||||
## begin gnulib module raise
|
||||
|
||||
if gl_GNULIB_ENABLED_raise
|
||||
|
||||
endif
|
||||
EXTRA_DIST += raise.c
|
||||
|
||||
EXTRA_libgnu_la_SOURCES += raise.c
|
||||
|
@ -1698,7 +1839,9 @@ EXTRA_libgnu_la_SOURCES += rmdir.c
|
|||
|
||||
## begin gnulib module round
|
||||
|
||||
if gl_GNULIB_ENABLED_round
|
||||
|
||||
endif
|
||||
EXTRA_DIST += round.c
|
||||
|
||||
EXTRA_libgnu_la_SOURCES += round.c
|
||||
|
@ -1725,14 +1868,18 @@ EXTRA_libgnu_la_SOURCES += safe-read.c
|
|||
|
||||
## begin gnulib module same-inode
|
||||
|
||||
if gl_GNULIB_ENABLED_9bc5f216d57e231e4834049d67d0db62
|
||||
|
||||
endif
|
||||
EXTRA_DIST += same-inode.h
|
||||
|
||||
## end gnulib module same-inode
|
||||
|
||||
## begin gnulib module secure_getenv
|
||||
|
||||
if gl_GNULIB_ENABLED_secure_getenv
|
||||
|
||||
endif
|
||||
EXTRA_DIST += secure_getenv.c
|
||||
|
||||
EXTRA_libgnu_la_SOURCES += secure_getenv.c
|
||||
|
@ -1837,7 +1984,9 @@ EXTRA_DIST += signal.in.h
|
|||
|
||||
## begin gnulib module signbit
|
||||
|
||||
if gl_GNULIB_ENABLED_signbit
|
||||
|
||||
endif
|
||||
EXTRA_DIST += float+.h signbitd.c signbitf.c signbitl.c
|
||||
|
||||
EXTRA_libgnu_la_SOURCES += signbitd.c signbitf.c signbitl.c
|
||||
|
@ -1846,8 +1995,10 @@ EXTRA_libgnu_la_SOURCES += signbitd.c signbitf.c signbitl.c
|
|||
|
||||
## begin gnulib module size_max
|
||||
|
||||
if gl_GNULIB_ENABLED_size_max
|
||||
libgnu_la_SOURCES += size_max.h
|
||||
|
||||
endif
|
||||
## end gnulib module size_max
|
||||
|
||||
## begin gnulib module snippet/_Noreturn
|
||||
|
@ -1911,31 +2062,6 @@ EXTRA_DIST += $(top_srcdir)/build-aux/snippet/c++defs.h
|
|||
|
||||
## end gnulib module snippet/c++defs
|
||||
|
||||
## begin gnulib module snippet/unused-parameter
|
||||
|
||||
# The BUILT_SOURCES created by this Makefile snippet are not used via #include
|
||||
# statements but through direct file reference. Therefore this snippet must be
|
||||
# present in all Makefile.am that need it. This is ensured by the applicability
|
||||
# 'all' defined above.
|
||||
|
||||
BUILT_SOURCES += unused-parameter.h
|
||||
# The unused-parameter.h that gets inserted into generated .h files is the same
|
||||
# as build-aux/snippet/unused-parameter.h, except that it has the copyright
|
||||
# header cut off.
|
||||
unused-parameter.h: $(top_srcdir)/build-aux/snippet/unused-parameter.h
|
||||
$(AM_V_GEN)rm -f $@-t $@ && \
|
||||
sed -n -e '/GL_UNUSED_PARAMETER/,$$p' \
|
||||
< $(top_srcdir)/build-aux/snippet/unused-parameter.h \
|
||||
> $@-t && \
|
||||
mv $@-t $@
|
||||
MOSTLYCLEANFILES += unused-parameter.h unused-parameter.h-t
|
||||
|
||||
UNUSED_PARAMETER_H=unused-parameter.h
|
||||
|
||||
EXTRA_DIST += $(top_srcdir)/build-aux/snippet/unused-parameter.h
|
||||
|
||||
## end gnulib module snippet/unused-parameter
|
||||
|
||||
## begin gnulib module snippet/warn-on-use
|
||||
|
||||
BUILT_SOURCES += warn-on-use.h
|
||||
|
@ -1958,7 +2084,9 @@ EXTRA_DIST += $(top_srcdir)/build-aux/snippet/warn-on-use.h
|
|||
|
||||
## begin gnulib module snprintf
|
||||
|
||||
if gl_GNULIB_ENABLED_snprintf
|
||||
|
||||
endif
|
||||
EXTRA_DIST += snprintf.c
|
||||
|
||||
EXTRA_libgnu_la_SOURCES += snprintf.c
|
||||
|
@ -1976,15 +2104,19 @@ EXTRA_libgnu_la_SOURCES += socket.c
|
|||
|
||||
## begin gnulib module sockets
|
||||
|
||||
if gl_GNULIB_ENABLED_sockets
|
||||
libgnu_la_SOURCES += sockets.h sockets.c
|
||||
|
||||
endif
|
||||
EXTRA_DIST += w32sock.h
|
||||
|
||||
## end gnulib module sockets
|
||||
|
||||
## begin gnulib module stat
|
||||
|
||||
if gl_GNULIB_ENABLED_stat
|
||||
|
||||
endif
|
||||
EXTRA_DIST += stat.c
|
||||
|
||||
EXTRA_libgnu_la_SOURCES += stat.c
|
||||
|
@ -2060,6 +2192,7 @@ stddef.h: stddef.in.h $(top_builddir)/config.status
|
|||
-e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \
|
||||
-e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \
|
||||
-e 's|@''NEXT_STDDEF_H''@|$(NEXT_STDDEF_H)|g' \
|
||||
-e 's|@''HAVE_MAX_ALIGN_T''@|$(HAVE_MAX_ALIGN_T)|g' \
|
||||
-e 's|@''HAVE_WCHAR_T''@|$(HAVE_WCHAR_T)|g' \
|
||||
-e 's|@''REPLACE_NULL''@|$(REPLACE_NULL)|g' \
|
||||
< $(srcdir)/stddef.in.h; \
|
||||
|
@ -2091,6 +2224,7 @@ stdint.h: stdint.in.h $(top_builddir)/config.status
|
|||
-e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \
|
||||
-e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \
|
||||
-e 's|@''NEXT_STDINT_H''@|$(NEXT_STDINT_H)|g' \
|
||||
-e 's/@''HAVE_C99_STDINT_H''@/$(HAVE_C99_STDINT_H)/g' \
|
||||
-e 's/@''HAVE_SYS_TYPES_H''@/$(HAVE_SYS_TYPES_H)/g' \
|
||||
-e 's/@''HAVE_INTTYPES_H''@/$(HAVE_INTTYPES_H)/g' \
|
||||
-e 's/@''HAVE_SYS_INTTYPES_H''@/$(HAVE_SYS_INTTYPES_H)/g' \
|
||||
|
@ -2112,6 +2246,7 @@ stdint.h: stdint.in.h $(top_builddir)/config.status
|
|||
-e 's/@''BITSIZEOF_WINT_T''@/$(BITSIZEOF_WINT_T)/g' \
|
||||
-e 's/@''HAVE_SIGNED_WINT_T''@/$(HAVE_SIGNED_WINT_T)/g' \
|
||||
-e 's/@''WINT_T_SUFFIX''@/$(WINT_T_SUFFIX)/g' \
|
||||
-e 's/@''GNULIB_OVERRIDES_WINT_T''@/$(GNULIB_OVERRIDES_WINT_T)/g' \
|
||||
< $(srcdir)/stdint.in.h; \
|
||||
} > $@-t && \
|
||||
mv $@-t $@
|
||||
|
@ -2286,6 +2421,7 @@ stdlib.h: stdlib.in.h $(top_builddir)/config.status $(CXXDEFS_H) \
|
|||
-e 's/@''GNULIB_PTSNAME''@/$(GNULIB_PTSNAME)/g' \
|
||||
-e 's/@''GNULIB_PTSNAME_R''@/$(GNULIB_PTSNAME_R)/g' \
|
||||
-e 's/@''GNULIB_PUTENV''@/$(GNULIB_PUTENV)/g' \
|
||||
-e 's/@''GNULIB_QSORT_R''@/$(GNULIB_QSORT_R)/g' \
|
||||
-e 's/@''GNULIB_RANDOM''@/$(GNULIB_RANDOM)/g' \
|
||||
-e 's/@''GNULIB_RANDOM_R''@/$(GNULIB_RANDOM_R)/g' \
|
||||
-e 's/@''GNULIB_REALLOC_POSIX''@/$(GNULIB_REALLOC_POSIX)/g' \
|
||||
|
@ -2315,6 +2451,7 @@ stdlib.h: stdlib.in.h $(top_builddir)/config.status $(CXXDEFS_H) \
|
|||
-e 's|@''HAVE_POSIX_OPENPT''@|$(HAVE_POSIX_OPENPT)|g' \
|
||||
-e 's|@''HAVE_PTSNAME''@|$(HAVE_PTSNAME)|g' \
|
||||
-e 's|@''HAVE_PTSNAME_R''@|$(HAVE_PTSNAME_R)|g' \
|
||||
-e 's|@''HAVE_QSORT_R''@|$(HAVE_QSORT_R)|g' \
|
||||
-e 's|@''HAVE_RANDOM''@|$(HAVE_RANDOM)|g' \
|
||||
-e 's|@''HAVE_RANDOM_H''@|$(HAVE_RANDOM_H)|g' \
|
||||
-e 's|@''HAVE_RANDOM_R''@|$(HAVE_RANDOM_R)|g' \
|
||||
|
@ -2337,6 +2474,7 @@ stdlib.h: stdlib.in.h $(top_builddir)/config.status $(CXXDEFS_H) \
|
|||
-e 's|@''REPLACE_PTSNAME''@|$(REPLACE_PTSNAME)|g' \
|
||||
-e 's|@''REPLACE_PTSNAME_R''@|$(REPLACE_PTSNAME_R)|g' \
|
||||
-e 's|@''REPLACE_PUTENV''@|$(REPLACE_PUTENV)|g' \
|
||||
-e 's|@''REPLACE_QSORT_R''@|$(REPLACE_QSORT_R)|g' \
|
||||
-e 's|@''REPLACE_RANDOM_R''@|$(REPLACE_RANDOM_R)|g' \
|
||||
-e 's|@''REPLACE_REALLOC''@|$(REPLACE_REALLOC)|g' \
|
||||
-e 's|@''REPLACE_REALPATH''@|$(REPLACE_REALPATH)|g' \
|
||||
|
@ -2358,7 +2496,9 @@ EXTRA_DIST += stdlib.in.h
|
|||
|
||||
## begin gnulib module strdup-posix
|
||||
|
||||
if gl_GNULIB_ENABLED_f9850631dca91859e9cddac9359921c0
|
||||
|
||||
endif
|
||||
EXTRA_DIST += strdup.c
|
||||
|
||||
EXTRA_libgnu_la_SOURCES += strdup.c
|
||||
|
@ -2367,7 +2507,9 @@ EXTRA_libgnu_la_SOURCES += strdup.c
|
|||
|
||||
## begin gnulib module streq
|
||||
|
||||
if gl_GNULIB_ENABLED_streq
|
||||
|
||||
endif
|
||||
EXTRA_DIST += streq.h
|
||||
|
||||
## end gnulib module streq
|
||||
|
@ -2786,8 +2928,10 @@ EXTRA_DIST += sys_uio.in.h
|
|||
|
||||
## begin gnulib module tempname
|
||||
|
||||
if gl_GNULIB_ENABLED_tempname
|
||||
libgnu_la_SOURCES += tempname.c
|
||||
|
||||
endif
|
||||
EXTRA_DIST += tempname.h
|
||||
|
||||
## end gnulib module tempname
|
||||
|
@ -2812,10 +2956,12 @@ time.h: time.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H) $(
|
|||
-e 's/@''GNULIB_STRPTIME''@/$(GNULIB_STRPTIME)/g' \
|
||||
-e 's/@''GNULIB_TIMEGM''@/$(GNULIB_TIMEGM)/g' \
|
||||
-e 's/@''GNULIB_TIME_R''@/$(GNULIB_TIME_R)/g' \
|
||||
-e 's/@''GNULIB_TIME_RZ''@/$(GNULIB_TIME_RZ)/g' \
|
||||
-e 's|@''HAVE_DECL_LOCALTIME_R''@|$(HAVE_DECL_LOCALTIME_R)|g' \
|
||||
-e 's|@''HAVE_NANOSLEEP''@|$(HAVE_NANOSLEEP)|g' \
|
||||
-e 's|@''HAVE_STRPTIME''@|$(HAVE_STRPTIME)|g' \
|
||||
-e 's|@''HAVE_TIMEGM''@|$(HAVE_TIMEGM)|g' \
|
||||
-e 's|@''HAVE_TIMEZONE_T''@|$(HAVE_TIMEZONE_T)|g' \
|
||||
-e 's|@''REPLACE_GMTIME''@|$(REPLACE_GMTIME)|g' \
|
||||
-e 's|@''REPLACE_LOCALTIME''@|$(REPLACE_LOCALTIME)|g' \
|
||||
-e 's|@''REPLACE_LOCALTIME_R''@|$(REPLACE_LOCALTIME_R)|g' \
|
||||
|
@ -2825,6 +2971,7 @@ time.h: time.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H) $(
|
|||
-e 's|@''PTHREAD_H_DEFINES_STRUCT_TIMESPEC''@|$(PTHREAD_H_DEFINES_STRUCT_TIMESPEC)|g' \
|
||||
-e 's|@''SYS_TIME_H_DEFINES_STRUCT_TIMESPEC''@|$(SYS_TIME_H_DEFINES_STRUCT_TIMESPEC)|g' \
|
||||
-e 's|@''TIME_H_DEFINES_STRUCT_TIMESPEC''@|$(TIME_H_DEFINES_STRUCT_TIMESPEC)|g' \
|
||||
-e 's|@''UNISTD_H_DEFINES_STRUCT_TIMESPEC''@|$(UNISTD_H_DEFINES_STRUCT_TIMESPEC)|g' \
|
||||
-e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \
|
||||
-e '/definition of _GL_ARG_NONNULL/r $(ARG_NONNULL_H)' \
|
||||
-e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)' \
|
||||
|
@ -2839,13 +2986,35 @@ EXTRA_DIST += time.in.h
|
|||
|
||||
## begin gnulib module time_r
|
||||
|
||||
if gl_GNULIB_ENABLED_time_r
|
||||
|
||||
endif
|
||||
EXTRA_DIST += time_r.c
|
||||
|
||||
EXTRA_libgnu_la_SOURCES += time_r.c
|
||||
|
||||
## end gnulib module time_r
|
||||
|
||||
## begin gnulib module time_rz
|
||||
|
||||
|
||||
EXTRA_DIST += time-internal.h time_rz.c
|
||||
|
||||
EXTRA_libgnu_la_SOURCES += time_rz.c
|
||||
|
||||
## end gnulib module time_rz
|
||||
|
||||
## begin gnulib module timegm
|
||||
|
||||
if gl_GNULIB_ENABLED_timegm
|
||||
|
||||
endif
|
||||
EXTRA_DIST += mktime-internal.h timegm.c
|
||||
|
||||
EXTRA_libgnu_la_SOURCES += timegm.c
|
||||
|
||||
## end gnulib module timegm
|
||||
|
||||
## begin gnulib module times
|
||||
|
||||
|
||||
|
@ -2944,7 +3113,6 @@ unistd.h: unistd.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H
|
|||
-e 's|@''HAVE_GETDTABLESIZE''@|$(HAVE_GETDTABLESIZE)|g' \
|
||||
-e 's|@''HAVE_GETGROUPS''@|$(HAVE_GETGROUPS)|g' \
|
||||
-e 's|@''HAVE_GETHOSTNAME''@|$(HAVE_GETHOSTNAME)|g' \
|
||||
-e 's|@''HAVE_GETLOGIN''@|$(HAVE_GETLOGIN)|g' \
|
||||
-e 's|@''HAVE_GETPAGESIZE''@|$(HAVE_GETPAGESIZE)|g' \
|
||||
-e 's|@''HAVE_GROUP_MEMBER''@|$(HAVE_GROUP_MEMBER)|g' \
|
||||
-e 's|@''HAVE_LCHOWN''@|$(HAVE_LCHOWN)|g' \
|
||||
|
@ -2966,6 +3134,7 @@ unistd.h: unistd.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H
|
|||
-e 's|@''HAVE_DECL_FCHDIR''@|$(HAVE_DECL_FCHDIR)|g' \
|
||||
-e 's|@''HAVE_DECL_FDATASYNC''@|$(HAVE_DECL_FDATASYNC)|g' \
|
||||
-e 's|@''HAVE_DECL_GETDOMAINNAME''@|$(HAVE_DECL_GETDOMAINNAME)|g' \
|
||||
-e 's|@''HAVE_DECL_GETLOGIN''@|$(HAVE_DECL_GETLOGIN)|g' \
|
||||
-e 's|@''HAVE_DECL_GETLOGIN_R''@|$(HAVE_DECL_GETLOGIN_R)|g' \
|
||||
-e 's|@''HAVE_DECL_GETPAGESIZE''@|$(HAVE_DECL_GETPAGESIZE)|g' \
|
||||
-e 's|@''HAVE_DECL_GETUSERSHELL''@|$(HAVE_DECL_GETUSERSHELL)|g' \
|
||||
|
@ -2995,9 +3164,11 @@ unistd.h: unistd.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H
|
|||
-e 's|@''REPLACE_PWRITE''@|$(REPLACE_PWRITE)|g' \
|
||||
-e 's|@''REPLACE_READ''@|$(REPLACE_READ)|g' \
|
||||
-e 's|@''REPLACE_READLINK''@|$(REPLACE_READLINK)|g' \
|
||||
-e 's|@''REPLACE_READLINKAT''@|$(REPLACE_READLINKAT)|g' \
|
||||
-e 's|@''REPLACE_RMDIR''@|$(REPLACE_RMDIR)|g' \
|
||||
-e 's|@''REPLACE_SLEEP''@|$(REPLACE_SLEEP)|g' \
|
||||
-e 's|@''REPLACE_SYMLINK''@|$(REPLACE_SYMLINK)|g' \
|
||||
-e 's|@''REPLACE_SYMLINKAT''@|$(REPLACE_SYMLINKAT)|g' \
|
||||
-e 's|@''REPLACE_TTYNAME_R''@|$(REPLACE_TTYNAME_R)|g' \
|
||||
-e 's|@''REPLACE_UNLINK''@|$(REPLACE_UNLINK)|g' \
|
||||
-e 's|@''REPLACE_UNLINKAT''@|$(REPLACE_UNLINKAT)|g' \
|
||||
|
@ -3016,77 +3187,16 @@ EXTRA_DIST += unistd.in.h
|
|||
|
||||
## end gnulib module unistd
|
||||
|
||||
## begin gnulib module unistr/base
|
||||
## begin gnulib module unsetenv
|
||||
|
||||
BUILT_SOURCES += $(LIBUNISTRING_UNISTR_H)
|
||||
if gl_GNULIB_ENABLED_unsetenv
|
||||
|
||||
unistr.h: unistr.in.h
|
||||
$(AM_V_GEN)rm -f $@-t $@ && \
|
||||
{ echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \
|
||||
cat $(srcdir)/unistr.in.h; \
|
||||
} > $@-t && \
|
||||
mv -f $@-t $@
|
||||
MOSTLYCLEANFILES += unistr.h unistr.h-t
|
||||
|
||||
EXTRA_DIST += unistr.in.h
|
||||
|
||||
## end gnulib module unistr/base
|
||||
|
||||
## begin gnulib module unistr/u8-mbtouc
|
||||
|
||||
if LIBUNISTRING_COMPILE_UNISTR_U8_MBTOUC
|
||||
libgnu_la_SOURCES += unistr/u8-mbtouc.c unistr/u8-mbtouc-aux.c
|
||||
endif
|
||||
EXTRA_DIST += unsetenv.c
|
||||
|
||||
## end gnulib module unistr/u8-mbtouc
|
||||
EXTRA_libgnu_la_SOURCES += unsetenv.c
|
||||
|
||||
## begin gnulib module unistr/u8-mbtouc-unsafe
|
||||
|
||||
if LIBUNISTRING_COMPILE_UNISTR_U8_MBTOUC_UNSAFE
|
||||
libgnu_la_SOURCES += unistr/u8-mbtouc-unsafe.c unistr/u8-mbtouc-unsafe-aux.c
|
||||
endif
|
||||
|
||||
## end gnulib module unistr/u8-mbtouc-unsafe
|
||||
|
||||
## begin gnulib module unistr/u8-mbtoucr
|
||||
|
||||
if LIBUNISTRING_COMPILE_UNISTR_U8_MBTOUCR
|
||||
libgnu_la_SOURCES += unistr/u8-mbtoucr.c
|
||||
endif
|
||||
|
||||
## end gnulib module unistr/u8-mbtoucr
|
||||
|
||||
## begin gnulib module unistr/u8-prev
|
||||
|
||||
if LIBUNISTRING_COMPILE_UNISTR_U8_PREV
|
||||
libgnu_la_SOURCES += unistr/u8-prev.c
|
||||
endif
|
||||
|
||||
## end gnulib module unistr/u8-prev
|
||||
|
||||
## begin gnulib module unistr/u8-uctomb
|
||||
|
||||
if LIBUNISTRING_COMPILE_UNISTR_U8_UCTOMB
|
||||
libgnu_la_SOURCES += unistr/u8-uctomb.c unistr/u8-uctomb-aux.c
|
||||
endif
|
||||
|
||||
## end gnulib module unistr/u8-uctomb
|
||||
|
||||
## begin gnulib module unitypes
|
||||
|
||||
BUILT_SOURCES += $(LIBUNISTRING_UNITYPES_H)
|
||||
|
||||
unitypes.h: unitypes.in.h
|
||||
$(AM_V_GEN)rm -f $@-t $@ && \
|
||||
{ echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \
|
||||
cat $(srcdir)/unitypes.in.h; \
|
||||
} > $@-t && \
|
||||
mv -f $@-t $@
|
||||
MOSTLYCLEANFILES += unitypes.h unitypes.h-t
|
||||
|
||||
EXTRA_DIST += unitypes.in.h
|
||||
|
||||
## end gnulib module unitypes
|
||||
## end gnulib module unsetenv
|
||||
|
||||
## begin gnulib module useless-if-before-free
|
||||
|
||||
|
@ -3097,7 +3207,9 @@ EXTRA_DIST += $(top_srcdir)/build-aux/useless-if-before-free
|
|||
|
||||
## begin gnulib module vasnprintf
|
||||
|
||||
if gl_GNULIB_ENABLED_vasnprintf
|
||||
|
||||
endif
|
||||
EXTRA_DIST += asnprintf.c float+.h printf-args.c printf-args.h printf-parse.c printf-parse.h vasnprintf.c vasnprintf.h
|
||||
|
||||
EXTRA_libgnu_la_SOURCES += asnprintf.c printf-args.c printf-parse.c vasnprintf.c
|
||||
|
@ -3143,6 +3255,7 @@ wchar.h: wchar.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H)
|
|||
-e 's|@''HAVE_FEATURES_H''@|$(HAVE_FEATURES_H)|g' \
|
||||
-e 's|@''NEXT_WCHAR_H''@|$(NEXT_WCHAR_H)|g' \
|
||||
-e 's|@''HAVE_WCHAR_H''@|$(HAVE_WCHAR_H)|g' \
|
||||
-e 's/@''GNULIB_OVERRIDES_WINT_T''@/$(GNULIB_OVERRIDES_WINT_T)/g' \
|
||||
-e 's/@''GNULIB_BTOWC''@/$(GNULIB_BTOWC)/g' \
|
||||
-e 's/@''GNULIB_WCTOB''@/$(GNULIB_WCTOB)/g' \
|
||||
-e 's/@''GNULIB_MBSINIT''@/$(GNULIB_MBSINIT)/g' \
|
||||
|
@ -3250,7 +3363,9 @@ EXTRA_DIST += wchar.in.h
|
|||
|
||||
## begin gnulib module wcrtomb
|
||||
|
||||
if gl_GNULIB_ENABLED_wcrtomb
|
||||
|
||||
endif
|
||||
EXTRA_DIST += wcrtomb.c
|
||||
|
||||
EXTRA_libgnu_la_SOURCES += wcrtomb.c
|
||||
|
@ -3259,6 +3374,7 @@ EXTRA_libgnu_la_SOURCES += wcrtomb.c
|
|||
|
||||
## begin gnulib module wctype-h
|
||||
|
||||
if gl_GNULIB_ENABLED_3dcce957eadc896e63ab5f137947b410
|
||||
BUILT_SOURCES += wctype.h
|
||||
libgnu_la_SOURCES += wctype-h.c
|
||||
|
||||
|
@ -3273,6 +3389,7 @@ wctype.h: wctype.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(WARN_ON_USE_H
|
|||
-e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \
|
||||
-e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \
|
||||
-e 's|@''NEXT_WCTYPE_H''@|$(NEXT_WCTYPE_H)|g' \
|
||||
-e 's/@''GNULIB_OVERRIDES_WINT_T''@/$(GNULIB_OVERRIDES_WINT_T)/g' \
|
||||
-e 's/@''GNULIB_ISWBLANK''@/$(GNULIB_ISWBLANK)/g' \
|
||||
-e 's/@''GNULIB_WCTYPE''@/$(GNULIB_WCTYPE)/g' \
|
||||
-e 's/@''GNULIB_ISWCTYPE''@/$(GNULIB_ISWCTYPE)/g' \
|
||||
|
@ -3293,6 +3410,7 @@ wctype.h: wctype.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(WARN_ON_USE_H
|
|||
mv $@-t $@
|
||||
MOSTLYCLEANFILES += wctype.h wctype.h-t
|
||||
|
||||
endif
|
||||
EXTRA_DIST += wctype.in.h
|
||||
|
||||
## end gnulib module wctype-h
|
||||
|
@ -3306,10 +3424,19 @@ EXTRA_libgnu_la_SOURCES += write.c
|
|||
|
||||
## end gnulib module write
|
||||
|
||||
## begin gnulib module xalloc-oversized
|
||||
|
||||
|
||||
EXTRA_DIST += xalloc-oversized.h
|
||||
|
||||
## end gnulib module xalloc-oversized
|
||||
|
||||
## begin gnulib module xsize
|
||||
|
||||
if gl_GNULIB_ENABLED_xsize
|
||||
libgnu_la_SOURCES += xsize.h xsize.c
|
||||
|
||||
endif
|
||||
## end gnulib module xsize
|
||||
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* accept.c --- wrappers for Windows accept function
|
||||
|
||||
Copyright (C) 2008-2014 Free Software Foundation, Inc.
|
||||
Copyright (C) 2008-2017 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 as published by
|
||||
|
|
128
lib/accept4.c
Normal file
128
lib/accept4.c
Normal file
|
@ -0,0 +1,128 @@
|
|||
/* Accept a connection on a socket, with specific opening flags.
|
||||
Copyright (C) 2009-2017 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 as published by
|
||||
the Free Software Foundation; either version 2, 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 Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License along
|
||||
with this program; if not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
/* Specification. */
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include "binary-io.h"
|
||||
#include "msvc-nothrow.h"
|
||||
|
||||
#ifndef SOCK_CLOEXEC
|
||||
# define SOCK_CLOEXEC 0
|
||||
#endif
|
||||
|
||||
int
|
||||
accept4 (int sockfd, struct sockaddr *addr, socklen_t *addrlen, int flags)
|
||||
{
|
||||
int fd;
|
||||
|
||||
#if HAVE_ACCEPT4
|
||||
# undef accept4
|
||||
/* Try the system call first, if it exists. (We may be running with a glibc
|
||||
that has the function but with an older kernel that lacks it.) */
|
||||
{
|
||||
/* Cache the information whether the system call really exists. */
|
||||
static int have_accept4_really; /* 0 = unknown, 1 = yes, -1 = no */
|
||||
if (have_accept4_really >= 0)
|
||||
{
|
||||
int result = accept4 (sockfd, addr, addrlen, flags);
|
||||
if (!(result < 0 && errno == ENOSYS))
|
||||
{
|
||||
have_accept4_really = 1;
|
||||
return result;
|
||||
}
|
||||
have_accept4_really = -1;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Check the supported flags. */
|
||||
if ((flags & ~(SOCK_CLOEXEC | O_TEXT | O_BINARY)) != 0)
|
||||
{
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
fd = accept (sockfd, addr, addrlen);
|
||||
if (fd < 0)
|
||||
return -1;
|
||||
|
||||
#if SOCK_CLOEXEC
|
||||
# if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
|
||||
/* Native Windows API. */
|
||||
if (flags & SOCK_CLOEXEC)
|
||||
{
|
||||
HANDLE curr_process = GetCurrentProcess ();
|
||||
HANDLE old_handle = (HANDLE) _get_osfhandle (fd);
|
||||
HANDLE new_handle;
|
||||
int nfd;
|
||||
|
||||
if (!DuplicateHandle (curr_process, /* SourceProcessHandle */
|
||||
old_handle, /* SourceHandle */
|
||||
curr_process, /* TargetProcessHandle */
|
||||
(PHANDLE) &new_handle, /* TargetHandle */
|
||||
(DWORD) 0, /* DesiredAccess */
|
||||
FALSE, /* InheritHandle */
|
||||
DUPLICATE_SAME_ACCESS)) /* Options */
|
||||
{
|
||||
close (fd);
|
||||
errno = EBADF; /* arbitrary */
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Closing fd before allocating the new fd ensures that the new fd will
|
||||
have the minimum possible value. */
|
||||
close (fd);
|
||||
nfd = _open_osfhandle ((intptr_t) new_handle,
|
||||
O_NOINHERIT | (flags & (O_TEXT | O_BINARY)));
|
||||
if (nfd < 0)
|
||||
{
|
||||
CloseHandle (new_handle);
|
||||
return -1;
|
||||
}
|
||||
return nfd;
|
||||
}
|
||||
# else
|
||||
/* Unix API. */
|
||||
if (flags & SOCK_CLOEXEC)
|
||||
{
|
||||
int fcntl_flags;
|
||||
|
||||
if ((fcntl_flags = fcntl (fd, F_GETFD, 0)) < 0
|
||||
|| fcntl (fd, F_SETFD, fcntl_flags | FD_CLOEXEC) == -1)
|
||||
{
|
||||
int saved_errno = errno;
|
||||
close (fd);
|
||||
errno = saved_errno;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if O_BINARY
|
||||
if (flags & O_BINARY)
|
||||
set_binary_mode (fd, O_BINARY);
|
||||
else if (flags & O_TEXT)
|
||||
set_binary_mode (fd, O_TEXT);
|
||||
#endif
|
||||
|
||||
return fd;
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
/* Determine alignment of types.
|
||||
Copyright (C) 2003-2004, 2006, 2009-2014 Free Software Foundation, Inc.
|
||||
Copyright (C) 2003-2004, 2006, 2009-2017 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 as published by
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* Memory allocation on the stack.
|
||||
|
||||
Copyright (C) 1995, 1999, 2001-2004, 2006-2014 Free Software Foundation,
|
||||
Copyright (C) 1995, 1999, 2001-2004, 2006-2017 Free Software Foundation,
|
||||
Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
|
@ -51,6 +51,8 @@ extern "C"
|
|||
void *_alloca (unsigned short);
|
||||
# pragma intrinsic (_alloca)
|
||||
# define alloca _alloca
|
||||
# elif defined __MVS__
|
||||
# include <stdlib.h>
|
||||
# else
|
||||
# include <stddef.h>
|
||||
# ifdef __cplusplus
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* A GNU-like <arpa/inet.h>.
|
||||
|
||||
Copyright (C) 2005-2006, 2008-2014 Free Software Foundation, Inc.
|
||||
Copyright (C) 2005-2006, 2008-2017 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 as published by
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* Formatted output to strings.
|
||||
Copyright (C) 1999, 2002, 2006, 2009-2014 Free Software Foundation, Inc.
|
||||
Copyright (C) 1999, 2002, 2006, 2009-2017 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 as published by
|
||||
|
|
37
lib/assure.h
Normal file
37
lib/assure.h
Normal file
|
@ -0,0 +1,37 @@
|
|||
/* Run-time assert-like macros.
|
||||
|
||||
Copyright (C) 2014-2017 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 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 Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
/* Written by Paul Eggert. */
|
||||
|
||||
#ifndef _GL_ASSURE_H
|
||||
#define _GL_ASSURE_H
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
/* Check E's value at runtime, and report an error and abort if not.
|
||||
However, do nothng if NDEBUG is defined.
|
||||
|
||||
Unlike standard 'assert', this macro always compiles E even when NDEBUG
|
||||
is defined, so as to catch typos and avoid some GCC warnings. */
|
||||
|
||||
#ifdef NDEBUG
|
||||
# define assure(E) ((void) (0 && (E)))
|
||||
#else
|
||||
# define assure(E) assert (E)
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -1,6 +1,6 @@
|
|||
/* basename.c -- return the last element in a file name
|
||||
|
||||
Copyright (C) 1990, 1998-2001, 2003-2006, 2009-2014 Free Software
|
||||
Copyright (C) 1990, 1998-2001, 2003-2006, 2009-2017 Free Software
|
||||
Foundation, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
#include <config.h>
|
||||
#define BINARY_IO_INLINE _GL_EXTERN_INLINE
|
||||
#include "binary-io.h"
|
||||
typedef int dummy;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* Binary mode I/O.
|
||||
Copyright (C) 2001, 2003, 2005, 2008-2014 Free Software Foundation, Inc.
|
||||
Copyright (C) 2001, 2003, 2005, 2008-2017 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 as published by
|
||||
|
@ -60,7 +60,7 @@ set_binary_mode (int fd, int mode)
|
|||
|
||||
/* SET_BINARY (fd);
|
||||
changes the file descriptor fd to perform binary I/O. */
|
||||
#ifdef __DJGPP__
|
||||
#if defined __DJGPP__ || defined __EMX__
|
||||
# include <unistd.h> /* declares isatty() */
|
||||
/* Avoid putting stdin/stdout in binary mode if it is connected to
|
||||
the console, because that would make it impossible for the user
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* bind.c --- wrappers for Windows bind function
|
||||
|
||||
Copyright (C) 2008-2014 Free Software Foundation, Inc.
|
||||
Copyright (C) 2008-2017 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 as published by
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* Convert unibyte character to wide character.
|
||||
Copyright (C) 2008, 2010-2014 Free Software Foundation, Inc.
|
||||
Copyright (C) 2008, 2010-2017 Free Software Foundation, Inc.
|
||||
Written by Bruno Haible <bruno@clisp.org>, 2008.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* byteswap.h - Byte swapping
|
||||
Copyright (C) 2005, 2007, 2009-2014 Free Software Foundation, Inc.
|
||||
Copyright (C) 2005, 2007, 2009-2017 Free Software Foundation, Inc.
|
||||
Written by Oskar Liljeblad <oskar@osk.mine.nu>, 2005.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
|
|
394
lib/c-ctype.c
394
lib/c-ctype.c
|
@ -1,395 +1,3 @@
|
|||
/* Character handling in C locale.
|
||||
|
||||
Copyright 2000-2003, 2006, 2009-2014 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 as published by
|
||||
the Free Software Foundation; either version 2 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 Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program; if not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
/* Specification. */
|
||||
#define NO_C_CTYPE_MACROS
|
||||
#define C_CTYPE_INLINE _GL_EXTERN_INLINE
|
||||
#include "c-ctype.h"
|
||||
|
||||
/* The function isascii is not locale dependent. Its use in EBCDIC is
|
||||
questionable. */
|
||||
bool
|
||||
c_isascii (int c)
|
||||
{
|
||||
return (c >= 0x00 && c <= 0x7f);
|
||||
}
|
||||
|
||||
bool
|
||||
c_isalnum (int c)
|
||||
{
|
||||
#if C_CTYPE_CONSECUTIVE_DIGITS \
|
||||
&& C_CTYPE_CONSECUTIVE_UPPERCASE && C_CTYPE_CONSECUTIVE_LOWERCASE
|
||||
#if C_CTYPE_ASCII
|
||||
return ((c >= '0' && c <= '9')
|
||||
|| ((c & ~0x20) >= 'A' && (c & ~0x20) <= 'Z'));
|
||||
#else
|
||||
return ((c >= '0' && c <= '9')
|
||||
|| (c >= 'A' && c <= 'Z')
|
||||
|| (c >= 'a' && c <= 'z'));
|
||||
#endif
|
||||
#else
|
||||
switch (c)
|
||||
{
|
||||
case '0': case '1': case '2': case '3': case '4': case '5':
|
||||
case '6': case '7': case '8': case '9':
|
||||
case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
|
||||
case 'G': case 'H': case 'I': case 'J': case 'K': case 'L':
|
||||
case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R':
|
||||
case 'S': case 'T': case 'U': case 'V': case 'W': case 'X':
|
||||
case 'Y': case 'Z':
|
||||
case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
|
||||
case 'g': case 'h': case 'i': case 'j': case 'k': case 'l':
|
||||
case 'm': case 'n': case 'o': case 'p': case 'q': case 'r':
|
||||
case 's': case 't': case 'u': case 'v': case 'w': case 'x':
|
||||
case 'y': case 'z':
|
||||
return 1;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
bool
|
||||
c_isalpha (int c)
|
||||
{
|
||||
#if C_CTYPE_CONSECUTIVE_UPPERCASE && C_CTYPE_CONSECUTIVE_LOWERCASE
|
||||
#if C_CTYPE_ASCII
|
||||
return ((c & ~0x20) >= 'A' && (c & ~0x20) <= 'Z');
|
||||
#else
|
||||
return ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z'));
|
||||
#endif
|
||||
#else
|
||||
switch (c)
|
||||
{
|
||||
case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
|
||||
case 'G': case 'H': case 'I': case 'J': case 'K': case 'L':
|
||||
case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R':
|
||||
case 'S': case 'T': case 'U': case 'V': case 'W': case 'X':
|
||||
case 'Y': case 'Z':
|
||||
case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
|
||||
case 'g': case 'h': case 'i': case 'j': case 'k': case 'l':
|
||||
case 'm': case 'n': case 'o': case 'p': case 'q': case 'r':
|
||||
case 's': case 't': case 'u': case 'v': case 'w': case 'x':
|
||||
case 'y': case 'z':
|
||||
return 1;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
bool
|
||||
c_isblank (int c)
|
||||
{
|
||||
return (c == ' ' || c == '\t');
|
||||
}
|
||||
|
||||
bool
|
||||
c_iscntrl (int c)
|
||||
{
|
||||
#if C_CTYPE_ASCII
|
||||
return ((c & ~0x1f) == 0 || c == 0x7f);
|
||||
#else
|
||||
switch (c)
|
||||
{
|
||||
case ' ': case '!': case '"': case '#': case '$': case '%':
|
||||
case '&': case '\'': case '(': case ')': case '*': case '+':
|
||||
case ',': case '-': case '.': case '/':
|
||||
case '0': case '1': case '2': case '3': case '4': case '5':
|
||||
case '6': case '7': case '8': case '9':
|
||||
case ':': case ';': case '<': case '=': case '>': case '?':
|
||||
case '@':
|
||||
case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
|
||||
case 'G': case 'H': case 'I': case 'J': case 'K': case 'L':
|
||||
case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R':
|
||||
case 'S': case 'T': case 'U': case 'V': case 'W': case 'X':
|
||||
case 'Y': case 'Z':
|
||||
case '[': case '\\': case ']': case '^': case '_': case '`':
|
||||
case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
|
||||
case 'g': case 'h': case 'i': case 'j': case 'k': case 'l':
|
||||
case 'm': case 'n': case 'o': case 'p': case 'q': case 'r':
|
||||
case 's': case 't': case 'u': case 'v': case 'w': case 'x':
|
||||
case 'y': case 'z':
|
||||
case '{': case '|': case '}': case '~':
|
||||
return 0;
|
||||
default:
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
bool
|
||||
c_isdigit (int c)
|
||||
{
|
||||
#if C_CTYPE_CONSECUTIVE_DIGITS
|
||||
return (c >= '0' && c <= '9');
|
||||
#else
|
||||
switch (c)
|
||||
{
|
||||
case '0': case '1': case '2': case '3': case '4': case '5':
|
||||
case '6': case '7': case '8': case '9':
|
||||
return 1;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
bool
|
||||
c_islower (int c)
|
||||
{
|
||||
#if C_CTYPE_CONSECUTIVE_LOWERCASE
|
||||
return (c >= 'a' && c <= 'z');
|
||||
#else
|
||||
switch (c)
|
||||
{
|
||||
case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
|
||||
case 'g': case 'h': case 'i': case 'j': case 'k': case 'l':
|
||||
case 'm': case 'n': case 'o': case 'p': case 'q': case 'r':
|
||||
case 's': case 't': case 'u': case 'v': case 'w': case 'x':
|
||||
case 'y': case 'z':
|
||||
return 1;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
bool
|
||||
c_isgraph (int c)
|
||||
{
|
||||
#if C_CTYPE_ASCII
|
||||
return (c >= '!' && c <= '~');
|
||||
#else
|
||||
switch (c)
|
||||
{
|
||||
case '!': case '"': case '#': case '$': case '%': case '&':
|
||||
case '\'': case '(': case ')': case '*': case '+': case ',':
|
||||
case '-': case '.': case '/':
|
||||
case '0': case '1': case '2': case '3': case '4': case '5':
|
||||
case '6': case '7': case '8': case '9':
|
||||
case ':': case ';': case '<': case '=': case '>': case '?':
|
||||
case '@':
|
||||
case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
|
||||
case 'G': case 'H': case 'I': case 'J': case 'K': case 'L':
|
||||
case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R':
|
||||
case 'S': case 'T': case 'U': case 'V': case 'W': case 'X':
|
||||
case 'Y': case 'Z':
|
||||
case '[': case '\\': case ']': case '^': case '_': case '`':
|
||||
case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
|
||||
case 'g': case 'h': case 'i': case 'j': case 'k': case 'l':
|
||||
case 'm': case 'n': case 'o': case 'p': case 'q': case 'r':
|
||||
case 's': case 't': case 'u': case 'v': case 'w': case 'x':
|
||||
case 'y': case 'z':
|
||||
case '{': case '|': case '}': case '~':
|
||||
return 1;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
bool
|
||||
c_isprint (int c)
|
||||
{
|
||||
#if C_CTYPE_ASCII
|
||||
return (c >= ' ' && c <= '~');
|
||||
#else
|
||||
switch (c)
|
||||
{
|
||||
case ' ': case '!': case '"': case '#': case '$': case '%':
|
||||
case '&': case '\'': case '(': case ')': case '*': case '+':
|
||||
case ',': case '-': case '.': case '/':
|
||||
case '0': case '1': case '2': case '3': case '4': case '5':
|
||||
case '6': case '7': case '8': case '9':
|
||||
case ':': case ';': case '<': case '=': case '>': case '?':
|
||||
case '@':
|
||||
case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
|
||||
case 'G': case 'H': case 'I': case 'J': case 'K': case 'L':
|
||||
case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R':
|
||||
case 'S': case 'T': case 'U': case 'V': case 'W': case 'X':
|
||||
case 'Y': case 'Z':
|
||||
case '[': case '\\': case ']': case '^': case '_': case '`':
|
||||
case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
|
||||
case 'g': case 'h': case 'i': case 'j': case 'k': case 'l':
|
||||
case 'm': case 'n': case 'o': case 'p': case 'q': case 'r':
|
||||
case 's': case 't': case 'u': case 'v': case 'w': case 'x':
|
||||
case 'y': case 'z':
|
||||
case '{': case '|': case '}': case '~':
|
||||
return 1;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
bool
|
||||
c_ispunct (int c)
|
||||
{
|
||||
#if C_CTYPE_ASCII
|
||||
return ((c >= '!' && c <= '~')
|
||||
&& !((c >= '0' && c <= '9')
|
||||
|| ((c & ~0x20) >= 'A' && (c & ~0x20) <= 'Z')));
|
||||
#else
|
||||
switch (c)
|
||||
{
|
||||
case '!': case '"': case '#': case '$': case '%': case '&':
|
||||
case '\'': case '(': case ')': case '*': case '+': case ',':
|
||||
case '-': case '.': case '/':
|
||||
case ':': case ';': case '<': case '=': case '>': case '?':
|
||||
case '@':
|
||||
case '[': case '\\': case ']': case '^': case '_': case '`':
|
||||
case '{': case '|': case '}': case '~':
|
||||
return 1;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
bool
|
||||
c_isspace (int c)
|
||||
{
|
||||
return (c == ' ' || c == '\t'
|
||||
|| c == '\n' || c == '\v' || c == '\f' || c == '\r');
|
||||
}
|
||||
|
||||
bool
|
||||
c_isupper (int c)
|
||||
{
|
||||
#if C_CTYPE_CONSECUTIVE_UPPERCASE
|
||||
return (c >= 'A' && c <= 'Z');
|
||||
#else
|
||||
switch (c)
|
||||
{
|
||||
case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
|
||||
case 'G': case 'H': case 'I': case 'J': case 'K': case 'L':
|
||||
case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R':
|
||||
case 'S': case 'T': case 'U': case 'V': case 'W': case 'X':
|
||||
case 'Y': case 'Z':
|
||||
return 1;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
bool
|
||||
c_isxdigit (int c)
|
||||
{
|
||||
#if C_CTYPE_CONSECUTIVE_DIGITS \
|
||||
&& C_CTYPE_CONSECUTIVE_UPPERCASE && C_CTYPE_CONSECUTIVE_LOWERCASE
|
||||
#if C_CTYPE_ASCII
|
||||
return ((c >= '0' && c <= '9')
|
||||
|| ((c & ~0x20) >= 'A' && (c & ~0x20) <= 'F'));
|
||||
#else
|
||||
return ((c >= '0' && c <= '9')
|
||||
|| (c >= 'A' && c <= 'F')
|
||||
|| (c >= 'a' && c <= 'f'));
|
||||
#endif
|
||||
#else
|
||||
switch (c)
|
||||
{
|
||||
case '0': case '1': case '2': case '3': case '4': case '5':
|
||||
case '6': case '7': case '8': case '9':
|
||||
case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
|
||||
case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
|
||||
return 1;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
int
|
||||
c_tolower (int c)
|
||||
{
|
||||
#if C_CTYPE_CONSECUTIVE_UPPERCASE && C_CTYPE_CONSECUTIVE_LOWERCASE
|
||||
return (c >= 'A' && c <= 'Z' ? c - 'A' + 'a' : c);
|
||||
#else
|
||||
switch (c)
|
||||
{
|
||||
case 'A': return 'a';
|
||||
case 'B': return 'b';
|
||||
case 'C': return 'c';
|
||||
case 'D': return 'd';
|
||||
case 'E': return 'e';
|
||||
case 'F': return 'f';
|
||||
case 'G': return 'g';
|
||||
case 'H': return 'h';
|
||||
case 'I': return 'i';
|
||||
case 'J': return 'j';
|
||||
case 'K': return 'k';
|
||||
case 'L': return 'l';
|
||||
case 'M': return 'm';
|
||||
case 'N': return 'n';
|
||||
case 'O': return 'o';
|
||||
case 'P': return 'p';
|
||||
case 'Q': return 'q';
|
||||
case 'R': return 'r';
|
||||
case 'S': return 's';
|
||||
case 'T': return 't';
|
||||
case 'U': return 'u';
|
||||
case 'V': return 'v';
|
||||
case 'W': return 'w';
|
||||
case 'X': return 'x';
|
||||
case 'Y': return 'y';
|
||||
case 'Z': return 'z';
|
||||
default: return c;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
int
|
||||
c_toupper (int c)
|
||||
{
|
||||
#if C_CTYPE_CONSECUTIVE_UPPERCASE && C_CTYPE_CONSECUTIVE_LOWERCASE
|
||||
return (c >= 'a' && c <= 'z' ? c - 'a' + 'A' : c);
|
||||
#else
|
||||
switch (c)
|
||||
{
|
||||
case 'a': return 'A';
|
||||
case 'b': return 'B';
|
||||
case 'c': return 'C';
|
||||
case 'd': return 'D';
|
||||
case 'e': return 'E';
|
||||
case 'f': return 'F';
|
||||
case 'g': return 'G';
|
||||
case 'h': return 'H';
|
||||
case 'i': return 'I';
|
||||
case 'j': return 'J';
|
||||
case 'k': return 'K';
|
||||
case 'l': return 'L';
|
||||
case 'm': return 'M';
|
||||
case 'n': return 'N';
|
||||
case 'o': return 'O';
|
||||
case 'p': return 'P';
|
||||
case 'q': return 'Q';
|
||||
case 'r': return 'R';
|
||||
case 's': return 'S';
|
||||
case 't': return 'T';
|
||||
case 'u': return 'U';
|
||||
case 'v': return 'V';
|
||||
case 'w': return 'W';
|
||||
case 'x': return 'X';
|
||||
case 'y': return 'Y';
|
||||
case 'z': return 'Z';
|
||||
default: return c;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
|
453
lib/c-ctype.h
453
lib/c-ctype.h
|
@ -5,7 +5,7 @@
|
|||
<ctype.h> functions' behaviour depends on the current locale set via
|
||||
setlocale.
|
||||
|
||||
Copyright (C) 2000-2003, 2006, 2008-2014 Free Software Foundation, Inc.
|
||||
Copyright (C) 2000-2003, 2006, 2008-2017 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 as published by
|
||||
|
@ -25,6 +25,13 @@ along with this program; if not, see <http://www.gnu.org/licenses/>. */
|
|||
|
||||
#include <stdbool.h>
|
||||
|
||||
#ifndef _GL_INLINE_HEADER_BEGIN
|
||||
#error "Please include config.h first."
|
||||
#endif
|
||||
_GL_INLINE_HEADER_BEGIN
|
||||
#ifndef C_CTYPE_INLINE
|
||||
# define C_CTYPE_INLINE _GL_INLINE
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
@ -39,38 +46,6 @@ extern "C" {
|
|||
characters. */
|
||||
|
||||
|
||||
/* Check whether the ASCII optimizations apply. */
|
||||
|
||||
/* ANSI C89 (and ISO C99 5.2.1.3 too) already guarantees that
|
||||
'0', '1', ..., '9' have consecutive integer values. */
|
||||
#define C_CTYPE_CONSECUTIVE_DIGITS 1
|
||||
|
||||
#if ('A' <= 'Z') \
|
||||
&& ('A' + 1 == 'B') && ('B' + 1 == 'C') && ('C' + 1 == 'D') \
|
||||
&& ('D' + 1 == 'E') && ('E' + 1 == 'F') && ('F' + 1 == 'G') \
|
||||
&& ('G' + 1 == 'H') && ('H' + 1 == 'I') && ('I' + 1 == 'J') \
|
||||
&& ('J' + 1 == 'K') && ('K' + 1 == 'L') && ('L' + 1 == 'M') \
|
||||
&& ('M' + 1 == 'N') && ('N' + 1 == 'O') && ('O' + 1 == 'P') \
|
||||
&& ('P' + 1 == 'Q') && ('Q' + 1 == 'R') && ('R' + 1 == 'S') \
|
||||
&& ('S' + 1 == 'T') && ('T' + 1 == 'U') && ('U' + 1 == 'V') \
|
||||
&& ('V' + 1 == 'W') && ('W' + 1 == 'X') && ('X' + 1 == 'Y') \
|
||||
&& ('Y' + 1 == 'Z')
|
||||
#define C_CTYPE_CONSECUTIVE_UPPERCASE 1
|
||||
#endif
|
||||
|
||||
#if ('a' <= 'z') \
|
||||
&& ('a' + 1 == 'b') && ('b' + 1 == 'c') && ('c' + 1 == 'd') \
|
||||
&& ('d' + 1 == 'e') && ('e' + 1 == 'f') && ('f' + 1 == 'g') \
|
||||
&& ('g' + 1 == 'h') && ('h' + 1 == 'i') && ('i' + 1 == 'j') \
|
||||
&& ('j' + 1 == 'k') && ('k' + 1 == 'l') && ('l' + 1 == 'm') \
|
||||
&& ('m' + 1 == 'n') && ('n' + 1 == 'o') && ('o' + 1 == 'p') \
|
||||
&& ('p' + 1 == 'q') && ('q' + 1 == 'r') && ('r' + 1 == 's') \
|
||||
&& ('s' + 1 == 't') && ('t' + 1 == 'u') && ('u' + 1 == 'v') \
|
||||
&& ('v' + 1 == 'w') && ('w' + 1 == 'x') && ('x' + 1 == 'y') \
|
||||
&& ('y' + 1 == 'z')
|
||||
#define C_CTYPE_CONSECUTIVE_LOWERCASE 1
|
||||
#endif
|
||||
|
||||
#if (' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \
|
||||
&& ('%' == 37) && ('&' == 38) && ('\'' == 39) && ('(' == 40) \
|
||||
&& (')' == 41) && ('*' == 42) && ('+' == 43) && (',' == 44) \
|
||||
|
@ -96,11 +71,84 @@ extern "C" {
|
|||
&& ('{' == 123) && ('|' == 124) && ('}' == 125) && ('~' == 126)
|
||||
/* The character set is ASCII or one of its variants or extensions, not EBCDIC.
|
||||
Testing the value of '\n' and '\r' is not relevant. */
|
||||
#define C_CTYPE_ASCII 1
|
||||
# define C_CTYPE_ASCII 1
|
||||
#elif ! (' ' == '\x40' && '0' == '\xf0' \
|
||||
&& 'A' == '\xc1' && 'J' == '\xd1' && 'S' == '\xe2' \
|
||||
&& 'a' == '\x81' && 'j' == '\x91' && 's' == '\xa2')
|
||||
# error "Only ASCII and EBCDIC are supported"
|
||||
#endif
|
||||
|
||||
#if 'A' < 0
|
||||
# error "EBCDIC and char is signed -- not supported"
|
||||
#endif
|
||||
|
||||
/* Function declarations. */
|
||||
/* Cases for control characters. */
|
||||
|
||||
#define _C_CTYPE_CNTRL \
|
||||
case '\a': case '\b': case '\f': case '\n': \
|
||||
case '\r': case '\t': case '\v': \
|
||||
_C_CTYPE_OTHER_CNTRL
|
||||
|
||||
/* ASCII control characters other than those with \-letter escapes. */
|
||||
|
||||
#if C_CTYPE_ASCII
|
||||
# define _C_CTYPE_OTHER_CNTRL \
|
||||
case '\x00': case '\x01': case '\x02': case '\x03': \
|
||||
case '\x04': case '\x05': case '\x06': case '\x0e': \
|
||||
case '\x0f': case '\x10': case '\x11': case '\x12': \
|
||||
case '\x13': case '\x14': case '\x15': case '\x16': \
|
||||
case '\x17': case '\x18': case '\x19': case '\x1a': \
|
||||
case '\x1b': case '\x1c': case '\x1d': case '\x1e': \
|
||||
case '\x1f': case '\x7f'
|
||||
#else
|
||||
/* Use EBCDIC code page 1047's assignments for ASCII control chars;
|
||||
assume all EBCDIC code pages agree about these assignments. */
|
||||
# define _C_CTYPE_OTHER_CNTRL \
|
||||
case '\x00': case '\x01': case '\x02': case '\x03': \
|
||||
case '\x07': case '\x0e': case '\x0f': case '\x10': \
|
||||
case '\x11': case '\x12': case '\x13': case '\x18': \
|
||||
case '\x19': case '\x1c': case '\x1d': case '\x1e': \
|
||||
case '\x1f': case '\x26': case '\x27': case '\x2d': \
|
||||
case '\x2e': case '\x32': case '\x37': case '\x3c': \
|
||||
case '\x3d': case '\x3f'
|
||||
#endif
|
||||
|
||||
/* Cases for lowercase hex letters, and lowercase letters, all offset by N. */
|
||||
|
||||
#define _C_CTYPE_LOWER_A_THRU_F_N(N) \
|
||||
case 'a' + (N): case 'b' + (N): case 'c' + (N): case 'd' + (N): \
|
||||
case 'e' + (N): case 'f' + (N)
|
||||
#define _C_CTYPE_LOWER_N(N) \
|
||||
_C_CTYPE_LOWER_A_THRU_F_N(N): \
|
||||
case 'g' + (N): case 'h' + (N): case 'i' + (N): case 'j' + (N): \
|
||||
case 'k' + (N): case 'l' + (N): case 'm' + (N): case 'n' + (N): \
|
||||
case 'o' + (N): case 'p' + (N): case 'q' + (N): case 'r' + (N): \
|
||||
case 's' + (N): case 't' + (N): case 'u' + (N): case 'v' + (N): \
|
||||
case 'w' + (N): case 'x' + (N): case 'y' + (N): case 'z' + (N)
|
||||
|
||||
/* Cases for hex letters, digits, lower, punct, and upper. */
|
||||
|
||||
#define _C_CTYPE_A_THRU_F \
|
||||
_C_CTYPE_LOWER_A_THRU_F_N (0): \
|
||||
_C_CTYPE_LOWER_A_THRU_F_N ('A' - 'a')
|
||||
#define _C_CTYPE_DIGIT \
|
||||
case '0': case '1': case '2': case '3': \
|
||||
case '4': case '5': case '6': case '7': \
|
||||
case '8': case '9'
|
||||
#define _C_CTYPE_LOWER _C_CTYPE_LOWER_N (0)
|
||||
#define _C_CTYPE_PUNCT \
|
||||
case '!': case '"': case '#': case '$': \
|
||||
case '%': case '&': case '\'': case '(': \
|
||||
case ')': case '*': case '+': case ',': \
|
||||
case '-': case '.': case '/': case ':': \
|
||||
case ';': case '<': case '=': case '>': \
|
||||
case '?': case '@': case '[': case '\\': \
|
||||
case ']': case '^': case '_': case '`': \
|
||||
case '{': case '|': case '}': case '~'
|
||||
#define _C_CTYPE_UPPER _C_CTYPE_LOWER_N ('A' - 'a')
|
||||
|
||||
|
||||
/* Function definitions. */
|
||||
|
||||
/* Unlike the functions in <ctype.h>, which require an argument in the range
|
||||
of the 'unsigned char' type, the functions here operate on values that are
|
||||
|
@ -117,179 +165,202 @@ extern "C" {
|
|||
if (c_isalpha (*s)) ...
|
||||
*/
|
||||
|
||||
extern bool c_isascii (int c) _GL_ATTRIBUTE_CONST; /* not locale dependent */
|
||||
C_CTYPE_INLINE bool
|
||||
c_isalnum (int c)
|
||||
{
|
||||
switch (c)
|
||||
{
|
||||
_C_CTYPE_DIGIT:
|
||||
_C_CTYPE_LOWER:
|
||||
_C_CTYPE_UPPER:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
extern bool c_isalnum (int c) _GL_ATTRIBUTE_CONST;
|
||||
extern bool c_isalpha (int c) _GL_ATTRIBUTE_CONST;
|
||||
extern bool c_isblank (int c) _GL_ATTRIBUTE_CONST;
|
||||
extern bool c_iscntrl (int c) _GL_ATTRIBUTE_CONST;
|
||||
extern bool c_isdigit (int c) _GL_ATTRIBUTE_CONST;
|
||||
extern bool c_islower (int c) _GL_ATTRIBUTE_CONST;
|
||||
extern bool c_isgraph (int c) _GL_ATTRIBUTE_CONST;
|
||||
extern bool c_isprint (int c) _GL_ATTRIBUTE_CONST;
|
||||
extern bool c_ispunct (int c) _GL_ATTRIBUTE_CONST;
|
||||
extern bool c_isspace (int c) _GL_ATTRIBUTE_CONST;
|
||||
extern bool c_isupper (int c) _GL_ATTRIBUTE_CONST;
|
||||
extern bool c_isxdigit (int c) _GL_ATTRIBUTE_CONST;
|
||||
C_CTYPE_INLINE bool
|
||||
c_isalpha (int c)
|
||||
{
|
||||
switch (c)
|
||||
{
|
||||
_C_CTYPE_LOWER:
|
||||
_C_CTYPE_UPPER:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
extern int c_tolower (int c) _GL_ATTRIBUTE_CONST;
|
||||
extern int c_toupper (int c) _GL_ATTRIBUTE_CONST;
|
||||
/* The function isascii is not locale dependent.
|
||||
Its use in EBCDIC is questionable. */
|
||||
C_CTYPE_INLINE bool
|
||||
c_isascii (int c)
|
||||
{
|
||||
switch (c)
|
||||
{
|
||||
case ' ':
|
||||
_C_CTYPE_CNTRL:
|
||||
_C_CTYPE_DIGIT:
|
||||
_C_CTYPE_LOWER:
|
||||
_C_CTYPE_PUNCT:
|
||||
_C_CTYPE_UPPER:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
C_CTYPE_INLINE bool
|
||||
c_isblank (int c)
|
||||
{
|
||||
return c == ' ' || c == '\t';
|
||||
}
|
||||
|
||||
#if (defined __GNUC__ && !defined __STRICT_ANSI__ && defined __OPTIMIZE__ \
|
||||
&& !defined __OPTIMIZE_SIZE__ && !defined NO_C_CTYPE_MACROS)
|
||||
C_CTYPE_INLINE bool
|
||||
c_iscntrl (int c)
|
||||
{
|
||||
switch (c)
|
||||
{
|
||||
_C_CTYPE_CNTRL:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/* ASCII optimizations. */
|
||||
C_CTYPE_INLINE bool
|
||||
c_isdigit (int c)
|
||||
{
|
||||
switch (c)
|
||||
{
|
||||
_C_CTYPE_DIGIT:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
#undef c_isascii
|
||||
#define c_isascii(c) \
|
||||
({ int __c = (c); \
|
||||
(__c >= 0x00 && __c <= 0x7f); \
|
||||
})
|
||||
C_CTYPE_INLINE bool
|
||||
c_isgraph (int c)
|
||||
{
|
||||
switch (c)
|
||||
{
|
||||
_C_CTYPE_DIGIT:
|
||||
_C_CTYPE_LOWER:
|
||||
_C_CTYPE_PUNCT:
|
||||
_C_CTYPE_UPPER:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
#if C_CTYPE_CONSECUTIVE_DIGITS \
|
||||
&& C_CTYPE_CONSECUTIVE_UPPERCASE && C_CTYPE_CONSECUTIVE_LOWERCASE
|
||||
#if C_CTYPE_ASCII
|
||||
#undef c_isalnum
|
||||
#define c_isalnum(c) \
|
||||
({ int __c = (c); \
|
||||
((__c >= '0' && __c <= '9') \
|
||||
|| ((__c & ~0x20) >= 'A' && (__c & ~0x20) <= 'Z')); \
|
||||
})
|
||||
#else
|
||||
#undef c_isalnum
|
||||
#define c_isalnum(c) \
|
||||
({ int __c = (c); \
|
||||
((__c >= '0' && __c <= '9') \
|
||||
|| (__c >= 'A' && __c <= 'Z') \
|
||||
|| (__c >= 'a' && __c <= 'z')); \
|
||||
})
|
||||
#endif
|
||||
#endif
|
||||
C_CTYPE_INLINE bool
|
||||
c_islower (int c)
|
||||
{
|
||||
switch (c)
|
||||
{
|
||||
_C_CTYPE_LOWER:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
#if C_CTYPE_CONSECUTIVE_UPPERCASE && C_CTYPE_CONSECUTIVE_LOWERCASE
|
||||
#if C_CTYPE_ASCII
|
||||
#undef c_isalpha
|
||||
#define c_isalpha(c) \
|
||||
({ int __c = (c); \
|
||||
((__c & ~0x20) >= 'A' && (__c & ~0x20) <= 'Z'); \
|
||||
})
|
||||
#else
|
||||
#undef c_isalpha
|
||||
#define c_isalpha(c) \
|
||||
({ int __c = (c); \
|
||||
((__c >= 'A' && __c <= 'Z') || (__c >= 'a' && __c <= 'z')); \
|
||||
})
|
||||
#endif
|
||||
#endif
|
||||
C_CTYPE_INLINE bool
|
||||
c_isprint (int c)
|
||||
{
|
||||
switch (c)
|
||||
{
|
||||
case ' ':
|
||||
_C_CTYPE_DIGIT:
|
||||
_C_CTYPE_LOWER:
|
||||
_C_CTYPE_PUNCT:
|
||||
_C_CTYPE_UPPER:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
#undef c_isblank
|
||||
#define c_isblank(c) \
|
||||
({ int __c = (c); \
|
||||
(__c == ' ' || __c == '\t'); \
|
||||
})
|
||||
C_CTYPE_INLINE bool
|
||||
c_ispunct (int c)
|
||||
{
|
||||
switch (c)
|
||||
{
|
||||
_C_CTYPE_PUNCT:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
#if C_CTYPE_ASCII
|
||||
#undef c_iscntrl
|
||||
#define c_iscntrl(c) \
|
||||
({ int __c = (c); \
|
||||
((__c & ~0x1f) == 0 || __c == 0x7f); \
|
||||
})
|
||||
#endif
|
||||
C_CTYPE_INLINE bool
|
||||
c_isspace (int c)
|
||||
{
|
||||
switch (c)
|
||||
{
|
||||
case ' ': case '\t': case '\n': case '\v': case '\f': case '\r':
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
#if C_CTYPE_CONSECUTIVE_DIGITS
|
||||
#undef c_isdigit
|
||||
#define c_isdigit(c) \
|
||||
({ int __c = (c); \
|
||||
(__c >= '0' && __c <= '9'); \
|
||||
})
|
||||
#endif
|
||||
C_CTYPE_INLINE bool
|
||||
c_isupper (int c)
|
||||
{
|
||||
switch (c)
|
||||
{
|
||||
_C_CTYPE_UPPER:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
#if C_CTYPE_CONSECUTIVE_LOWERCASE
|
||||
#undef c_islower
|
||||
#define c_islower(c) \
|
||||
({ int __c = (c); \
|
||||
(__c >= 'a' && __c <= 'z'); \
|
||||
})
|
||||
#endif
|
||||
C_CTYPE_INLINE bool
|
||||
c_isxdigit (int c)
|
||||
{
|
||||
switch (c)
|
||||
{
|
||||
_C_CTYPE_DIGIT:
|
||||
_C_CTYPE_A_THRU_F:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
#if C_CTYPE_ASCII
|
||||
#undef c_isgraph
|
||||
#define c_isgraph(c) \
|
||||
({ int __c = (c); \
|
||||
(__c >= '!' && __c <= '~'); \
|
||||
})
|
||||
#endif
|
||||
|
||||
#if C_CTYPE_ASCII
|
||||
#undef c_isprint
|
||||
#define c_isprint(c) \
|
||||
({ int __c = (c); \
|
||||
(__c >= ' ' && __c <= '~'); \
|
||||
})
|
||||
#endif
|
||||
|
||||
#if C_CTYPE_ASCII
|
||||
#undef c_ispunct
|
||||
#define c_ispunct(c) \
|
||||
({ int _c = (c); \
|
||||
(c_isgraph (_c) && ! c_isalnum (_c)); \
|
||||
})
|
||||
#endif
|
||||
|
||||
#undef c_isspace
|
||||
#define c_isspace(c) \
|
||||
({ int __c = (c); \
|
||||
(__c == ' ' || __c == '\t' \
|
||||
|| __c == '\n' || __c == '\v' || __c == '\f' || __c == '\r'); \
|
||||
})
|
||||
|
||||
#if C_CTYPE_CONSECUTIVE_UPPERCASE
|
||||
#undef c_isupper
|
||||
#define c_isupper(c) \
|
||||
({ int __c = (c); \
|
||||
(__c >= 'A' && __c <= 'Z'); \
|
||||
})
|
||||
#endif
|
||||
|
||||
#if C_CTYPE_CONSECUTIVE_DIGITS \
|
||||
&& C_CTYPE_CONSECUTIVE_UPPERCASE && C_CTYPE_CONSECUTIVE_LOWERCASE
|
||||
#if C_CTYPE_ASCII
|
||||
#undef c_isxdigit
|
||||
#define c_isxdigit(c) \
|
||||
({ int __c = (c); \
|
||||
((__c >= '0' && __c <= '9') \
|
||||
|| ((__c & ~0x20) >= 'A' && (__c & ~0x20) <= 'F')); \
|
||||
})
|
||||
#else
|
||||
#undef c_isxdigit
|
||||
#define c_isxdigit(c) \
|
||||
({ int __c = (c); \
|
||||
((__c >= '0' && __c <= '9') \
|
||||
|| (__c >= 'A' && __c <= 'F') \
|
||||
|| (__c >= 'a' && __c <= 'f')); \
|
||||
})
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if C_CTYPE_CONSECUTIVE_UPPERCASE && C_CTYPE_CONSECUTIVE_LOWERCASE
|
||||
#undef c_tolower
|
||||
#define c_tolower(c) \
|
||||
({ int __c = (c); \
|
||||
(__c >= 'A' && __c <= 'Z' ? __c - 'A' + 'a' : __c); \
|
||||
})
|
||||
#undef c_toupper
|
||||
#define c_toupper(c) \
|
||||
({ int __c = (c); \
|
||||
(__c >= 'a' && __c <= 'z' ? __c - 'a' + 'A' : __c); \
|
||||
})
|
||||
#endif
|
||||
|
||||
#endif /* optimizing for speed */
|
||||
C_CTYPE_INLINE int
|
||||
c_tolower (int c)
|
||||
{
|
||||
switch (c)
|
||||
{
|
||||
_C_CTYPE_UPPER:
|
||||
return c - 'A' + 'a';
|
||||
default:
|
||||
return c;
|
||||
}
|
||||
}
|
||||
|
||||
C_CTYPE_INLINE int
|
||||
c_toupper (int c)
|
||||
{
|
||||
switch (c)
|
||||
{
|
||||
_C_CTYPE_LOWER:
|
||||
return c - 'a' + 'A';
|
||||
default:
|
||||
return c;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
_GL_INLINE_HEADER_END
|
||||
|
||||
#endif /* C_CTYPE_H */
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* Case-insensitive string comparison functions in C locale.
|
||||
Copyright (C) 1995-1996, 2001, 2003, 2005, 2009-2014 Free Software
|
||||
Copyright (C) 1995-1996, 2001, 2003, 2005, 2009-2017 Free Software
|
||||
Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
|
|
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