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
|
*.x
|
||||||
*.lo
|
*.lo
|
||||||
*.la
|
*.la
|
||||||
|
*.exe
|
||||||
aclocal.m4
|
aclocal.m4
|
||||||
libtool
|
libtool
|
||||||
ltmain.sh
|
ltmain.sh
|
||||||
|
@ -142,6 +143,7 @@ INSTALL
|
||||||
/test-suite/standalone/test-scm-spawn-thread
|
/test-suite/standalone/test-scm-spawn-thread
|
||||||
/test-suite/standalone/test-pthread-create
|
/test-suite/standalone/test-pthread-create
|
||||||
/test-suite/standalone/test-pthread-create-secondary
|
/test-suite/standalone/test-pthread-create-secondary
|
||||||
|
/test-suite/standalone/test-smob-mark-race
|
||||||
/lib/fcntl.h
|
/lib/fcntl.h
|
||||||
/lib/sys/uio.h
|
/lib/sys/uio.h
|
||||||
/lib/stdalign.h
|
/lib/stdalign.h
|
||||||
|
@ -163,3 +165,6 @@ INSTALL
|
||||||
/libguile/vm-operations.h
|
/libguile/vm-operations.h
|
||||||
/test-suite/standalone/test-foreign-object-c
|
/test-suite/standalone/test-foreign-object-c
|
||||||
/test-suite/standalone/test-srfi-4
|
/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
|
# It is necessary if you want to build targets usually of interest
|
||||||
# only to the maintainer.
|
# 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
|
# This program is free software: you can redistribute it and/or modify
|
||||||
# it under the terms of the GNU General Public License as published by
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
|
|
@ -2,8 +2,8 @@
|
||||||
|
|
||||||
# Note: `GUILE_VERSION' is defined in `configure.ac' using `git-version-gen'.
|
# Note: `GUILE_VERSION' is defined in `configure.ac' using `git-version-gen'.
|
||||||
GUILE_MAJOR_VERSION=2
|
GUILE_MAJOR_VERSION=2
|
||||||
GUILE_MINOR_VERSION=1
|
GUILE_MINOR_VERSION=2
|
||||||
GUILE_MICRO_VERSION=0
|
GUILE_MICRO_VERSION=2
|
||||||
|
|
||||||
GUILE_EFFECTIVE_VERSION=2.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
|
# See libtool info pages for more information on how and when to
|
||||||
# change these.
|
# change these.
|
||||||
|
|
||||||
LIBGUILE_INTERFACE_CURRENT=0
|
LIBGUILE_INTERFACE_CURRENT=3
|
||||||
LIBGUILE_INTERFACE_REVISION=0
|
LIBGUILE_INTERFACE_REVISION=0
|
||||||
LIBGUILE_INTERFACE_AGE=0
|
LIBGUILE_INTERFACE_AGE=2
|
||||||
LIBGUILE_INTERFACE="${LIBGUILE_INTERFACE_CURRENT}:${LIBGUILE_INTERFACE_REVISION}:${LIBGUILE_INTERFACE_AGE}"
|
LIBGUILE_INTERFACE="${LIBGUILE_INTERFACE_CURRENT}:${LIBGUILE_INTERFACE_REVISION}:${LIBGUILE_INTERFACE_AGE}"
|
||||||
|
|
121
HACKING
121
HACKING
|
@ -1,6 +1,6 @@
|
||||||
-*-text-*-
|
-*-text-*-
|
||||||
Guile Hacking Guide
|
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
|
Permission is granted to anyone to make or distribute verbatim copies
|
||||||
of this document as received, in any medium, provided that the
|
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.
|
You can hack whatever you want, thank GNU.
|
||||||
|
|
||||||
However, to see what others have indicated as their interest (and avoid
|
It's a good idea to join the guile-devel@gnu.org mailing list. See
|
||||||
potential wasteful duplication of effort), see file TODO. Note that
|
http://www.gnu.org/software/guile/mail/mail.html for more info.
|
||||||
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.
|
|
||||||
|
|
||||||
|
|
||||||
Hacking It Yourself ==================================================
|
Hacking It Yourself ==================================================
|
||||||
|
@ -69,7 +64,7 @@ gettext --- a system for rigging a program so that it can output its
|
||||||
itself.
|
itself.
|
||||||
|
|
||||||
flex --- a scanner generator. It's probably not essential to have the
|
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
|
One false move and you will be lost in a little maze of automatically
|
||||||
generated files, all different.
|
generated files, all different.
|
||||||
|
@ -77,67 +72,11 @@ generated files, all different.
|
||||||
Here is the authoritative list of tool/version/platform tuples that
|
Here is the authoritative list of tool/version/platform tuples that
|
||||||
have been known to cause problems, and a short description of the problem.
|
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=========================================
|
Sample GDB Initialization File=========================================
|
||||||
|
|
||||||
Here is a sample .gdbinit posted by Bill Schottstaedt (modified to
|
In GDB, you probably want to load the gdbinit file included with Guile,
|
||||||
use `set' instead of `call' in some places):
|
which defines a number of GDB helpers to inspect Scheme values.
|
||||||
|
|
||||||
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\""
|
|
||||||
|
|
||||||
|
|
||||||
Contributing Your Changes ============================================
|
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.
|
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
|
Note that the warnings generated vary from one version of GCC to the
|
||||||
next, and from one architecture to the next (apparently). To provide
|
next, and from one architecture to the next. For this reason,
|
||||||
a concrete common standard, Guile should compile without warnings from
|
--enable-error-on-warning is not enabled by default.
|
||||||
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. :)
|
|
||||||
|
|
||||||
- If you add code which uses functions or other features that are not
|
- If you add code which uses functions or other features that are not
|
||||||
entirely portable, please make sure the rest of Guile will still
|
entirely portable, please make sure the rest of Guile will still
|
||||||
function properly on systems where they are missing. This usually
|
function properly on systems where they are missing. This usually
|
||||||
entails adding a test to configure.in, and then adding #ifdefs to your
|
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
|
- 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
|
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
|
4. Add an entry that the definition has been deprecated in NEWS and
|
||||||
explain what to do instead.
|
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
|
- Write commit messages for functions written in C using the
|
||||||
functions' C names, and write entries for functions written in Scheme
|
functions' C names, and write entries for functions written in Scheme
|
||||||
using the functions' Scheme names. For example,
|
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
|
has signed copyright papers, and that the Free Software Foundation has
|
||||||
received them.
|
received them.
|
||||||
|
|
||||||
If you receive contributions you want to use from someone, let me know
|
If you receive contributions you want to use from someone, let a
|
||||||
and I'll take care of the administrivia. Put the contributions aside
|
maintainer know and they will take care of the administrivia. Put the
|
||||||
until we have the necessary papers.
|
contributions aside until we have the necessary papers.
|
||||||
|
|
||||||
Once you accept a contribution, be sure to keep the files AUTHORS and
|
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
|
- 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.
|
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
|
str - this denotes a zero terminated C string
|
||||||
|
|
||||||
mem - a C string with an explicit count
|
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,
|
## Copyright (C) 1998, 1999, 2000, 2001, 2002, 2006, 2007,
|
||||||
## 2008, 2009, 2010, 2011, 2012, 2013,
|
## 2008, 2009, 2010, 2011, 2012, 2013,
|
||||||
## 2014 Free Software Foundation, Inc.
|
## 2014, 2015, 2016 Free Software Foundation, Inc.
|
||||||
##
|
##
|
||||||
## This file is part of GUILE.
|
## This file is part of GUILE.
|
||||||
##
|
##
|
||||||
|
@ -30,6 +30,7 @@ SUBDIRS = \
|
||||||
lib \
|
lib \
|
||||||
meta \
|
meta \
|
||||||
libguile \
|
libguile \
|
||||||
|
bootstrap \
|
||||||
module \
|
module \
|
||||||
guile-readline \
|
guile-readline \
|
||||||
examples \
|
examples \
|
||||||
|
@ -40,6 +41,8 @@ SUBDIRS = \
|
||||||
am \
|
am \
|
||||||
doc
|
doc
|
||||||
|
|
||||||
|
DIST_SUBDIRS = $(SUBDIRS) prebuilt
|
||||||
|
|
||||||
libguileincludedir = $(pkgincludedir)/$(GUILE_EFFECTIVE_VERSION)
|
libguileincludedir = $(pkgincludedir)/$(GUILE_EFFECTIVE_VERSION)
|
||||||
libguileinclude_HEADERS = libguile.h
|
libguileinclude_HEADERS = libguile.h
|
||||||
|
|
||||||
|
@ -88,7 +91,7 @@ DISTCLEANFILES = check-guile.log
|
||||||
|
|
||||||
DISTCHECK_CONFIGURE_FLAGS = --enable-error-on-warning
|
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:
|
clean-local:
|
||||||
rm -rf cache/
|
rm -rf cache/
|
||||||
|
@ -105,6 +108,16 @@ gen-ChangeLog:
|
||||||
mv $(distdir)/cl-t $(distdir)/ChangeLog; \
|
mv $(distdir)/cl-t $(distdir)/ChangeLog; \
|
||||||
fi
|
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
|
BUILT_SOURCES += $(top_srcdir)/.version
|
||||||
$(top_srcdir)/.version:
|
$(top_srcdir)/.version:
|
||||||
echo $(VERSION) > $@-t && mv $@-t $@
|
echo $(VERSION) > $@-t && mv $@-t $@
|
||||||
|
|
877
NEWS
877
NEWS
|
@ -1,12 +1,149 @@
|
||||||
Guile NEWS --- history of user-visible changes.
|
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.
|
See the end for copying conditions.
|
||||||
|
|
||||||
Please send Guile bug reports to bug-guile@gnu.org.
|
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
|
* 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
|
This new release series takes the ABI-break opportunity to fix some
|
||||||
interfaces that were difficult to use correctly from multiple threads.
|
interfaces that were difficult to use correctly from multiple threads.
|
||||||
Notably, weak hash tables are now transparently thread-safe. Ports are
|
Notably, weak hash tables and ports are now transparently thread-safe.
|
||||||
also thread-safe; see "New interfaces" below for details on the changes
|
See "Scheduling" in the manual, for updated documentation on threads and
|
||||||
to the C interface.
|
communications primitives.
|
||||||
|
|
||||||
** Better space-safety
|
** 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 via a call to `(setlocale LC_ALL "")'. For users with a unicode
|
||||||
locale, this makes all ports unicode-capable by default, without the
|
locale, this makes all ports unicode-capable by default, without the
|
||||||
need to call `setlocale' in your program. This behavior may be
|
need to call `setlocale' in your program. This behavior may be
|
||||||
controlled via the GUILE_INSTALL_LOCALE environment variable; see the
|
controlled via the GUILE_INSTALL_LOCALE environment variable; see
|
||||||
manual for more.
|
"Environment Variables" in the manual, for more.
|
||||||
|
|
||||||
** Complete Emacs-compatible Elisp implementation
|
** Complete Emacs-compatible Elisp implementation
|
||||||
|
|
||||||
Thanks to the work of BT Templeton, Guile's Elisp implementation is now
|
Thanks to the work of Robin Templeton, Guile's Elisp implementation is
|
||||||
fully Emacs-compatible, implementing all of Elisp's features and quirks
|
now fully Emacs-compatible, implementing all of Elisp's features and
|
||||||
in the same way as the editor we know and love.
|
quirks in the same way as the editor we know and love.
|
||||||
|
|
||||||
** Dynamically expandable stacks
|
** 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,
|
while also makes it possible to implement new features in the future,
|
||||||
such as method combinations or `eqv?' specializers.
|
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
|
* Performance improvements
|
||||||
|
|
||||||
** Faster programs via new virtual machine
|
** 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
|
intermediate language, allowing it to reason easily about temporary
|
||||||
values and control flow. Examples of optimizations that this permits
|
values and control flow. Examples of optimizations that this permits
|
||||||
are optimal contification, optimal common subexpression elimination,
|
are optimal contification, optimal common subexpression elimination,
|
||||||
dead code elimination, parallel moves with at most one temporary,
|
dead code elimination, loop-invariant code motion, loop peeling, loop
|
||||||
allocation of stack slots using precise liveness information, and
|
inversion, parallel moves with at most one temporary, allocation of
|
||||||
closure optimization. For more, see "Continuation-Passing Style" in the
|
stack slots using precise liveness information, unboxing of 64-bit
|
||||||
manual.
|
integers and floating point values, and closure optimization. For more,
|
||||||
|
see "Continuation-Passing Style" in the manual.
|
||||||
|
|
||||||
** Faster interpreter
|
** 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
|
faster now, as it is internally better able to dispatch on the type of
|
||||||
the underlying backing store.
|
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 interfaces
|
||||||
|
|
||||||
** New `cond-expand' feature: `guile-2.2'
|
** 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.
|
of the compiler and the low-level loader and introspection interfaces.
|
||||||
See the "Guile Implementation" chapter in the manual for all details.
|
See the "Guile Implementation" chapter in the manual for all details.
|
||||||
|
|
||||||
** New functions: `scm_to_intptr_t', `scm_from_intptr_t'
|
** Add "tree" display mode for statprof.
|
||||||
** New functions: `scm_to_uintptr_t', `scm_from_uintptr_t'
|
|
||||||
|
|
||||||
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',
|
See "Non-Blocking I/O" in the manual, for more.
|
||||||
`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.
|
|
||||||
|
|
||||||
There is now a routine to atomically adjust port "revealed counts". See
|
** Implement R6RS custom binary input/output ports
|
||||||
XXX for more on `scm_adjust_port_revealed_x' and
|
|
||||||
`adjust-port-revealed!',
|
|
||||||
|
|
||||||
All other port API now takes the lock on the port if needed. There are
|
See "Custom Ports" in the manual.
|
||||||
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',
|
** Implement R6RS output-buffer-mode
|
||||||
`scm_peek_byte_or_eof_unlocked' `scm_c_read_unlocked',
|
** Implement R6RS bytevector->string, string->bytevector
|
||||||
`scm_getc_unlocked' `scm_unget_byte_unlocked', `scm_ungetc_unlocked',
|
|
||||||
`scm_ungets_unlocked', `scm_fill_input_unlocked' `scm_putc_unlocked',
|
See "R6RS Transcoders" in the manual.
|
||||||
`scm_puts_unlocked', and `scm_lfwrite_unlocked'.
|
|
||||||
|
** `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'
|
** 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
|
the old `SCM2PTR' and `PTR2SCM'. Also, `SCM_UNPACK_POINTER' yields a
|
||||||
void*.
|
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
|
** <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.
|
** Convenience utilities for ports and strings.
|
||||||
|
|
||||||
See XXX for more on `scm_from_port_string', `scm_from_port_stringn',
|
See "Conversion to/from C" for more on `scm_from_port_string',
|
||||||
`scm_to_port_string', and `scm_to_port_stringn'.
|
`scm_from_port_stringn', `scm_to_port_string', and
|
||||||
|
`scm_to_port_stringn'.
|
||||||
|
|
||||||
** New expressive PEG parser
|
** 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
|
locale is set to ASCII, and the user or a program writes non-ASCII
|
||||||
codepoints to a port.
|
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
|
** String ports default to UTF-8
|
||||||
|
|
||||||
Guile 2.0 would use the `%default-port-encoding' when creating string
|
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
|
textual and binary, and thus both kinds have port transcoders. This is
|
||||||
an incompatibility with respect to R6RS.
|
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
|
** Vtable hierarchy changes
|
||||||
|
|
||||||
In an attempt to make Guile's structure and record types integrate
|
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
|
values, renamed by imports or exports, et cetera. See "Syntax-rules
|
||||||
Macros" in the manual for more on literals.
|
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
|
** `dynamic-wind' doesn't check that guards are thunks
|
||||||
|
|
||||||
Checking that the dynamic-wind out-guard procedure was actually a thunk
|
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
|
* 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_WTA_DISPATCH_0, SCM_WTA_DISPATCH_1, SCM_WTA_DISPATCH_2, SCM_WTA_DISPATCH_N
|
||||||
** SCM_GASSERT0, SCM_GASSERT1, SCM_GASSERT2, SCM_GASSERTn
|
** SCM_GASSERT0, SCM_GASSERT1, SCM_GASSERT2, SCM_GASSERTn
|
||||||
** SCM_WTA_DISPATCH_1_SUBR
|
** SCM_WTA_DISPATCH_1_SUBR
|
||||||
|
@ -524,6 +1038,19 @@ Instead use the normal `scm_slot_ref' and similar procedures.
|
||||||
|
|
||||||
* Changes to the distribution
|
* 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
|
** New minor version
|
||||||
|
|
||||||
The "effective version" of Guile is now 2.2, which allows parallel
|
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.
|
** 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 readline extension is now installed in the extensionsdir
|
||||||
|
|
||||||
The shared library that implements Guile's readline extension is no
|
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.
|
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):
|
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
|
Guile is an implementation of the Scheme programming language, packaged
|
||||||
as a library that can be linked into applications to give them their own
|
as a library that can be linked into applications to give them their own
|
||||||
extension language. Guile supports other languages as well, giving
|
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
|
`utf*->string' procedures. It is available from
|
||||||
http://www.gnu.org/software/libunistring/ .
|
http://www.gnu.org/software/libunistring/ .
|
||||||
|
|
||||||
- libgc, at least version 7.0
|
- libgc, at least version 7.2
|
||||||
|
|
||||||
libgc (aka. the Boehm-Demers-Weiser garbage collector) is the
|
libgc (aka. the Boehm-Demers-Weiser garbage collector) is the
|
||||||
conservative garbage collector used by Guile. It is available
|
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
|
treatment. If you can send us fixes for these problems, we'd be
|
||||||
grateful.
|
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 =================================
|
Guile specific flags Accepted by Configure =================================
|
||||||
|
|
||||||
|
@ -244,7 +257,7 @@ switches specific to Guile you may find useful in some circumstances.
|
||||||
|
|
||||||
Cross building Guile =====================================================
|
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
|
along with Guile "object files" containing bytecode to be interpreted by
|
||||||
Guile's virtual machine. The bytecode format depends on the endianness
|
Guile's virtual machine. The bytecode format depends on the endianness
|
||||||
and word size of the host CPU.
|
and word size of the host CPU.
|
||||||
|
@ -401,8 +414,6 @@ Documentation in Info format, in ${prefix}/info:
|
||||||
|
|
||||||
guile --- Guile reference manual.
|
guile --- Guile reference manual.
|
||||||
|
|
||||||
guile-tut --- Guile tutorial.
|
|
||||||
|
|
||||||
GOOPS --- GOOPS reference manual.
|
GOOPS --- GOOPS reference manual.
|
||||||
|
|
||||||
r5rs --- Revised(5) Report on the Algorithmic Language Scheme.
|
r5rs --- Revised(5) Report on the Algorithmic Language Scheme.
|
||||||
|
@ -413,9 +424,7 @@ The Guile source tree is laid out as follows:
|
||||||
libguile:
|
libguile:
|
||||||
The Guile Scheme interpreter --- both the object library
|
The Guile Scheme interpreter --- both the object library
|
||||||
for you to link with your programs, and the executable you can run.
|
for you to link with your programs, and the executable you can run.
|
||||||
ice-9: Guile's module system, initialization code, and other infrastructure.
|
module: Scheme libraries included with Guile.
|
||||||
guile-config:
|
|
||||||
Source for the guile-config script.
|
|
||||||
guile-readline:
|
guile-readline:
|
||||||
The glue code for using GNU readline with Guile. This
|
The glue code for using GNU readline with Guile. This
|
||||||
will be build when configure can find a recent enough readline
|
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
|
Dan McMahill
|
||||||
Roger Mc Murtrie
|
Roger Mc Murtrie
|
||||||
Scott McPeak
|
Scott McPeak
|
||||||
|
David Michael
|
||||||
Glenn Michaels
|
Glenn Michaels
|
||||||
Andrew Milkowski
|
Andrew Milkowski
|
||||||
Tim Mooney
|
Tim Mooney
|
||||||
|
@ -170,6 +171,7 @@ For fixes or providing information which led to a fix:
|
||||||
Dale Smith
|
Dale Smith
|
||||||
Cesar Strauss
|
Cesar Strauss
|
||||||
Klaus Stehle
|
Klaus Stehle
|
||||||
|
Kouhei Sutou
|
||||||
Rainer Tammer
|
Rainer Tammer
|
||||||
Frank Terbeck
|
Frank Terbeck
|
||||||
Samuel Thibault
|
Samuel Thibault
|
||||||
|
@ -199,6 +201,7 @@ For fixes or providing information which led to a fix:
|
||||||
Jon Wilson
|
Jon Wilson
|
||||||
Andy Wingo
|
Andy Wingo
|
||||||
Keith Wright
|
Keith Wright
|
||||||
|
Ricardo Wurmus
|
||||||
William Xu
|
William Xu
|
||||||
Atom X Zane
|
Atom X Zane
|
||||||
|
|
||||||
|
|
|
@ -557,6 +557,8 @@ AC_DEFUN([GUILE_CHECK_GUILE_FOR_BUILD], [
|
||||||
if test "$GUILE_FOR_BUILD" = "not-found"; then
|
if test "$GUILE_FOR_BUILD" = "not-found"; then
|
||||||
AC_MSG_ERROR([a native Guile $PACKAGE_VERSION is required to cross-build Guile])
|
AC_MSG_ERROR([a native Guile $PACKAGE_VERSION is required to cross-build Guile])
|
||||||
fi
|
fi
|
||||||
|
else
|
||||||
|
GUILE_FOR_BUILD=$(which "$GUILE_FOR_BUILD" || echo "$GUILE_FOR_BUILD")
|
||||||
fi
|
fi
|
||||||
AC_MSG_CHECKING([guile for build])
|
AC_MSG_CHECKING([guile for build])
|
||||||
AC_MSG_RESULT([$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 -*-
|
# -*- makefile -*-
|
||||||
GOBJECTS = $(SOURCES:%.scm=%.go) $(ELISP_SOURCES:%.el=%.go)
|
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)
|
moddir = $(pkgdatadir)/$(GUILE_EFFECTIVE_VERSION)/$(modpath)
|
||||||
nobase_mod_DATA = $(SOURCES) $(ELISP_SOURCES) $(NOCOMP_SOURCES)
|
nobase_mod_DATA = $(SOURCES) $(ELISP_SOURCES) $(NOCOMP_SOURCES)
|
||||||
|
@ -28,7 +28,7 @@ SUFFIXES = .scm .el .go
|
||||||
|
|
||||||
.scm.go:
|
.scm.go:
|
||||||
$(AM_V_GUILEC)GUILE_AUTO_COMPILE=0 \
|
$(AM_V_GUILEC)GUILE_AUTO_COMPILE=0 \
|
||||||
$(top_builddir)/meta/uninstalled-env \
|
$(top_builddir)/meta/build-env \
|
||||||
guild compile --target="$(host)" $(GUILE_WARNINGS) \
|
guild compile --target="$(host)" $(GUILE_WARNINGS) \
|
||||||
-L "$(abs_srcdir)" -L "$(abs_builddir)" \
|
-L "$(abs_srcdir)" -L "$(abs_builddir)" \
|
||||||
-L "$(abs_top_srcdir)/guile-readline" \
|
-L "$(abs_top_srcdir)/guile-readline" \
|
||||||
|
@ -36,7 +36,7 @@ SUFFIXES = .scm .el .go
|
||||||
|
|
||||||
.el.go:
|
.el.go:
|
||||||
$(AM_V_GUILEC)GUILE_AUTO_COMPILE=0 \
|
$(AM_V_GUILEC)GUILE_AUTO_COMPILE=0 \
|
||||||
$(top_builddir)/meta/uninstalled-env \
|
$(top_builddir)/meta/build-env \
|
||||||
guild compile --target="$(host)" $(GUILE_WARNINGS) \
|
guild compile --target="$(host)" $(GUILE_WARNINGS) \
|
||||||
-L "$(abs_srcdir)" -L "$(abs_builddir)" \
|
-L "$(abs_srcdir)" -L "$(abs_builddir)" \
|
||||||
-L "$(abs_top_srcdir)/guile-readline" \
|
-L "$(abs_top_srcdir)/guile-readline" \
|
||||||
|
|
|
@ -51,20 +51,20 @@
|
||||||
|
|
||||||
(with-benchmark-prefix "read"
|
(with-benchmark-prefix "read"
|
||||||
|
|
||||||
(benchmark "_IONBF" 5 ;; this one is very slow
|
(benchmark "'none" 5 ;; this one is very slow
|
||||||
(exercise-read (list _IONBF)))
|
(exercise-read (list 'none)))
|
||||||
|
|
||||||
(benchmark "_IOLBF" 10
|
(benchmark "'line" 10
|
||||||
(exercise-read (list _IOLBF)))
|
(exercise-read (list 'line)))
|
||||||
|
|
||||||
(benchmark "_IOFBF 4096" 10
|
(benchmark "'block 4096" 10
|
||||||
(exercise-read (list _IOFBF 4096)))
|
(exercise-read (list 'block 4096)))
|
||||||
|
|
||||||
(benchmark "_IOFBF 8192" 10
|
(benchmark "'block 8192" 10
|
||||||
(exercise-read (list _IOFBF 8192)))
|
(exercise-read (list 'block 8192)))
|
||||||
|
|
||||||
(benchmark "_IOFBF 16384" 10
|
(benchmark "'block 16384" 10
|
||||||
(exercise-read (list _IOFBF 16384)))
|
(exercise-read (list 'block 16384)))
|
||||||
|
|
||||||
(benchmark "small strings" 100000
|
(benchmark "small strings" 100000
|
||||||
(call-with-input-string small read))
|
(call-with-input-string small read))
|
||||||
|
|
|
@ -43,7 +43,7 @@
|
||||||
|
|
||||||
(benchmark "uniform-vector-read!" 20000
|
(benchmark "uniform-vector-read!" 20000
|
||||||
(let ((input (open-input-file file-name)))
|
(let ((input (open-input-file file-name)))
|
||||||
(setvbuf input _IONBF)
|
(setvbuf input 'none)
|
||||||
(uniform-vector-read! buf input)
|
(uniform-vector-read! buf input)
|
||||||
(close 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'
|
& eval 'exec perl -wS "$0" $argv:q'
|
||||||
if 0;
|
if 0;
|
||||||
# Generate a release announcement message.
|
# 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
|
# The definition above must lie within the first 8 lines in order
|
||||||
# for the Emacs time-stamp write hook (at end) to update it.
|
# for the Emacs time-stamp write hook (at end) to update it.
|
||||||
# If you change this file with Emacs, please let the write hook
|
# If you change this file with Emacs, please let the write hook
|
||||||
# do its job. Otherwise, update this string manually.
|
# 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
|
# This program is free software: you can redistribute it and/or modify
|
||||||
# it under the terms of the GNU General Public License as published by
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
@ -29,15 +29,18 @@ my $VERSION = '2012-06-08 06:53'; # UTC
|
||||||
use strict;
|
use strict;
|
||||||
|
|
||||||
use Getopt::Long;
|
use Getopt::Long;
|
||||||
use Digest::MD5;
|
|
||||||
eval { require Digest::SHA; }
|
|
||||||
or eval 'use Digest::SHA1';
|
|
||||||
use POSIX qw(strftime);
|
use POSIX qw(strftime);
|
||||||
|
|
||||||
(my $ME = $0) =~ s|.*/||;
|
(my $ME = $0) =~ s|.*/||;
|
||||||
|
|
||||||
my %valid_release_types = map {$_ => 1} qw (alpha beta stable);
|
my %valid_release_types = map {$_ => 1} qw (alpha beta stable);
|
||||||
my @archive_suffixes = ('tar.gz', 'tar.bz2', 'tar.lzma', 'tar.xz');
|
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 = '.';
|
my $srcdir = '.';
|
||||||
|
|
||||||
sub usage ($)
|
sub usage ($)
|
||||||
|
@ -157,15 +160,13 @@ sub print_checksums (@)
|
||||||
|
|
||||||
foreach my $meth (qw (md5 sha1))
|
foreach my $meth (qw (md5 sha1))
|
||||||
{
|
{
|
||||||
|
my $class = $digest_classes{$meth} or next;
|
||||||
foreach my $f (@file)
|
foreach my $f (@file)
|
||||||
{
|
{
|
||||||
open IN, '<', $f
|
open IN, '<', $f
|
||||||
or die "$ME: $f: cannot open for reading: $!\n";
|
or die "$ME: $f: cannot open for reading: $!\n";
|
||||||
binmode IN;
|
binmode IN;
|
||||||
my $dig =
|
my $dig = $class->new->addfile(*IN)->hexdigest;
|
||||||
($meth eq 'md5'
|
|
||||||
? Digest::MD5->new->addfile(*IN)->hexdigest
|
|
||||||
: Digest::SHA1->new->addfile(*IN)->hexdigest);
|
|
||||||
close IN;
|
close IN;
|
||||||
print "$dig $f\n";
|
print "$dig $f\n";
|
||||||
}
|
}
|
||||||
|
@ -416,14 +417,15 @@ sub get_tool_versions ($$)
|
||||||
@url_dir_list
|
@url_dir_list
|
||||||
or (warn "URL directory name(s) not specified\n"), $fail = 1;
|
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
|
grep (/^gnulib$/, @tool_list) ^ defined $gnulib_version
|
||||||
and (warn "when specifying gnulib as a tool, you must also specify\n"
|
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"
|
. "--gnulib-version=V, where V is the result of running git describe\n"
|
||||||
. "in the gnulib source directory.\n"), $fail = 1;
|
. "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;
|
or (warn "'$release_type': invalid release type\n"), $fail = 1;
|
||||||
|
|
||||||
@ARGV
|
@ARGV
|
||||||
|
@ -550,6 +552,6 @@ EOF
|
||||||
## eval: (add-hook 'write-file-hooks 'time-stamp)
|
## eval: (add-hook 'write-file-hooks 'time-stamp)
|
||||||
## time-stamp-start: "my $VERSION = '"
|
## time-stamp-start: "my $VERSION = '"
|
||||||
## time-stamp-format: "%:y-%02m-%02d %02H:%02M"
|
## time-stamp-format: "%:y-%02m-%02d %02H:%02M"
|
||||||
## time-stamp-time-zone: "UTC"
|
## time-stamp-time-zone: "UTC0"
|
||||||
## time-stamp-end: "'; # UTC"
|
## time-stamp-end: "'; # UTC"
|
||||||
## End:
|
## End:
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
# Output a system dependent set of variables, describing how to set the
|
# Output a system dependent set of variables, describing how to set the
|
||||||
# run time search path of shared libraries in an executable.
|
# 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
|
# Taken from GNU libtool, 2001
|
||||||
# Originally by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996
|
# Originally by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996
|
||||||
#
|
#
|
||||||
|
@ -367,11 +367,7 @@ else
|
||||||
dgux*)
|
dgux*)
|
||||||
hardcode_libdir_flag_spec='-L$libdir'
|
hardcode_libdir_flag_spec='-L$libdir'
|
||||||
;;
|
;;
|
||||||
freebsd2.2*)
|
freebsd2.[01]*)
|
||||||
hardcode_libdir_flag_spec='-R$libdir'
|
|
||||||
hardcode_direct=yes
|
|
||||||
;;
|
|
||||||
freebsd2*)
|
|
||||||
hardcode_direct=yes
|
hardcode_direct=yes
|
||||||
hardcode_minus_L=yes
|
hardcode_minus_L=yes
|
||||||
;;
|
;;
|
||||||
|
@ -548,13 +544,11 @@ case "$host_os" in
|
||||||
dgux*)
|
dgux*)
|
||||||
library_names_spec='$libname$shrext'
|
library_names_spec='$libname$shrext'
|
||||||
;;
|
;;
|
||||||
|
freebsd[23].*)
|
||||||
|
library_names_spec='$libname$shrext$versuffix'
|
||||||
|
;;
|
||||||
freebsd* | dragonfly*)
|
freebsd* | dragonfly*)
|
||||||
case "$host_os" in
|
library_names_spec='$libname$shrext'
|
||||||
freebsd[123]*)
|
|
||||||
library_names_spec='$libname$shrext$versuffix' ;;
|
|
||||||
*)
|
|
||||||
library_names_spec='$libname$shrext' ;;
|
|
||||||
esac
|
|
||||||
;;
|
;;
|
||||||
gnu*)
|
gnu*)
|
||||||
library_names_spec='$libname$shrext'
|
library_names_spec='$libname$shrext'
|
||||||
|
|
|
@ -2,10 +2,9 @@
|
||||||
# gendocs.sh -- generate a GNU manual in many formats. This script is
|
# gendocs.sh -- generate a GNU manual in many formats. This script is
|
||||||
# mentioned in maintain.texi. See the help message below for usage details.
|
# 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
|
# Copyright 2003-2017 Free Software Foundation, Inc.
|
||||||
# Free Software Foundation, Inc.
|
|
||||||
#
|
#
|
||||||
# This program is free software: you can redistribute it and/or modify
|
# This program is free software: you can redistribute it and/or modify
|
||||||
# it under the terms of the GNU General Public License as published by
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
@ -21,17 +20,16 @@ scriptversion=2013-10-10.09
|
||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
#
|
#
|
||||||
# Original author: Mohit Agarwal.
|
# 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
|
# The latest version of this script, and the companion template, is
|
||||||
# available from Texinfo CVS:
|
# available from the Gnulib repository:
|
||||||
# http://savannah.gnu.org/cgi-bin/viewcvs/texinfo/texinfo/util/gendocs.sh
|
|
||||||
# http://savannah.gnu.org/cgi-bin/viewcvs/texinfo/texinfo/util/gendocs_template
|
|
||||||
#
|
#
|
||||||
# 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:
|
# 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.
|
# makeinfo. But it should be simple enough to adjust.
|
||||||
# - images are not imported in the source tarball. All the needed
|
# - images are not imported in the source tarball. All the needed
|
||||||
# formats (PDF, PNG, etc.) should be included.
|
# formats (PDF, PNG, etc.) should be included.
|
||||||
|
@ -39,12 +37,12 @@ scriptversion=2013-10-10.09
|
||||||
prog=`basename "$0"`
|
prog=`basename "$0"`
|
||||||
srcdir=`pwd`
|
srcdir=`pwd`
|
||||||
|
|
||||||
scripturl="http://savannah.gnu.org/cgi-bin/viewcvs/~checkout~/texinfo/texinfo/util/gendocs.sh"
|
scripturl="http://git.savannah.gnu.org/cgit/gnulib.git/plain/build-aux/gendocs.sh"
|
||||||
templateurl="http://savannah.gnu.org/cgi-bin/viewcvs/~checkout~/texinfo/texinfo/util/gendocs_template"
|
templateurl="http://git.savannah.gnu.org/cgit/gnulib.git/plain/doc/gendocs_template"
|
||||||
|
|
||||||
: ${SETLANG="env LANG= LC_MESSAGES= LC_ALL= LANGUAGE="}
|
: ${SETLANG="env LANG= LC_MESSAGES= LC_ALL= LANGUAGE="}
|
||||||
: ${MAKEINFO="makeinfo"}
|
: ${MAKEINFO="makeinfo"}
|
||||||
: ${TEXI2DVI="texi2dvi -t @finalout"}
|
: ${TEXI2DVI="texi2dvi"}
|
||||||
: ${DOCBOOK2HTML="docbook2html"}
|
: ${DOCBOOK2HTML="docbook2html"}
|
||||||
: ${DOCBOOK2PDF="docbook2pdf"}
|
: ${DOCBOOK2PDF="docbook2pdf"}
|
||||||
: ${DOCBOOK2TXT="docbook2txt"}
|
: ${DOCBOOK2TXT="docbook2txt"}
|
||||||
|
@ -54,9 +52,27 @@ templateurl="http://savannah.gnu.org/cgi-bin/viewcvs/~checkout~/texinfo/texinfo/
|
||||||
unset CDPATH
|
unset CDPATH
|
||||||
unset use_texi2html
|
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
|
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
|
There is NO warranty. You may redistribute this software
|
||||||
under the terms of the GNU General Public License.
|
under the terms of the GNU General Public License.
|
||||||
For more information about these matters, see the files named COPYING."
|
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/.
|
-o OUTDIR write files into OUTDIR, instead of manual/.
|
||||||
-I DIR append DIR to the Texinfo search path.
|
-I DIR append DIR to the Texinfo search path.
|
||||||
--common ARG pass ARG in all invocations.
|
--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.
|
--info ARG pass ARG to makeinfo for Info, instead of --no-split.
|
||||||
--no-ascii skip generating the plain text output.
|
--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.
|
--source ARG include ARG in tar archive of sources.
|
||||||
--split HOW make split HTML by node, section, chapter; default node.
|
--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.
|
--texi2html use texi2html to make HTML target, with all split versions.
|
||||||
--docbook convert through DocBook too (xml, txt, html, pdf).
|
--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
|
happen to have a non-English manual and non-English web site, see the
|
||||||
SETLANG setting in the source.
|
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
|
while test $# -gt 0; do
|
||||||
case $1 in
|
case $1 in
|
||||||
-s) shift; srcfile=$1;;
|
-s) shift; srcfile=$1;;
|
||||||
|
@ -159,8 +166,12 @@ while test $# -gt 0; do
|
||||||
--html) shift; htmlarg=$1;;
|
--html) shift; htmlarg=$1;;
|
||||||
--info) shift; infoarg=$1;;
|
--info) shift; infoarg=$1;;
|
||||||
--no-ascii) generate_ascii=false;;
|
--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;;
|
--source) shift; source_extra=$1;;
|
||||||
--split) shift; split=$1;;
|
--split) shift; split=$1;;
|
||||||
|
--tex) shift; texarg=$1;;
|
||||||
--texi2html) use_texi2html=1;;
|
--texi2html) use_texi2html=1;;
|
||||||
|
|
||||||
--help) echo "$usage"; exit 0;;
|
--help) echo "$usage"; exit 0;;
|
||||||
|
@ -221,8 +232,9 @@ calcsize()
|
||||||
|
|
||||||
# copy_images OUTDIR HTML-FILE...
|
# copy_images OUTDIR HTML-FILE...
|
||||||
# -------------------------------
|
# -------------------------------
|
||||||
# Copy all the images needed by the HTML-FILEs into OUTDIR. Look
|
# Copy all the images needed by the HTML-FILEs into OUTDIR.
|
||||||
# for them in the -I directories.
|
# Look for them in . and the -I directories; this is simpler than what
|
||||||
|
# makeinfo supports with -I, but hopefully it will suffice.
|
||||||
copy_images()
|
copy_images()
|
||||||
{
|
{
|
||||||
local odir
|
local odir
|
||||||
|
@ -232,7 +244,7 @@ copy_images()
|
||||||
BEGIN {
|
BEGIN {
|
||||||
\$me = '$prog';
|
\$me = '$prog';
|
||||||
\$odir = '$odir';
|
\$odir = '$odir';
|
||||||
@dirs = qw($dirs);
|
@dirs = qw(. $dirs);
|
||||||
}
|
}
|
||||||
" -e '
|
" -e '
|
||||||
/<img src="(.*?)"/g && ++$need{$1};
|
/<img src="(.*?)"/g && ++$need{$1};
|
||||||
|
@ -270,32 +282,39 @@ echo "Making output for $srcfile"
|
||||||
echo " in `pwd`"
|
echo " in `pwd`"
|
||||||
mkdir -p "$outdir/"
|
mkdir -p "$outdir/"
|
||||||
|
|
||||||
cmd="$SETLANG $MAKEINFO -o $PACKAGE.info $commonarg $infoarg \"$srcfile\""
|
#
|
||||||
echo "Generating info... ($cmd)"
|
if $generate_info; then
|
||||||
rm -f $PACKAGE.info* # get rid of any strays
|
cmd="$SETLANG $MAKEINFO -o $PACKAGE.info $commonarg $infoarg \"$srcfile\""
|
||||||
eval "$cmd"
|
echo "Generating info... ($cmd)"
|
||||||
tar czf "$outdir/$PACKAGE.info.tar.gz" $PACKAGE.info*
|
rm -f $PACKAGE.info* # get rid of any strays
|
||||||
ls -l "$outdir/$PACKAGE.info.tar.gz"
|
eval "$cmd"
|
||||||
info_tgz_size=`calcsize "$outdir/$PACKAGE.info.tar.gz"`
|
tar czf "$outdir/$PACKAGE.info.tar.gz" $PACKAGE.info*
|
||||||
# do not mv the info files, there's no point in having them available
|
ls -l "$outdir/$PACKAGE.info.tar.gz"
|
||||||
# separately on the web.
|
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"
|
if $generate_tex; then
|
||||||
eval "$cmd"
|
cmd="$SETLANG $TEXI2DVI $dirargs $texarg \"$srcfile\""
|
||||||
# compress/finish dvi:
|
printf "\nGenerating dvi... ($cmd)\n"
|
||||||
gzip -f -9 $PACKAGE.dvi
|
eval "$cmd"
|
||||||
dvi_gz_size=`calcsize $PACKAGE.dvi.gz`
|
# compress/finish dvi:
|
||||||
mv $PACKAGE.dvi.gz "$outdir/"
|
gzip -f -9 $PACKAGE.dvi
|
||||||
ls -l "$outdir/$PACKAGE.dvi.gz"
|
dvi_gz_size=`calcsize $PACKAGE.dvi.gz`
|
||||||
|
mv $PACKAGE.dvi.gz "$outdir/"
|
||||||
|
ls -l "$outdir/$PACKAGE.dvi.gz"
|
||||||
|
|
||||||
cmd="$SETLANG $TEXI2DVI --pdf $dirargs \"$srcfile\""
|
cmd="$SETLANG $TEXI2DVI --pdf $dirargs $texarg \"$srcfile\""
|
||||||
printf "\nGenerating pdf... ($cmd)\n"
|
printf "\nGenerating pdf... ($cmd)\n"
|
||||||
eval "$cmd"
|
eval "$cmd"
|
||||||
pdf_size=`calcsize $PACKAGE.pdf`
|
pdf_size=`calcsize $PACKAGE.pdf`
|
||||||
mv $PACKAGE.pdf "$outdir/"
|
mv $PACKAGE.pdf "$outdir/"
|
||||||
ls -l "$outdir/$PACKAGE.pdf"
|
ls -l "$outdir/$PACKAGE.pdf"
|
||||||
|
fi # end tex (dvi + pdf)
|
||||||
|
|
||||||
|
#
|
||||||
if $generate_ascii; then
|
if $generate_ascii; then
|
||||||
opt="-o $PACKAGE.txt --no-split --no-headers $commonarg"
|
opt="-o $PACKAGE.txt --no-split --no-headers $commonarg"
|
||||||
cmd="$SETLANG $MAKEINFO $opt \"$srcfile\""
|
cmd="$SETLANG $MAKEINFO $opt \"$srcfile\""
|
||||||
|
@ -308,6 +327,9 @@ if $generate_ascii; then
|
||||||
ls -l "$outdir/$PACKAGE.txt" "$outdir/$PACKAGE.txt.gz"
|
ls -l "$outdir/$PACKAGE.txt" "$outdir/$PACKAGE.txt.gz"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
#
|
||||||
|
|
||||||
|
if $generate_html; then
|
||||||
# Split HTML at level $1. Used for texi2html.
|
# Split HTML at level $1. Used for texi2html.
|
||||||
html_split()
|
html_split()
|
||||||
{
|
{
|
||||||
|
@ -382,7 +404,9 @@ else # use texi2html:
|
||||||
html_split chapter
|
html_split chapter
|
||||||
html_split section
|
html_split section
|
||||||
fi
|
fi
|
||||||
|
fi # end html
|
||||||
|
|
||||||
|
#
|
||||||
printf "\nMaking .tar.gz for sources...\n"
|
printf "\nMaking .tar.gz for sources...\n"
|
||||||
d=`dirname $srcfile`
|
d=`dirname $srcfile`
|
||||||
(
|
(
|
||||||
|
@ -393,6 +417,8 @@ d=`dirname $srcfile`
|
||||||
)
|
)
|
||||||
texi_tgz_size=`calcsize "$outdir/$PACKAGE.texi.tar.gz"`
|
texi_tgz_size=`calcsize "$outdir/$PACKAGE.texi.tar.gz"`
|
||||||
|
|
||||||
|
#
|
||||||
|
# Do everything again through docbook.
|
||||||
if test -n "$docbook"; then
|
if test -n "$docbook"; then
|
||||||
opt="-o - --docbook $commonarg"
|
opt="-o - --docbook $commonarg"
|
||||||
cmd="$SETLANG $MAKEINFO $opt \"$srcfile\" >${srcdir}/$PACKAGE-db.xml"
|
cmd="$SETLANG $MAKEINFO $opt \"$srcfile\" >${srcdir}/$PACKAGE-db.xml"
|
||||||
|
@ -431,7 +457,8 @@ if test -n "$docbook"; then
|
||||||
mv $PACKAGE-db.pdf "$outdir/"
|
mv $PACKAGE-db.pdf "$outdir/"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
printf "\nMaking index file...\n"
|
#
|
||||||
|
printf "\nMaking index.html for $PACKAGE...\n"
|
||||||
if test -z "$use_texi2html"; then
|
if test -z "$use_texi2html"; then
|
||||||
CONDS="/%%IF *HTML_SECTION%%/,/%%ENDIF *HTML_SECTION%%/d;\
|
CONDS="/%%IF *HTML_SECTION%%/,/%%ENDIF *HTML_SECTION%%/d;\
|
||||||
/%%IF *HTML_CHAPTER%%/,/%%ENDIF *HTML_CHAPTER%%/d"
|
/%%IF *HTML_CHAPTER%%/,/%%ENDIF *HTML_CHAPTER%%/d"
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
# Print a version string.
|
# 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
|
# This program is free software: you can redistribute it and/or modify
|
||||||
# it under the terms of the GNU General Public License as published by
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
@ -85,9 +85,10 @@ Print a version string.
|
||||||
|
|
||||||
Options:
|
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*')
|
--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
|
--help display this help and exit
|
||||||
--version output version information and exit
|
--version output version information and exit
|
||||||
|
@ -104,9 +105,9 @@ while test $# -gt 0; do
|
||||||
case $1 in
|
case $1 in
|
||||||
--help) echo "$usage"; exit 0;;
|
--help) echo "$usage"; exit 0;;
|
||||||
--version) echo "$version"; exit 0;;
|
--version) echo "$version"; exit 0;;
|
||||||
--prefix) shift; prefix="$1";;
|
--prefix) shift; prefix=${1?};;
|
||||||
--match) shift; match="$1";;
|
--match) shift; match="$1";;
|
||||||
--fallback) shift; fallback="$1";;
|
--fallback) shift; fallback=${1?};;
|
||||||
-*)
|
-*)
|
||||||
echo "$0: Unknown option '$1'." >&2
|
echo "$0: Unknown option '$1'." >&2
|
||||||
echo "$0: Try '--help' for more information." >&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"
|
# string we're using came from git. I.e., skip the test if it's "UNKNOWN"
|
||||||
# or if it came from .tarball-version.
|
# or if it came from .tarball-version.
|
||||||
if test "x$v_from_git" != x; then
|
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
|
git update-index --refresh > /dev/null 2>&1
|
||||||
|
|
||||||
dirty=`exec 2>/dev/null;git diff-index --name-only HEAD` || dirty=
|
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
|
fi
|
||||||
|
|
||||||
# Omit the trailing newline, so that m4_esyscmd can use the result directly.
|
# Omit the trailing newline, so that m4_esyscmd can use the result directly.
|
||||||
echo "$v" | tr -d "$nl"
|
printf %s "$v"
|
||||||
|
|
||||||
# Local variables:
|
# Local variables:
|
||||||
# eval: (add-hook 'write-file-hooks 'time-stamp)
|
# eval: (add-hook 'write-file-hooks 'time-stamp)
|
||||||
# time-stamp-start: "scriptversion="
|
# time-stamp-start: "scriptversion="
|
||||||
# time-stamp-format: "%:y-%02m-%02d.%02H"
|
# time-stamp-format: "%:y-%02m-%02d.%02H"
|
||||||
# time-stamp-time-zone: "UTC"
|
# time-stamp-time-zone: "UTC0"
|
||||||
# time-stamp-end: "; # UTC"
|
# time-stamp-end: "; # UTC"
|
||||||
# End:
|
# 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'
|
& eval 'exec perl -wS "$0" $argv:q'
|
||||||
if 0;
|
if 0;
|
||||||
# Convert git log output to ChangeLog format.
|
# 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
|
# The definition above must lie within the first 8 lines in order
|
||||||
# for the Emacs time-stamp write hook (at end) to update it.
|
# for the Emacs time-stamp write hook (at end) to update it.
|
||||||
# If you change this file with Emacs, please let the write hook
|
# If you change this file with Emacs, please let the write hook
|
||||||
# do its job. Otherwise, update this string manually.
|
# 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
|
# This program is free software: you can redistribute it and/or modify
|
||||||
# it under the terms of the GNU General Public License as published by
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
@ -72,6 +72,9 @@ OPTIONS:
|
||||||
directory can be derived.
|
directory can be derived.
|
||||||
--since=DATE convert only the logs since DATE;
|
--since=DATE convert only the logs since DATE;
|
||||||
the default is to convert all log entries.
|
the default is to convert all log entries.
|
||||||
|
--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;
|
--format=FMT set format string for commit subject and body;
|
||||||
see 'man git-log' for the list of format metacharacters;
|
see 'man git-log' for the list of format metacharacters;
|
||||||
the default is '%s%n%b%n'
|
the default is '%s%n%b%n'
|
||||||
|
@ -220,10 +223,13 @@ sub git_dir_option($)
|
||||||
|
|
||||||
{
|
{
|
||||||
my $since_date;
|
my $since_date;
|
||||||
|
my $until_date;
|
||||||
my $format_string = '%s%n%b%n';
|
my $format_string = '%s%n%b%n';
|
||||||
my $amend_file;
|
my $amend_file;
|
||||||
my $append_dot = 0;
|
my $append_dot = 0;
|
||||||
my $cluster = 1;
|
my $cluster = 1;
|
||||||
|
my $ignore_matching;
|
||||||
|
my $ignore_line;
|
||||||
my $strip_tab = 0;
|
my $strip_tab = 0;
|
||||||
my $strip_cherry_pick = 0;
|
my $strip_cherry_pick = 0;
|
||||||
my $srcdir;
|
my $srcdir;
|
||||||
|
@ -232,10 +238,13 @@ sub git_dir_option($)
|
||||||
help => sub { usage 0 },
|
help => sub { usage 0 },
|
||||||
version => sub { print "$ME version $VERSION\n"; exit },
|
version => sub { print "$ME version $VERSION\n"; exit },
|
||||||
'since=s' => \$since_date,
|
'since=s' => \$since_date,
|
||||||
|
'until=s' => \$until_date,
|
||||||
'format=s' => \$format_string,
|
'format=s' => \$format_string,
|
||||||
'amend=s' => \$amend_file,
|
'amend=s' => \$amend_file,
|
||||||
'append-dot' => \$append_dot,
|
'append-dot' => \$append_dot,
|
||||||
'cluster!' => \$cluster,
|
'cluster!' => \$cluster,
|
||||||
|
'ignore-matching=s' => \$ignore_matching,
|
||||||
|
'ignore-line=s' => \$ignore_line,
|
||||||
'strip-tab' => \$strip_tab,
|
'strip-tab' => \$strip_tab,
|
||||||
'strip-cherry-pick' => \$strip_cherry_pick,
|
'strip-cherry-pick' => \$strip_cherry_pick,
|
||||||
'srcdir=s' => \$srcdir,
|
'srcdir=s' => \$srcdir,
|
||||||
|
@ -243,6 +252,8 @@ sub git_dir_option($)
|
||||||
|
|
||||||
defined $since_date
|
defined $since_date
|
||||||
and unshift @ARGV, "--since=$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/)
|
# 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.
|
# 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_multi_paragraph;
|
||||||
my $prev_date_line = '';
|
my $prev_date_line = '';
|
||||||
my @prev_coauthors = ();
|
my @prev_coauthors = ();
|
||||||
|
my @skipshas = ();
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
defined (my $in = <PIPE>)
|
defined (my $in = <PIPE>)
|
||||||
|
@ -279,6 +291,19 @@ sub git_dir_option($)
|
||||||
$sha =~ /^[0-9a-fA-F]{40}$/
|
$sha =~ /^[0-9a-fA-F]{40}$/
|
||||||
or die "$ME:$.: invalid SHA1: $sha\n";
|
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.
|
# If this commit's log requires any transformation, do it now.
|
||||||
my $code = $amend_code->{$sha};
|
my $code = $amend_code->{$sha};
|
||||||
if (defined $code)
|
if (defined $code)
|
||||||
|
@ -306,7 +331,7 @@ sub git_dir_option($)
|
||||||
$rest =~ s/^\s*\(cherry picked from commit [\da-f]+\)\n//m;
|
$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;
|
my $author_line = shift @line;
|
||||||
defined $author_line
|
defined $author_line
|
||||||
or die "$ME:$.: unexpected EOF\n";
|
or die "$ME:$.: unexpected EOF\n";
|
||||||
|
@ -316,17 +341,18 @@ sub git_dir_option($)
|
||||||
|
|
||||||
# Format 'Copyright-paperwork-exempt: Yes' as a standard ChangeLog
|
# Format 'Copyright-paperwork-exempt: Yes' as a standard ChangeLog
|
||||||
# `(tiny change)' annotation.
|
# `(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)' : '');
|
? ' (tiny change)' : '');
|
||||||
|
|
||||||
my $date_line = sprintf "%s %s$tiny\n",
|
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;
|
my @coauthors = grep /^Co-authored-by:.*$/, @line;
|
||||||
# Omit meta-data lines we've already interpreted.
|
# Omit meta-data lines we've already interpreted.
|
||||||
@line = grep !/^(?:Signed-off-by:[ ].*>$
|
@line = grep !/^(?:Signed-off-by:[ ].*>$
|
||||||
|Co-authored-by:[ ]
|
|Co-authored-by:[ ]
|
||||||
|Copyright-paperwork-exempt:[ ]
|
|Copyright-paperwork-exempt:[ ]
|
||||||
|
|Tiny-change:[ ]
|
||||||
)/x, @line;
|
)/x, @line;
|
||||||
|
|
||||||
# Remove leading and trailing blank lines.
|
# Remove leading and trailing blank lines.
|
||||||
|
@ -336,68 +362,109 @@ sub git_dir_option($)
|
||||||
while ($line[$#line] =~ /^\s*$/) { pop @line; }
|
while ($line[$#line] =~ /^\s*$/) { pop @line; }
|
||||||
}
|
}
|
||||||
|
|
||||||
# Record whether there are two or more paragraphs.
|
# Handle Emacs gitmerge.el "skipped" commits.
|
||||||
my $multi_paragraph = grep /^\s*$/, @line;
|
# 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
|
# Ignore commits that match the --ignore-matching pattern, if specified.
|
||||||
# standard multi-author ChangeLog format.
|
if (defined $ignore_matching && @line && $line[0] =~ /$ignore_matching/)
|
||||||
for (@coauthors)
|
|
||||||
{
|
{
|
||||||
s/^Co-authored-by:\s*/\t /;
|
$skipflag = 1;
|
||||||
s/\s*</ </;
|
}
|
||||||
|
elsif ($skipflag)
|
||||||
/<.*?@.*\..*>/
|
{
|
||||||
or warn "$ME: warning: missing email address for "
|
## Perhaps only warn if a pattern matches more than once?
|
||||||
. substr ($_, 5) . "\n";
|
warn "$ME: warning: skipping $sha due to $skipflag\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
# If clustering of commit messages has been disabled, if this header
|
if (! $skipflag)
|
||||||
# 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)
|
|
||||||
{
|
{
|
||||||
$prev_date_line eq ''
|
if (defined $ignore_line && @line)
|
||||||
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
|
@line = grep ! /$ignore_line/, @line;
|
||||||
if (length $line[0] < 72)
|
while ($line[$#line] =~ /^\s*$/) { pop @line; }
|
||||||
{
|
|
||||||
# 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.
|
# Record whether there are two or more paragraphs.
|
||||||
$strip_tab
|
my $multi_paragraph = grep /^\s*$/, @line;
|
||||||
and map { s/^\t// } @line;
|
|
||||||
|
|
||||||
# Prefix each non-empty line with a TAB.
|
# Format 'Co-authored-by: A U Thor <email@example.com>' lines in
|
||||||
@line = map { length $_ ? "\t$_" : '' } @line;
|
# 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>)
|
defined ($in = <PIPE>)
|
||||||
|
@ -427,6 +494,6 @@ sub git_dir_option($)
|
||||||
# eval: (add-hook 'write-file-hooks 'time-stamp)
|
# eval: (add-hook 'write-file-hooks 'time-stamp)
|
||||||
# time-stamp-start: "my $VERSION = '"
|
# time-stamp-start: "my $VERSION = '"
|
||||||
# time-stamp-format: "%:y-%02m-%02d %02H:%02M"
|
# time-stamp-format: "%:y-%02m-%02d %02H:%02M"
|
||||||
# time-stamp-time-zone: "UTC"
|
# time-stamp-time-zone: "UTC0"
|
||||||
# time-stamp-end: "'; # UTC"
|
# time-stamp-end: "'; # UTC"
|
||||||
# End:
|
# End:
|
||||||
|
|
|
@ -2,9 +2,9 @@
|
||||||
# Run this after each non-alpha release, to update the web documentation at
|
# Run this after each non-alpha release, to update the web documentation at
|
||||||
# http://www.gnu.org/software/$pkg/manual/
|
# 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
|
# This program is free software: you can redistribute it and/or modify
|
||||||
# it under the terms of the GNU General Public License as published by
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
@ -40,6 +40,7 @@ assumes all documentation is in the doc/ sub-directory.
|
||||||
Options:
|
Options:
|
||||||
-C, --builddir=DIR location of (configured) Makefile (default: .)
|
-C, --builddir=DIR location of (configured) Makefile (default: .)
|
||||||
-n, --dry-run don't actually commit anything
|
-n, --dry-run don't actually commit anything
|
||||||
|
-m, --mirror remove out of date files from document server
|
||||||
--help print this help, then exit
|
--help print this help, then exit
|
||||||
--version print version number, then exit
|
--version print version number, then exit
|
||||||
|
|
||||||
|
@ -107,6 +108,7 @@ find_tool XARGS gxargs xargs
|
||||||
|
|
||||||
builddir=.
|
builddir=.
|
||||||
dryrun=
|
dryrun=
|
||||||
|
rm_stale='echo'
|
||||||
while test $# != 0
|
while test $# != 0
|
||||||
do
|
do
|
||||||
# Handle --option=value by splitting apart and putting back on argv.
|
# Handle --option=value by splitting apart and putting back on argv.
|
||||||
|
@ -115,7 +117,7 @@ do
|
||||||
opt=$(echo "$1" | sed -e 's/=.*//')
|
opt=$(echo "$1" | sed -e 's/=.*//')
|
||||||
val=$(echo "$1" | sed -e 's/[^=]*=//')
|
val=$(echo "$1" | sed -e 's/[^=]*=//')
|
||||||
shift
|
shift
|
||||||
set dummy "$opt" "$val" ${1+"$@"}; shift
|
set dummy "$opt" "$val" "$@"; shift
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
|
@ -123,6 +125,7 @@ do
|
||||||
--help|--version) ${1#--};;
|
--help|--version) ${1#--};;
|
||||||
-C|--builddir) shift; builddir=$1; shift ;;
|
-C|--builddir) shift; builddir=$1; shift ;;
|
||||||
-n|--dry-run) dryrun=echo; shift;;
|
-n|--dry-run) dryrun=echo; shift;;
|
||||||
|
-m|--mirror) rm_stale=''; shift;;
|
||||||
--*) die "unrecognized option: $1";;
|
--*) die "unrecognized option: $1";;
|
||||||
*) break;;
|
*) break;;
|
||||||
esac
|
esac
|
||||||
|
@ -159,6 +162,7 @@ $GIT submodule update --recursive
|
||||||
./bootstrap
|
./bootstrap
|
||||||
srcdir=$(pwd)
|
srcdir=$(pwd)
|
||||||
cd "$builddir"
|
cd "$builddir"
|
||||||
|
builddir=$(pwd)
|
||||||
./config.status --recheck
|
./config.status --recheck
|
||||||
./config.status
|
./config.status
|
||||||
make
|
make
|
||||||
|
@ -175,13 +179,25 @@ $RSYNC -avP "$builddir"/doc/manual/ $tmp/$pkg/manual
|
||||||
cd $tmp/$pkg/manual
|
cd $tmp/$pkg/manual
|
||||||
|
|
||||||
# Add all the files. This is simpler than trying to add only the
|
# Add all the files. This is simpler than trying to add only the
|
||||||
# new ones because of new directories: it would require iterating on
|
# new ones because of new directories
|
||||||
# adding the outer directories, and then their contents.
|
# First add non empty dirs individually
|
||||||
#
|
find . -name CVS -prune -o -type d \! -empty -print \
|
||||||
# find guarantees that we add outer directories first.
|
| $XARGS -n1 --no-run-if-empty -- $dryrun $CVS add -ko
|
||||||
find . -name CVS -prune -o -print \
|
# Now add all files
|
||||||
|
find . -name CVS -prune -o -type f -print \
|
||||||
| $XARGS --no-run-if-empty -- $dryrun $CVS add -ko
|
| $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
|
$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)
|
# eval: (add-hook 'write-file-hooks 'time-stamp)
|
||||||
# time-stamp-start: "VERSION="
|
# time-stamp-start: "VERSION="
|
||||||
# time-stamp-format: "%:y-%02m-%02d.%02H"
|
# time-stamp-format: "%:y-%02m-%02d.%02H"
|
||||||
# time-stamp-time-zone: "UTC"
|
# time-stamp-time-zone: "UTC0"
|
||||||
# time-stamp-end: "; # UTC"
|
# time-stamp-end: "; # UTC"
|
||||||
# End:
|
# End:
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
# Sign files and upload them.
|
# 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
|
# This program is free software; you can redistribute it and/or modify
|
||||||
# it under the terms of the GNU General Public License as published by
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
@ -435,6 +435,6 @@ exit 0
|
||||||
# eval: (add-hook 'write-file-hooks 'time-stamp)
|
# eval: (add-hook 'write-file-hooks 'time-stamp)
|
||||||
# time-stamp-start: "scriptversion="
|
# time-stamp-start: "scriptversion="
|
||||||
# time-stamp-format: "%:y-%02m-%02d.%02H"
|
# time-stamp-format: "%:y-%02m-%02d.%02H"
|
||||||
# time-stamp-time-zone: "UTC"
|
# time-stamp-time-zone: "UTC0"
|
||||||
# time-stamp-end: "; # UTC"
|
# time-stamp-end: "; # UTC"
|
||||||
# End:
|
# End:
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/* A C macro for declaring that specific arguments must not be NULL.
|
/* 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
|
This program is free software: you can redistribute it and/or modify it
|
||||||
under the terms of the GNU General Public License as published
|
under the terms of the GNU General Public License as published
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/* C++ compatible function declaration macros.
|
/* 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
|
This program is free software: you can redistribute it and/or modify it
|
||||||
under the terms of the GNU General Public License as published
|
under the terms of the GNU General Public License as published
|
||||||
|
@ -17,6 +17,15 @@
|
||||||
#ifndef _GL_CXXDEFS_H
|
#ifndef _GL_CXXDEFS_H
|
||||||
#define _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:
|
/* The three most frequent use cases of these macros are:
|
||||||
|
|
||||||
* For providing a substitute for a function that is missing on some
|
* 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.
|
that redirects to rpl_func, if GNULIB_NAMESPACE is defined.
|
||||||
Example:
|
Example:
|
||||||
_GL_CXXALIAS_RPL (open, int, (const char *filename, int flags, ...));
|
_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) \
|
#define _GL_CXXALIAS_RPL(func,rettype,parameters) \
|
||||||
_GL_CXXALIAS_RPL_1 (func, rpl_##func, rettype, parameters)
|
_GL_CXXALIAS_RPL_1 (func, rpl_##func, rettype, parameters)
|
||||||
#if defined __cplusplus && defined GNULIB_NAMESPACE
|
#if defined __cplusplus && defined GNULIB_NAMESPACE
|
||||||
# define _GL_CXXALIAS_RPL_1(func,rpl_func,rettype,parameters) \
|
# define _GL_CXXALIAS_RPL_1(func,rpl_func,rettype,parameters) \
|
||||||
namespace GNULIB_NAMESPACE \
|
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
|
_GL_EXTERN_C int _gl_cxxalias_dummy
|
||||||
#else
|
#else
|
||||||
|
@ -135,8 +155,15 @@
|
||||||
# define _GL_CXXALIAS_RPL_CAST_1(func,rpl_func,rettype,parameters) \
|
# define _GL_CXXALIAS_RPL_CAST_1(func,rpl_func,rettype,parameters) \
|
||||||
namespace GNULIB_NAMESPACE \
|
namespace GNULIB_NAMESPACE \
|
||||||
{ \
|
{ \
|
||||||
rettype (*const func) parameters = \
|
static const struct _gl_ ## func ## _wrapper \
|
||||||
reinterpret_cast<rettype(*)parameters>(::rpl_func); \
|
{ \
|
||||||
|
typedef rettype (*type) parameters; \
|
||||||
|
\
|
||||||
|
inline operator type () const \
|
||||||
|
{ \
|
||||||
|
return reinterpret_cast<type>(::rpl_func); \
|
||||||
|
} \
|
||||||
|
} func = {}; \
|
||||||
} \
|
} \
|
||||||
_GL_EXTERN_C int _gl_cxxalias_dummy
|
_GL_EXTERN_C int _gl_cxxalias_dummy
|
||||||
#else
|
#else
|
||||||
|
@ -150,19 +177,24 @@
|
||||||
is defined.
|
is defined.
|
||||||
Example:
|
Example:
|
||||||
_GL_CXXALIAS_SYS (open, int, (const char *filename, int flags, ...));
|
_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 defined __cplusplus && defined GNULIB_NAMESPACE
|
||||||
/* If we were to write
|
# define _GL_CXXALIAS_SYS(func,rettype,parameters) \
|
||||||
rettype (*const func) parameters = ::func;
|
namespace GNULIB_NAMESPACE \
|
||||||
like above in _GL_CXXALIAS_RPL_1, the compiler could optimize calls
|
{ \
|
||||||
better (remove an indirection through a 'static' pointer variable),
|
static const struct _gl_ ## func ## _wrapper \
|
||||||
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. */
|
typedef rettype (*type) parameters; \
|
||||||
# define _GL_CXXALIAS_SYS(func,rettype,parameters) \
|
\
|
||||||
namespace GNULIB_NAMESPACE \
|
inline operator type () const \
|
||||||
{ \
|
{ \
|
||||||
static rettype (*func) parameters = ::func; \
|
return ::func; \
|
||||||
} \
|
} \
|
||||||
|
} func = {}; \
|
||||||
|
} \
|
||||||
_GL_EXTERN_C int _gl_cxxalias_dummy
|
_GL_EXTERN_C int _gl_cxxalias_dummy
|
||||||
#else
|
#else
|
||||||
# define _GL_CXXALIAS_SYS(func,rettype,parameters) \
|
# define _GL_CXXALIAS_SYS(func,rettype,parameters) \
|
||||||
|
@ -178,8 +210,15 @@
|
||||||
# define _GL_CXXALIAS_SYS_CAST(func,rettype,parameters) \
|
# define _GL_CXXALIAS_SYS_CAST(func,rettype,parameters) \
|
||||||
namespace GNULIB_NAMESPACE \
|
namespace GNULIB_NAMESPACE \
|
||||||
{ \
|
{ \
|
||||||
static rettype (*func) parameters = \
|
static const struct _gl_ ## func ## _wrapper \
|
||||||
reinterpret_cast<rettype(*)parameters>(::func); \
|
{ \
|
||||||
|
typedef rettype (*type) parameters; \
|
||||||
|
\
|
||||||
|
inline operator type () const \
|
||||||
|
{ \
|
||||||
|
return reinterpret_cast<type>(::func); \
|
||||||
|
} \
|
||||||
|
} func = {}; \
|
||||||
} \
|
} \
|
||||||
_GL_EXTERN_C int _gl_cxxalias_dummy
|
_GL_EXTERN_C int _gl_cxxalias_dummy
|
||||||
#else
|
#else
|
||||||
|
@ -202,9 +241,15 @@
|
||||||
# define _GL_CXXALIAS_SYS_CAST2(func,rettype,parameters,rettype2,parameters2) \
|
# define _GL_CXXALIAS_SYS_CAST2(func,rettype,parameters,rettype2,parameters2) \
|
||||||
namespace GNULIB_NAMESPACE \
|
namespace GNULIB_NAMESPACE \
|
||||||
{ \
|
{ \
|
||||||
static rettype (*func) parameters = \
|
static const struct _gl_ ## func ## _wrapper \
|
||||||
reinterpret_cast<rettype(*)parameters>( \
|
{ \
|
||||||
(rettype2(*)parameters2)(::func)); \
|
typedef rettype (*type) parameters; \
|
||||||
|
\
|
||||||
|
inline operator type () const \
|
||||||
|
{ \
|
||||||
|
return reinterpret_cast<type>((rettype2 (*) parameters2)(::func)); \
|
||||||
|
} \
|
||||||
|
} func = {}; \
|
||||||
} \
|
} \
|
||||||
_GL_EXTERN_C int _gl_cxxalias_dummy
|
_GL_EXTERN_C int _gl_cxxalias_dummy
|
||||||
#else
|
#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.
|
/* 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
|
This program is free software: you can redistribute it and/or modify it
|
||||||
under the terms of the GNU General Public License as published
|
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'
|
& eval 'exec perl -wST "$0" $argv:q'
|
||||||
if 0;
|
if 0;
|
||||||
# Detect instances of "if (p) free (p);".
|
# Detect instances of "if (p) free (p);".
|
||||||
# Likewise "if (p != 0)", "if (0 != p)", or with NULL; and with braces.
|
# 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
|
# The definition above must lie within the first 8 lines in order
|
||||||
# for the Emacs time-stamp write hook (at end) to update it.
|
# for the Emacs time-stamp write hook (at end) to update it.
|
||||||
# If you change this file with Emacs, please let the write hook
|
# If you change this file with Emacs, please let the write hook
|
||||||
# do its job. Otherwise, update this string manually.
|
# 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
|
# This program is free software: you can redistribute it and/or modify
|
||||||
# it under the terms of the GNU General Public License as published by
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
@ -129,6 +129,9 @@ sub is_NULL ($)
|
||||||
$err = EXIT_ERROR, next;
|
$err = EXIT_ERROR, next;
|
||||||
while (defined (my $line = <FH>))
|
while (defined (my $line = <FH>))
|
||||||
{
|
{
|
||||||
|
# Skip non-matching lines early to save time
|
||||||
|
$line =~ /\bif\b/
|
||||||
|
or next;
|
||||||
while ($line =~
|
while ($line =~
|
||||||
/\b(if\s*\(\s*([^)]+?)(?:\s*!=\s*([^)]+?))?\s*\)
|
/\b(if\s*\(\s*([^)]+?)(?:\s*!=\s*([^)]+?))?\s*\)
|
||||||
# 1 2 3
|
# 1 2 3
|
||||||
|
@ -202,6 +205,6 @@ EOF
|
||||||
## eval: (add-hook 'write-file-hooks 'time-stamp)
|
## eval: (add-hook 'write-file-hooks 'time-stamp)
|
||||||
## time-stamp-start: "my $VERSION = '"
|
## time-stamp-start: "my $VERSION = '"
|
||||||
## time-stamp-format: "%:y-%02m-%02d %02H:%02M"
|
## time-stamp-format: "%:y-%02m-%02d %02H:%02M"
|
||||||
## time-stamp-time-zone: "UTC"
|
## time-stamp-time-zone: "UTC0"
|
||||||
## time-stamp-end: "'; # UTC"
|
## time-stamp-end: "'; # UTC"
|
||||||
## End:
|
## End:
|
||||||
|
|
|
@ -2,9 +2,9 @@
|
||||||
# List version-controlled file names.
|
# List version-controlled file names.
|
||||||
|
|
||||||
# Print a version string.
|
# 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
|
# This program is free software: you can redistribute it and/or modify
|
||||||
# it under the terms of the GNU General Public License as published by
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
@ -108,6 +108,6 @@ done
|
||||||
# eval: (add-hook 'write-file-hooks 'time-stamp)
|
# eval: (add-hook 'write-file-hooks 'time-stamp)
|
||||||
# time-stamp-start: "scriptversion="
|
# time-stamp-start: "scriptversion="
|
||||||
# time-stamp-format: "%:y-%02m-%02d.%02H"
|
# time-stamp-format: "%:y-%02m-%02d.%02H"
|
||||||
# time-stamp-time-zone: "UTC"
|
# time-stamp-time-zone: "UTC0"
|
||||||
# time-stamp-end: "; # UTC"
|
# time-stamp-end: "; # UTC"
|
||||||
# End:
|
# End:
|
||||||
|
|
125
configure.ac
125
configure.ac
|
@ -5,7 +5,7 @@ dnl
|
||||||
define(GUILE_CONFIGURE_COPYRIGHT,[[
|
define(GUILE_CONFIGURE_COPYRIGHT,[[
|
||||||
|
|
||||||
Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
|
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
|
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 (`parallel-tests' is the default in Automake 1.13.)
|
||||||
dnl `serial-tests' was introduced in Automake 1.12.
|
dnl `serial-tests' was introduced in Automake 1.12.
|
||||||
AM_INIT_AUTOMAKE([1.12 gnu no-define -Wall -Wno-override \
|
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)])
|
m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])], [AC_SUBST([AM_DEFAULT_VERBOSITY],1)])
|
||||||
|
|
||||||
AC_COPYRIGHT(GUILE_CONFIGURE_COPYRIGHT)
|
AC_COPYRIGHT(GUILE_CONFIGURE_COPYRIGHT)
|
||||||
|
@ -66,6 +66,18 @@ AC_LIBTOOL_WIN32_DLL
|
||||||
|
|
||||||
AC_PROG_INSTALL
|
AC_PROG_INSTALL
|
||||||
AC_PROG_CC
|
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
|
gl_EARLY
|
||||||
AC_PROG_CPP
|
AC_PROG_CPP
|
||||||
AC_PROG_SED
|
AC_PROG_SED
|
||||||
|
@ -83,7 +95,8 @@ AC_DEFINE([GNULIB_LOCK], [1],
|
||||||
[Define to allow Gnulib modules to use Guile's locks.])
|
[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
|
# for per-target cflags in the libguile subdir
|
||||||
AM_PROG_CC_C_O
|
AM_PROG_CC_C_O
|
||||||
|
@ -313,6 +326,7 @@ AC_SUBST([SCM_I_GSC_T_PTRDIFF])
|
||||||
|
|
||||||
AC_CHECK_HEADERS([stdint.h])
|
AC_CHECK_HEADERS([stdint.h])
|
||||||
AC_CHECK_HEADERS([inttypes.h])
|
AC_CHECK_HEADERS([inttypes.h])
|
||||||
|
AC_CHECK_HEADERS([stdatomic.h])
|
||||||
|
|
||||||
AC_CHECK_SIZEOF(intmax_t)
|
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_STDINT_H])
|
||||||
AC_SUBST([SCM_I_GSC_NEEDS_INTTYPES_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_STDC
|
||||||
AC_HEADER_TIME
|
AC_HEADER_TIME
|
||||||
AC_HEADER_SYS_WAIT
|
AC_HEADER_SYS_WAIT
|
||||||
|
@ -715,7 +741,7 @@ case $host in
|
||||||
AC_CHECK_HEADER(winsock2.h, [AC_DEFINE([HAVE_WINSOCK2_H], 1,
|
AC_CHECK_HEADER(winsock2.h, [AC_DEFINE([HAVE_WINSOCK2_H], 1,
|
||||||
[Define if you have the <winsock2.h> header file.])])
|
[Define if you have the <winsock2.h> header file.])])
|
||||||
AC_CHECK_LIB(ws2_32, main)
|
AC_CHECK_LIB(ws2_32, main)
|
||||||
AC_LIBOBJ([win32-uname])
|
AC_LIBOBJ([posix-w32])
|
||||||
if test "$enable_shared" = yes ; then
|
if test "$enable_shared" = yes ; then
|
||||||
EXTRA_DEFS="-DSCM_IMPORT"
|
EXTRA_DEFS="-DSCM_IMPORT"
|
||||||
AC_DEFINE([USE_DLL_IMPORT], 1,
|
AC_DEFINE([USE_DLL_IMPORT], 1,
|
||||||
|
@ -752,21 +778,22 @@ AC_CHECK_HEADERS([assert.h crt_externs.h])
|
||||||
# isblank - available as a GNU extension or in C99
|
# isblank - available as a GNU extension or in C99
|
||||||
# _NSGetEnviron - Darwin specific
|
# _NSGetEnviron - Darwin specific
|
||||||
# strcoll_l, newlocale, uselocale, utimensat - POSIX.1-2008
|
# strcoll_l, newlocale, uselocale, utimensat - POSIX.1-2008
|
||||||
|
# strtol_l - non-POSIX, found in glibc
|
||||||
# fork - unavailable on Windows
|
# fork - unavailable on Windows
|
||||||
# sched_getaffinity, sched_setaffinity - GNU extensions (glibc)
|
# sched_getaffinity, sched_setaffinity - GNU extensions (glibc)
|
||||||
# sendfile - non-POSIX, found in glibc
|
# sendfile - non-POSIX, found in glibc
|
||||||
#
|
#
|
||||||
AC_CHECK_FUNCS([DINFINITY DQNAN cexp chsize clog clog10 ctermid \
|
AC_CHECK_FUNCS([DINFINITY DQNAN cexp chsize clog clog10 ctermid \
|
||||||
fesetround ftime ftruncate fchown fchmod getcwd geteuid getsid \
|
fesetround ftime ftruncate fchown fchmod getcwd geteuid getsid \
|
||||||
gettimeofday gmtime_r ioctl lstat mkdir mknod nice \
|
gettimeofday getuid getgid gmtime_r ioctl lstat mkdir mknod nice \
|
||||||
readdir_r readdir64_r readlink rename rmdir setegid seteuid \
|
readlink rename rmdir setegid seteuid \
|
||||||
setlocale setpgid setsid sigaction siginterrupt stat64 \
|
setlocale setuid setgid setpgid setsid sigaction siginterrupt stat64 \
|
||||||
strptime symlink sync sysconf tcgetpgrp tcsetpgrp uname waitpid \
|
strptime symlink sync sysconf tcgetpgrp tcsetpgrp uname waitpid \
|
||||||
strdup system usleep atexit on_exit chown link fcntl ttyname getpwent \
|
strdup system usleep atexit on_exit chown link fcntl ttyname getpwent \
|
||||||
getgrent kill getppid getpgrp fork setitimer getitimer strchr strcmp \
|
getgrent kill getppid getpgrp fork setitimer getitimer strchr strcmp \
|
||||||
index bcopy memcpy rindex truncate unsetenv isblank _NSGetEnviron \
|
index bcopy memcpy rindex truncate isblank _NSGetEnviron \
|
||||||
strcoll strcoll_l newlocale uselocale utimensat sched_getaffinity \
|
strcoll strcoll_l strtod_l strtol_l newlocale uselocale utimensat \
|
||||||
sched_setaffinity sendfile])
|
sched_getaffinity sched_setaffinity sendfile])
|
||||||
|
|
||||||
# Reasons for testing:
|
# Reasons for testing:
|
||||||
# netdb.h - not in mingw
|
# netdb.h - not in mingw
|
||||||
|
@ -865,6 +892,57 @@ main (void)
|
||||||
esac
|
esac
|
||||||
fi
|
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
|
AC_CACHE_SAVE
|
||||||
|
|
||||||
dnl GMP tests
|
dnl GMP tests
|
||||||
|
@ -890,6 +968,13 @@ if test "x$LTLIBUNISTRING" = "x"; then
|
||||||
AC_MSG_ERROR([GNU libunistring is required, please install it.])
|
AC_MSG_ERROR([GNU libunistring is required, please install it.])
|
||||||
fi
|
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
|
GUILE_LIBUNISTRING_WITH_ICONV_SUPPORT
|
||||||
if test "x$ac_cv_libunistring_with_iconv_support" != "xyes"; then
|
if test "x$ac_cv_libunistring_with_iconv_support" != "xyes"; then
|
||||||
AC_MSG_ERROR([No iconv support. Please recompile libunistring with iconv enabled.])
|
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.])
|
AC_DEFINE([ENABLE_REGEX], 1, [Define when regex support is enabled.])
|
||||||
fi
|
fi
|
||||||
|
|
||||||
AC_REPLACE_FUNCS([strerror memmove mkstemp])
|
AC_REPLACE_FUNCS([strerror memmove])
|
||||||
|
|
||||||
# Reasons for testing:
|
# Reasons for testing:
|
||||||
# asinh, acosh, atanh, trunc - C99 standard, generally not available on
|
# asinh, acosh, atanh, trunc - C99 standard, generally not available on
|
||||||
# older systems
|
# older systems
|
||||||
# sincos - GLIBC extension
|
# 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.
|
# C99 specifies isinf and isnan as macros.
|
||||||
# HP-UX provides only macros, no functions.
|
# HP-UX provides only macros, no functions.
|
||||||
|
@ -1246,7 +1332,11 @@ main (int argc, char **argv)
|
||||||
# Boehm's GC library
|
# 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"
|
save_LIBS="$LIBS"
|
||||||
LIBS="$BDW_GC_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])
|
AC_CHECK_FUNCS([GC_pthread_exit GC_pthread_cancel GC_pthread_sigmask])
|
||||||
|
|
||||||
# Functions from GC 7.3.
|
# 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"
|
LIBS="$save_LIBS"
|
||||||
|
|
||||||
|
@ -1643,12 +1733,19 @@ AC_CONFIG_FILES([
|
||||||
test-suite/standalone/Makefile
|
test-suite/standalone/Makefile
|
||||||
test-suite/vm/Makefile
|
test-suite/vm/Makefile
|
||||||
meta/Makefile
|
meta/Makefile
|
||||||
|
bootstrap/Makefile
|
||||||
module/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([check-guile])
|
||||||
GUILE_CONFIG_SCRIPT([benchmark-guile])
|
GUILE_CONFIG_SCRIPT([benchmark-guile])
|
||||||
GUILE_CONFIG_SCRIPT([meta/guile])
|
GUILE_CONFIG_SCRIPT([meta/guile])
|
||||||
|
GUILE_CONFIG_SCRIPT([meta/build-env])
|
||||||
GUILE_CONFIG_SCRIPT([meta/uninstalled-env])
|
GUILE_CONFIG_SCRIPT([meta/uninstalled-env])
|
||||||
GUILE_CONFIG_SCRIPT([meta/gdb-uninstalled-guile])
|
GUILE_CONFIG_SCRIPT([meta/gdb-uninstalled-guile])
|
||||||
GUILE_CONFIG_SCRIPT([libguile/guile-snarf])
|
GUILE_CONFIG_SCRIPT([libguile/guile-snarf])
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
<!--#include virtual="/server/header.html" -->
|
<!--#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" -->
|
<!--#include virtual="/server/banner.html" -->
|
||||||
<h2>%%TITLE%%</h2>
|
<h2>%%TITLE%%</h2>
|
||||||
|
|
||||||
|
@ -67,19 +68,22 @@ script</a>.)</p>
|
||||||
</div><!-- for id="content", starts in the include above -->
|
</div><!-- for id="content", starts in the include above -->
|
||||||
<!--#include virtual="/server/footer.html" -->
|
<!--#include virtual="/server/footer.html" -->
|
||||||
<div id="footer">
|
<div id="footer">
|
||||||
|
<div class="unprintable">
|
||||||
|
|
||||||
<p>Please send general FSF & GNU inquiries to
|
<p>Please send general FSF & GNU inquiries to
|
||||||
<a href="mailto:gnu@gnu.org"><gnu@gnu.org></a>.
|
<a href="mailto:gnu@gnu.org"><gnu@gnu.org></a>.
|
||||||
There are also <a href="/contact/">other ways to contact</a>
|
There are also <a href="/contact/">other ways to contact</a>
|
||||||
the FSF.<br />
|
the FSF. Broken links and other corrections or suggestions can be sent
|
||||||
Please send broken links and other corrections or suggestions to
|
to <a href="mailto:%%EMAIL%%"><%%EMAIL%%></a>.</p>
|
||||||
<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
|
<p>This page is licensed under a <a rel="license"
|
||||||
permitted worldwide, without royalty, in any medium, provided this
|
href="http://creativecommons.org/licenses/by-nd/3.0/us/">Creative
|
||||||
notice, and the copyright notice, are preserved.</p>
|
Commons Attribution-NoDerivs 3.0 United States License</a>.</p>
|
||||||
|
|
||||||
|
<!--#include virtual="/server/bottom-notes.html" -->
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</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).
|
Compile source files automatically (default behavior).
|
||||||
.
|
.
|
||||||
.TP
|
.TP
|
||||||
.B --no-autocompile
|
.B --no-auto-compile
|
||||||
Disable automatic source file compilation.
|
Disable automatic source file compilation.
|
||||||
.
|
.
|
||||||
.TP
|
.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 \
|
r6rs.texi \
|
||||||
match.texi \
|
match.texi \
|
||||||
misc-modules.texi \
|
misc-modules.texi \
|
||||||
api-compound.texi \
|
|
||||||
libguile-autoconf.texi \
|
libguile-autoconf.texi \
|
||||||
autoconf-macros.texi \
|
autoconf-macros.texi \
|
||||||
tools.texi \
|
tools.texi \
|
||||||
|
@ -120,7 +119,7 @@ EXTRA_DIST = ChangeLog-2008 $(PICTURES)
|
||||||
|
|
||||||
libguile-autoconf.texi: autoconf-macros.texi
|
libguile-autoconf.texi: autoconf-macros.texi
|
||||||
autoconf-macros.texi: $(top_srcdir)/meta/guile.m4
|
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 \
|
snarf-guile-m4-docs $(top_srcdir)/meta/guile.m4 \
|
||||||
> $(srcdir)/$@
|
> $(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
|
definitions at runtime, building out their program without restarting
|
||||||
it. (You can do this using @code{reload-module}, the @code{reload} REPL
|
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
|
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
|
there are some variables that you @emph{don't} want to redefine all the
|
||||||
time. For these, use @code{define-once}.
|
time. For these, use @code{define-once}.
|
||||||
|
|
||||||
|
@ -301,7 +301,7 @@ following case:
|
||||||
(define a 1)
|
(define a 1)
|
||||||
(define b (+ a a))
|
(define b (+ a a))
|
||||||
(+ a b))
|
(+ a b))
|
||||||
@end lisp
|
@end lisp
|
||||||
|
|
||||||
@noindent
|
@noindent
|
||||||
Guile decided to follow the R6RS in this regard, and now expands
|
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.
|
* Exceptions:: Throwing and catching exceptions.
|
||||||
* Error Reporting:: Procedures for signaling errors.
|
* Error Reporting:: Procedures for signaling errors.
|
||||||
* Dynamic Wind:: Dealing with non-local entrance/exit.
|
* 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.
|
* Handling Errors:: How to handle errors in C code.
|
||||||
* Continuation Barriers:: Protection from non-local control flow.
|
* Continuation Barriers:: Protection from non-local control flow.
|
||||||
@end menu
|
@end menu
|
||||||
|
@ -168,7 +170,7 @@ Each @code{cond}-clause must look like this:
|
||||||
(@var{test} @var{expression} @dots{})
|
(@var{test} @var{expression} @dots{})
|
||||||
@end lisp
|
@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
|
this
|
||||||
|
|
||||||
@lisp
|
@lisp
|
||||||
|
@ -178,7 +180,7 @@ this
|
||||||
where @var{expression} must evaluate to a procedure.
|
where @var{expression} must evaluate to a procedure.
|
||||||
|
|
||||||
The @var{test}s of the clauses are evaluated in order and as soon as one
|
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
|
are evaluated in order and the last value is returned as the value of
|
||||||
the @code{cond}-expression. For the @code{=>} clause type,
|
the @code{cond}-expression. For the @code{=>} clause type,
|
||||||
@var{expression} is evaluated and the resulting procedure is applied to
|
@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
|
One example where this optimization matters is @dfn{escape
|
||||||
continuations}. Escape continuations are delimited continuations whose
|
continuations}. Escape continuations are delimited continuations whose
|
||||||
only use is to make a non-local exit---i.e., to escape from the current
|
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
|
continuation. A common use of escape continuations is when throwing an
|
||||||
reason they are sometimes called @dfn{one-shot continuations}. A common
|
exception (@pxref{Exceptions}).
|
||||||
use of escape continuations is when throwing an exception
|
|
||||||
(@pxref{Exceptions}).
|
|
||||||
|
|
||||||
The constructs below are syntactic sugar atop prompts to simplify the
|
The constructs below are syntactic sugar atop prompts to simplify the
|
||||||
use of escape continuations.
|
use of escape continuations.
|
||||||
|
@ -628,6 +628,33 @@ This is equivalent to
|
||||||
@code{(call/ec (lambda (@var{k}) @var{body} @dots{}))}.
|
@code{(call/ec (lambda (@var{k}) @var{body} @dots{}))}.
|
||||||
@end deffn
|
@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
|
@node Shift and Reset
|
||||||
@subsubsection Shift, Reset, and All That
|
@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}.
|
@var{base}.
|
||||||
|
|
||||||
Currently this creates a list and passes it to @code{scm_values}, but we
|
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.
|
representation.
|
||||||
@end deftypefn
|
@end deftypefn
|
||||||
|
|
||||||
|
@ -1660,6 +1687,339 @@ context is exited, whether normally or non-locally.
|
||||||
@end deftypefn
|
@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
|
@node Handling Errors
|
||||||
@subsection How to Handle 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.
|
describing the type of argument that was expected.
|
||||||
|
|
||||||
In @code{scm_misc_error}, @var{message} is the error message string,
|
In @code{scm_misc_error}, @var{message} is the error message string,
|
||||||
possibly containing @code{simple-format} escapes (@pxref{Writing}), and
|
possibly containing @code{simple-format} escapes (@pxref{Simple
|
||||||
the corresponding arguments in the @var{args} list.
|
Output}), and the corresponding arguments in the @var{args} list.
|
||||||
@end deftypefn
|
@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.
|
@var{frame} is the first frame in its stack.
|
||||||
@end deffn
|
@end deffn
|
||||||
|
|
||||||
@deffn {Scheme Procedure} frame-procedure frame
|
@deffn {Scheme Procedure} frame-procedure-name frame
|
||||||
@deffnx {C Function} scm_frame_procedure (frame)
|
@deffnx {C Function} scm_frame_procedure_name (frame)
|
||||||
Return the procedure for @var{frame}, or @code{#f} if no
|
Return the name of the procedure being applied in @var{frame}, as a
|
||||||
procedure is associated with @var{frame}.
|
symbol, or @code{#f} if the procedure has no name.
|
||||||
@end deffn
|
@end deffn
|
||||||
|
|
||||||
@deffn {Scheme Procedure} frame-arguments frame
|
@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
|
@deffnx {Scheme Procedure} frame-mv-return-address frame
|
||||||
Accessors for the three saved VM registers in a frame: the previous
|
Accessors for the three saved VM registers in a frame: the previous
|
||||||
frame pointer, the single-value return address, and the multiple-value
|
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
|
@end deffn
|
||||||
|
|
||||||
@deffn {Scheme Procedure} frame-num-locals frame
|
@deffn {Scheme Procedure} frame-bindings frame
|
||||||
@deffnx {Scheme Procedure} frame-local-ref frame i
|
Return a list of binding records indicating the local variables that are
|
||||||
@deffnx {Scheme Procedure} frame-local-set! frame i val
|
live in a frame.
|
||||||
Accessors for the temporary values corresponding to @var{frame}'s
|
@end deffn
|
||||||
procedure application. The first local is the first argument given to
|
|
||||||
the procedure. After the arguments, there are the local variables, and
|
@deffn {Scheme Procedure} frame-lookup-binding frame var
|
||||||
after that temporary values. @xref{Stack Layout}, for more information.
|
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
|
@end deffn
|
||||||
|
|
||||||
@deffn {Scheme Procedure} display-application frame [port [indent]]
|
@deffn {Scheme Procedure} display-application frame [port [indent]]
|
||||||
|
@ -1088,11 +1104,6 @@ separately, we discuss them all together here:
|
||||||
@table @code
|
@table @code
|
||||||
@item #:vm
|
@item #:vm
|
||||||
The VM to instrument. Defaults to the current thread's 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
|
@item #:current-frame
|
||||||
For traps that enable more hooks depending on their dynamic context,
|
For traps that enable more hooks depending on their dynamic context,
|
||||||
this argument gives the current frame that the trap is running in.
|
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
|
@end lisp
|
||||||
|
|
||||||
@deffn {Scheme Procedure} trap-at-procedure-call proc handler @
|
@deffn {Scheme Procedure} trap-at-procedure-call proc handler @
|
||||||
[#:vm] [#:closure?]
|
[#:vm]
|
||||||
A trap that calls @var{handler} when @var{proc} is applied.
|
A trap that calls @var{handler} when @var{proc} is applied.
|
||||||
@end deffn
|
@end deffn
|
||||||
|
|
||||||
@deffn {Scheme Procedure} trap-in-procedure proc @
|
@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},
|
A trap that calls @var{enter-handler} when control enters @var{proc},
|
||||||
and @var{exit-handler} when control leaves @var{proc}.
|
and @var{exit-handler} when control leaves @var{proc}.
|
||||||
|
|
||||||
|
@ -1140,13 +1151,13 @@ An abort.
|
||||||
@end deffn
|
@end deffn
|
||||||
|
|
||||||
@deffn {Scheme Procedure} trap-instructions-in-procedure proc @
|
@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
|
A trap that calls @var{next-handler} for every instruction executed in
|
||||||
@var{proc}, and @var{exit-handler} when execution leaves @var{proc}.
|
@var{proc}, and @var{exit-handler} when execution leaves @var{proc}.
|
||||||
@end deffn
|
@end deffn
|
||||||
|
|
||||||
@deffn {Scheme Procedure} trap-at-procedure-ip-in-range proc range @
|
@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
|
A trap that calls @var{handler} when execution enters a range of
|
||||||
instructions in @var{proc}. @var{range} is a simple of pairs,
|
instructions in @var{proc}. @var{range} is a simple of pairs,
|
||||||
@code{((@var{start} . @var{end}) ...)}. The @var{start} addresses are
|
@code{((@var{start} . @var{end}) ...)}. The @var{start} addresses are
|
||||||
|
@ -1169,7 +1180,7 @@ exit.
|
||||||
@end deffn
|
@end deffn
|
||||||
|
|
||||||
@deffn {Scheme Procedure} trap-in-dynamic-extent proc @
|
@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}
|
A more traditional dynamic-wind trap, which fires @var{enter-handler}
|
||||||
when control enters @var{proc}, @var{return-handler} on a normal return,
|
when control enters @var{proc}, @var{return-handler} on a normal return,
|
||||||
and @var{abort-handler} on a nonlocal exit.
|
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
|
@end deffn
|
||||||
|
|
||||||
@deffn {Scheme Procedure} trap-calls-in-dynamic-extent proc @
|
@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,
|
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
|
and @var{return-handler} for returns, but only during the dynamic extent
|
||||||
of an application of @var{proc}.
|
of an application of @var{proc}.
|
||||||
@end deffn
|
@end deffn
|
||||||
|
|
||||||
@deffn {Scheme Procedure} trap-instructions-in-dynamic-extent proc @
|
@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
|
A trap that calls @var{next-handler} for all retired instructions within
|
||||||
the dynamic extent of a call to @var{proc}.
|
the dynamic extent of a call to @var{proc}.
|
||||||
@end deffn
|
@end deffn
|
||||||
|
|
|
@ -22,6 +22,7 @@ loading, evaluating, and compiling Scheme code at run time.
|
||||||
* Delayed Evaluation:: Postponing evaluation until it is needed.
|
* Delayed Evaluation:: Postponing evaluation until it is needed.
|
||||||
* Local Evaluation:: Evaluation in a local lexical environment.
|
* Local Evaluation:: Evaluation in a local lexical environment.
|
||||||
* Local Inclusion:: Compile-time inclusion of one file in another.
|
* Local Inclusion:: Compile-time inclusion of one file in another.
|
||||||
|
* Sandboxed Evaluation:: Evaluation with limited capabilities.
|
||||||
* REPL Servers:: Serving a REPL over a socket.
|
* REPL Servers:: Serving a REPL over a socket.
|
||||||
* Cooperative REPL Servers:: REPL server for single-threaded applications.
|
* Cooperative REPL Servers:: REPL server for single-threaded applications.
|
||||||
@end menu
|
@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,
|
is simply a shorthand for an @code{unquote} form. For example,
|
||||||
|
|
||||||
@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 2 ,(* 9 9) 3 4) @result{} (1 2 81 3 4)
|
||||||
`(1 (unquote (+ 1 1)) 3) @result{} (1 2 3)
|
`(1 (unquote (+ 1 1)) 3) @result{} (1 2 3)
|
||||||
`#(1 ,(/ 12 2)) @result{} #(1 6)
|
`#(1 ,(/ 12 2)) @result{} #(1 6)
|
||||||
|
@ -153,8 +155,9 @@ the returned list inserted. @var{expr} must evaluate to a list. The
|
||||||
|
|
||||||
@example
|
@example
|
||||||
(define x '(2 3))
|
(define x '(2 3))
|
||||||
|
`(1 ,x 4) @result{} (1 (2 3) 4)
|
||||||
`(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)
|
`#(9 ,@@x 9) @result{} #(9 2 3 9)
|
||||||
@end example
|
@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
|
to evaluate an installed file from source, instead of relying on the
|
||||||
@code{.go} file being up to date.
|
@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
|
@node REPL Servers
|
||||||
@subsection REPL Servers
|
@subsection REPL Servers
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
@c -*-texinfo-*-
|
@c -*-texinfo-*-
|
||||||
@c This is part of the GNU Guile Reference Manual.
|
@c This is part of the GNU Guile Reference Manual.
|
||||||
@c Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004, 2007, 2008,
|
@c Copyright (C) 1996, 1997, 2000-2004, 2007-2014, 2016-2017
|
||||||
@c 2009, 2010, 2011, 2012, 2013, 2014 Free Software Foundation, Inc.
|
@c Free Software Foundation, Inc.
|
||||||
@c See the file guile.texi for copying conditions.
|
@c See the file guile.texi for copying conditions.
|
||||||
|
|
||||||
@node Foreign Function Interface
|
@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
|
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
|
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
|
many operating systems that support shared libraries do just that, and
|
||||||
chances are that Guile will allow you to access this feature from within
|
chances are that Guile will allow you to access this feature from within
|
||||||
your Scheme programs. As you might have guessed already, this feature
|
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,
|
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
|
including those exported by the program itself and the shared libraries already
|
||||||
loaded.
|
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
|
@end deffn
|
||||||
|
|
||||||
@deffn {Scheme Procedure} dynamic-object? obj
|
@deffn {Scheme Procedure} dynamic-object? obj
|
||||||
|
@ -488,6 +493,8 @@ platform-dependent size:
|
||||||
@defvrx {Scheme Variable} unsigned-int
|
@defvrx {Scheme Variable} unsigned-int
|
||||||
@defvrx {Scheme Variable} long
|
@defvrx {Scheme Variable} long
|
||||||
@defvrx {Scheme Variable} unsigned-long
|
@defvrx {Scheme Variable} unsigned-long
|
||||||
|
@defvrx {Scheme Variable} short
|
||||||
|
@defvrx {Scheme Variable} unsigned-short
|
||||||
@defvrx {Scheme Variable} size_t
|
@defvrx {Scheme Variable} size_t
|
||||||
@defvrx {Scheme Variable} ssize_t
|
@defvrx {Scheme Variable} ssize_t
|
||||||
@defvrx {Scheme Variable} ptrdiff_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
|
Of course, the land of C is not all nouns and no verbs: there are
|
||||||
functions too, and Guile allows you to call them.
|
functions too, and Guile allows you to call them.
|
||||||
|
|
||||||
@deffn {Scheme Procedure} pointer->procedure return_type func_ptr arg_types
|
@deffn {Scheme Procedure} pointer->procedure return_type func_ptr arg_types @
|
||||||
@deffnx {C Procedure} scm_pointer_to_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.
|
Make a foreign function.
|
||||||
|
|
||||||
Given the foreign void pointer @var{func_ptr}, its argument and
|
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.
|
@var{arg_types} should be a list of foreign types.
|
||||||
@code{return_type} should be a foreign type. @xref{Foreign Types}, for
|
@code{return_type} should be a foreign type. @xref{Foreign Types}, for
|
||||||
more information on foreign types.
|
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
|
@end deffn
|
||||||
|
|
||||||
Here is a better definition of @code{(math bessel)}:
|
Here is a better definition of @code{(math bessel)}:
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
@c -*-texinfo-*-
|
@c -*-texinfo-*-
|
||||||
@c This is part of the GNU Guile Reference Manual.
|
@c This is part of the GNU Guile Reference Manual.
|
||||||
@c Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004, 2006, 2007, 2009, 2010
|
@c Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004, 2006, 2007,
|
||||||
@c Free Software Foundation, Inc.
|
@c 2009, 2010, 2017 Free Software Foundation, Inc.
|
||||||
@c See the file guile.texi for copying conditions.
|
@c See the file guile.texi for copying conditions.
|
||||||
|
|
||||||
@node Internationalization
|
@node Internationalization
|
||||||
|
@ -263,8 +263,10 @@ Reference Manual}).
|
||||||
@deffn {Scheme Procedure} number->locale-string number [fraction-digits [locale]]
|
@deffn {Scheme Procedure} number->locale-string number [fraction-digits [locale]]
|
||||||
Convert @var{number} (an inexact) into a string according to the
|
Convert @var{number} (an inexact) into a string according to the
|
||||||
cultural conventions of either @var{locale} (a locale object) or the
|
cultural conventions of either @var{locale} (a locale object) or the
|
||||||
current locale. Optionally, @var{fraction-digits} may be bound to an
|
current locale. By default, print as many fractional digits as
|
||||||
integer specifying the number of fractional digits to be displayed.
|
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
|
@end deffn
|
||||||
|
|
||||||
@deffn {Scheme Procedure} monetary-amount->locale-string amount intl? [locale]
|
@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
|
may be made very efficiently. See @code{libguile/boolean.h}, for more
|
||||||
information.
|
information.
|
||||||
|
|
||||||
@subsubsection Equality
|
@subsubheading Equality
|
||||||
|
|
||||||
Since Scheme's @code{equal?} must be transitive, and @code{'()}
|
Since Scheme's @code{equal?} must be transitive, and @code{'()}
|
||||||
is not @code{equal?} to @code{#f}, to Scheme @code{nil} is not
|
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:
|
This problem has a mirror-image case in Elisp:
|
||||||
|
|
||||||
@example
|
@example
|
||||||
(deffn my-falsep (x)
|
(defun my-falsep (x)
|
||||||
(if (eq x nil)
|
(if (eq x nil)
|
||||||
t
|
t
|
||||||
nil))
|
nil))
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
@c -*-texinfo-*-
|
@c -*-texinfo-*-
|
||||||
@c This is part of the GNU Guile Reference Manual.
|
@c This is part of the GNU Guile Reference Manual.
|
||||||
@c Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004, 2009, 2010, 2011,
|
@c Copyright (C) 1996, 1997, 2000-2004, 2009-2015
|
||||||
@c 2012, 2013, 2014 Free Software Foundation, Inc.
|
@c Free Software Foundation, Inc.
|
||||||
@c See the file guile.texi for copying conditions.
|
@c See the file guile.texi for copying conditions.
|
||||||
|
|
||||||
@node Macros
|
@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}.
|
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
|
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
|
@end deffn
|
||||||
|
|
||||||
For completeness, we should mention that it is possible to strip the metadata
|
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.
|
@var{x}. @xref{Source Properties}, for more information.
|
||||||
@end deffn
|
@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
|
Guile also offers some more experimental interfaces in a separate
|
||||||
module. As was the case with the Large Hadron Collider, it is unclear
|
module. As was the case with the Large Hadron Collider, it is unclear
|
||||||
to our senior macrologists whether adding these interfaces will result
|
to our senior macrologists whether adding these interfaces will result
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
@c -*-texinfo-*-
|
@c -*-texinfo-*-
|
||||||
@c This is part of the GNU Guile Reference Manual.
|
@c This is part of the GNU Guile Reference Manual.
|
||||||
@c Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004, 2009, 2010, 2012, 2013, 2014
|
@c Copyright (C) 1996, 1997, 2000-2004, 2009, 2010, 2012-2016
|
||||||
@c Free Software Foundation, Inc.
|
@c Free Software Foundation, Inc.
|
||||||
@c See the file guile.texi for copying conditions.
|
@c See the file guile.texi for copying conditions.
|
||||||
|
|
||||||
|
@ -27,24 +27,26 @@ collection relates to using Guile from C.
|
||||||
|
|
||||||
@deffn {Scheme Procedure} gc
|
@deffn {Scheme Procedure} gc
|
||||||
@deffnx {C Function} scm_gc ()
|
@deffnx {C Function} scm_gc ()
|
||||||
Scans all of SCM objects and reclaims for further use those that are
|
Finds all of the ``live'' @code{SCM} objects and reclaims for further
|
||||||
no longer accessible. You normally don't need to call this function
|
use those that are no longer accessible. You normally don't need to
|
||||||
explicitly. It is called automatically when appropriate.
|
call this function explicitly. Its functionality is invoked
|
||||||
|
automatically as needed.
|
||||||
@end deffn
|
@end deffn
|
||||||
|
|
||||||
@deftypefn {C Function} SCM scm_gc_protect_object (SCM @var{obj})
|
@deftypefn {C Function} SCM scm_gc_protect_object (SCM @var{obj})
|
||||||
Protects @var{obj} from being freed by the garbage collector, when it
|
Protects @var{obj} from being freed by the garbage collector, when it
|
||||||
otherwise might be. When you are done with the object, call
|
otherwise might be. When you are done with the object, call
|
||||||
@code{scm_gc_unprotect_object} on the object. Calls to
|
@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
|
the object remains protected until it has been unprotected as many times
|
||||||
as it was protected. It is an error to unprotect an object more times
|
as it was protected. It is an error to unprotect an object more times
|
||||||
than it has been protected. Returns the SCM object it was passed.
|
than it has been protected. Returns the SCM object it was passed.
|
||||||
|
|
||||||
Note that storing @var{obj} in a C global variable has the same
|
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
|
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}
|
visited by the garbage collector in the mark phase; hence,
|
||||||
was the only way in C to prevent a Scheme object from being freed.}.
|
@code{scm_gc_protect_object} was the only way in C to prevent a Scheme
|
||||||
|
object from being freed.}.
|
||||||
@end deftypefn
|
@end deftypefn
|
||||||
|
|
||||||
@deftypefn {C Function} SCM scm_gc_unprotect_object (SCM @var{obj})
|
@deftypefn {C Function} SCM scm_gc_unprotect_object (SCM @var{obj})
|
||||||
|
@ -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
|
allocated with @code{scm_gc_malloc} @emph{had} to be freed with
|
||||||
@code{scm_gc_free}.}.
|
@code{scm_gc_free}.}.
|
||||||
|
|
||||||
Memory allocated with @code{scm_gc_malloc} is scanned for live pointers.
|
When garbage collection occurs, Guile will visit the words in memory
|
||||||
This means that if @code{scm_gc_malloc}-allocated memory contains a
|
allocated with @code{scm_gc_malloc}, looking for live pointers. This
|
||||||
pointer to some other part of the memory, the garbage collector notices
|
means that if @code{scm_gc_malloc}-allocated memory contains a pointer
|
||||||
it and prevents it from being reclaimed@footnote{In Guile up to 1.8,
|
to some other part of the memory, the garbage collector notices it and
|
||||||
memory allocated with @code{scm_gc_malloc} was @emph{not} scanned.
|
prevents it from being reclaimed@footnote{In Guile up to 1.8, memory
|
||||||
Consequently, the GC had to be told explicitly about pointers to live
|
allocated with @code{scm_gc_malloc} was @emph{not} visited by the
|
||||||
objects contained in the memory block, e.g., @i{via} SMOB mark functions
|
collector in the mark phase. Consequently, the GC had to be told
|
||||||
(@pxref{Smobs, @code{scm_set_smob_mark}})}. Conversely, memory
|
explicitly about pointers to live objects contained in the memory block,
|
||||||
allocated with @code{scm_gc_malloc_pointerless} is assumed to be
|
e.g., @i{via} SMOB mark functions (@pxref{Smobs,
|
||||||
``pointer-less'' and is not scanned.
|
@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
|
For memory that is not associated with a Scheme object, you can use
|
||||||
@code{scm_malloc} instead of @code{malloc}. Like
|
@code{scm_malloc} instead of @code{malloc}. Like
|
||||||
|
@ -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
|
is automatically freed when no longer referenced from any live memory
|
||||||
block.
|
block.
|
||||||
|
|
||||||
Memory allocated with @code{scm_gc_malloc} or @code{scm_gc_calloc} is
|
When garbage collection occurs, Guile will visit the words in memory
|
||||||
scanned for pointers. Memory allocated by
|
allocated with @code{scm_gc_malloc} or @code{scm_gc_calloc}, looking for
|
||||||
@code{scm_gc_malloc_pointerless} is not scanned.
|
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
|
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
|
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
|
hash table, choosing a good size for the table requires some
|
||||||
caution.
|
caution.
|
||||||
|
|
||||||
You can modify weak hash tables in exactly the same way you
|
You can modify weak hash tables in exactly the same way you would modify
|
||||||
would modify regular hash tables. (@pxref{Hash Tables})
|
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
|
@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
|
@deffn {Scheme Procedure} weak-key-hash-table? obj
|
||||||
@deffnx {Scheme Procedure} weak-value-hash-table? obj
|
@deffnx {Scheme Procedure} weak-value-hash-table? obj
|
||||||
@deffnx {Scheme Procedure} doubly-weak-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.
|
debugging, for example.
|
||||||
|
|
||||||
Note that just as with a @code{use-modules} statement, any module that
|
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
|
has not yet been loaded will be loaded when referenced by a @code{@@} or
|
||||||
@code{@@} or @code{@@@@} form.
|
@code{@@@@} form.
|
||||||
|
|
||||||
You can also use the @code{@@} and @code{@@@@} syntaxes as the target
|
You can also use the @code{@@} and @code{@@@@} syntaxes as the target
|
||||||
of a @code{set!} when the binding refers to a variable.
|
of a @code{set!} when the binding refers to a variable.
|
||||||
|
|
|
@ -241,7 +241,7 @@ procedures (@pxref{Arrays}).
|
||||||
|
|
||||||
@item char-ready?
|
@item char-ready?
|
||||||
Indicates that the @code{char-ready?} function is available
|
Indicates that the @code{char-ready?} function is available
|
||||||
(@pxref{Reading}).
|
(@pxref{Venerable Port Interfaces}).
|
||||||
|
|
||||||
@item complex
|
@item complex
|
||||||
Indicates support for complex numbers.
|
Indicates support for complex numbers.
|
||||||
|
@ -284,8 +284,11 @@ Indicates support for POSIX functions: @code{pipe}, @code{getgroups},
|
||||||
|
|
||||||
@item fork
|
@item fork
|
||||||
Indicates support for the POSIX @code{fork} function (@pxref{Processes,
|
Indicates support for the POSIX @code{fork} function (@pxref{Processes,
|
||||||
@code{primitive-fork}}). This is a prerequisite for the @code{(ice-9
|
@code{primitive-fork}}).
|
||||||
popen)} module (@pxref{Pipes}).
|
|
||||||
|
@item popen
|
||||||
|
Indicates support for @code{open-pipe} in the @code{(ice-9 popen)}
|
||||||
|
module (@pxref{Pipes}).
|
||||||
|
|
||||||
@item random
|
@item random
|
||||||
Indicates availability of random number generation functions:
|
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!))
|
(define foo (make-procedure-with-setter foo-ref foo-set!))
|
||||||
@end lisp
|
@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.
|
structure stored in @code{f}, or to write into the structure.
|
||||||
|
|
||||||
@lisp
|
@lisp
|
||||||
|
|
|
@ -14,10 +14,7 @@
|
||||||
|
|
||||||
A @dfn{regular expression} (or @dfn{regexp}) is a pattern that
|
A @dfn{regular expression} (or @dfn{regexp}) is a pattern that
|
||||||
describes a whole class of strings. A full description of regular
|
describes a whole class of strings. A full description of regular
|
||||||
expressions and their syntax is beyond the scope of this manual;
|
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.
|
|
||||||
|
|
||||||
If your system does not include a POSIX regular expression library,
|
If your system does not include a POSIX regular expression library,
|
||||||
and you have not linked Guile with a third-party regexp library such
|
and you have not linked Guile with a third-party regexp library such
|
||||||
|
@ -41,10 +38,11 @@ regex))}.
|
||||||
@node Regexp Functions
|
@node Regexp Functions
|
||||||
@subsection Regexp Functions
|
@subsection Regexp Functions
|
||||||
|
|
||||||
By default, Guile supports POSIX extended regular expressions.
|
By default, Guile supports POSIX extended regular expressions. That
|
||||||
That means that the characters @samp{(}, @samp{)}, @samp{+} and
|
means that the characters @samp{(}, @samp{)}, @samp{+} and @samp{?} are
|
||||||
@samp{?} are special, and must be escaped if you wish to match the
|
special, and must be escaped if you wish to match the literal characters
|
||||||
literal characters.
|
and there is no support for ``non-greedy'' variants of @samp{*},
|
||||||
|
@samp{+} or @samp{?}.
|
||||||
|
|
||||||
This regular expression interface was modeled after that
|
This regular expression interface was modeled after that
|
||||||
implemented by SCSH, the Scheme Shell. It is intended to be
|
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
|
@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
|
@node C Hooks
|
||||||
@subsubsection Hooks For C Code.
|
@subsubsection Hooks For C Code.
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
@c -*-texinfo-*-
|
@c -*-texinfo-*-
|
||||||
@c This is part of the GNU Guile Reference Manual.
|
@c This is part of the GNU Guile Reference Manual.
|
||||||
@c Copyright (C) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015
|
@c Copyright (C) 2008-2016
|
||||||
@c Free Software Foundation, Inc.
|
@c Free Software Foundation, Inc.
|
||||||
@c See the file guile.texi for copying conditions.
|
@c See the file guile.texi for copying conditions.
|
||||||
|
|
||||||
|
@ -363,7 +363,7 @@ Sets a variable in the current procedure's module.
|
||||||
@end deftp
|
@end deftp
|
||||||
|
|
||||||
@deftp {Scheme Variable} <toplevel-define> src name exp
|
@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.
|
Defines a new top-level variable in the current procedure's module.
|
||||||
@end deftp
|
@end deftp
|
||||||
|
|
||||||
|
@ -513,12 +513,8 @@ Optimization passes performed on Tree-IL currently include:
|
||||||
and calls to primitives to primcalls)
|
and calls to primitives to primcalls)
|
||||||
@item Partial evaluation (comprising inlining, copy propagation, and
|
@item Partial evaluation (comprising inlining, copy propagation, and
|
||||||
constant folding)
|
constant folding)
|
||||||
@item Common subexpression elimination (CSE)
|
|
||||||
@end itemize
|
@end itemize
|
||||||
|
|
||||||
In the future, we will move the CSE pass to operate over the lower-level
|
|
||||||
CPS language.
|
|
||||||
|
|
||||||
@node Continuation-Passing Style
|
@node Continuation-Passing Style
|
||||||
@subsection Continuation-Passing Style
|
@subsection Continuation-Passing Style
|
||||||
|
|
||||||
|
@ -534,6 +530,7 @@ compiler.
|
||||||
* An Introduction to CPS::
|
* An Introduction to CPS::
|
||||||
* CPS in Guile::
|
* CPS in Guile::
|
||||||
* Building CPS::
|
* Building CPS::
|
||||||
|
* CPS Soup::
|
||||||
* Compiling CPS::
|
* Compiling CPS::
|
||||||
@end menu
|
@end menu
|
||||||
|
|
||||||
|
@ -624,12 +621,57 @@ details manifest, and gives them names.
|
||||||
@node CPS in Guile
|
@node CPS in Guile
|
||||||
@subsubsection CPS in Guile
|
@subsubsection CPS in Guile
|
||||||
|
|
||||||
Guile's CPS language is composed of @dfn{terms}, @dfn{expressions},
|
@cindex continuation, CPS
|
||||||
and @dfn{continuations}.
|
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
|
@cindex term, CPS
|
||||||
to some continuation, or it can declare local continuations and contain
|
@cindex expression, CPS
|
||||||
a sub-term in the scope of those continuations.
|
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
|
@deftp {CPS Term} $continue k src exp
|
||||||
Evaluate the expression @var{exp} and pass the resulting values (if any)
|
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.
|
source.
|
||||||
@end deftp
|
@end deftp
|
||||||
|
|
||||||
@deftp {CPS Term} $letk conts body
|
There are a number of expression kinds. Above you see an example of
|
||||||
Bind @var{conts}, a list of continuations (@code{$cont} instances), in
|
@code{$primcall}.
|
||||||
the scope of the sub-term @var{body}. The continuations are mutually
|
|
||||||
recursive.
|
@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
|
@end deftp
|
||||||
|
|
||||||
Additionally, the early stages of CPS allow for a set of mutually
|
@cindex dominate, CPS
|
||||||
recursive functions to be declared as a term. This @code{$letrec} type
|
The variables that are used by @code{$primcall}, or indeed by any
|
||||||
is like Tree-IL's @code{<fix>}. The contification pass will attempt to
|
expression, must be defined before the expression is evaluated. An
|
||||||
transform the functions declared in a @code{$letrec} into local
|
equivalent way of saying this is that predecessor @code{$kargs}
|
||||||
continuations. Any remaining functions are later lowered to @code{$fun}
|
continuation(s) that bind the variables(s) used by the expression must
|
||||||
expressions.
|
@dfn{dominate} the continuation that uses the expression: definitions
|
||||||
|
dominate uses. This condition is trivially satisfied in our example
|
||||||
@deftp {CPS Term} $letrec names syms funs body
|
above, but in general to determine the set of variables that are in
|
||||||
Declare the mutually recursive set of functions denoted by @var{names},
|
``scope'' for a given term, you need to do a flow analysis to see what
|
||||||
@var{syms}, and @var{funs} within the sub-term @var{body}. @var{names}
|
continuations dominate a term. The variables that are in scope are
|
||||||
and @var{syms} are lists of symbols, and @var{funs} is a list of
|
those variables defined by the continuations that dominate a term.
|
||||||
@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
|
|
||||||
|
|
||||||
Here is an inventory of the kinds of expressions in Guile's CPS
|
Here is an inventory of the kinds of expressions in Guile's CPS
|
||||||
language. Recall that all expressions are wrapped in a @code{$continue}
|
language, besides @code{$primcall} which has already been described.
|
||||||
term which specifies their continuation.
|
Recall that all expressions are wrapped in a @code{$continue} term which
|
||||||
|
specifies their continuation.
|
||||||
|
|
||||||
@deftp {CPS Expression} $const val
|
@deftp {CPS Expression} $const val
|
||||||
Continue with the constant value @var{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}.
|
named by @var{name}.
|
||||||
@end deftp
|
@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
|
@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
|
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
|
the continuation. @var{proc} and the elements of the @var{args} list
|
||||||
should all be variable names. The continuation identified by the term's
|
should all be variable names. The continuation identified by the term's
|
||||||
@var{k} should be a @code{$kreceive} or a @code{$ktail} instance.
|
@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
|
@end deftp
|
||||||
|
|
||||||
@deftp {CPS Expression} $values args
|
@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
|
@deftp {CPS Expression} $branch kt exp
|
||||||
Evaluate the branching expression @var{exp}, and continue to @var{kt}
|
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
|
Only certain expressions are valid in a @var{$branch}. Compiling a
|
||||||
@code{$branch} avoids allocating space for the test variable, so the
|
@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{=},
|
this condition is true for @code{$primcall}s to @code{null?}, @code{=},
|
||||||
and similar primitives that have corresponding @code{br-if-@var{foo}} VM
|
and similar primitives that have corresponding @code{br-if-@var{foo}} VM
|
||||||
operations; see the source code for full details. When in doubt, bind
|
operations; see the source code for full details. When in doubt, bind
|
||||||
the test expression to a variable, and reference the variable in the
|
the test expression to a variable, and branch on a @code{$values}
|
||||||
@code{$branch} expression. The optimizer should inline the reference if
|
expression that references that variable. The optimizer should inline
|
||||||
possible.
|
the reference if possible.
|
||||||
@end deftp
|
@end deftp
|
||||||
|
|
||||||
@deftp {CPS Expression} $prompt escape? tag handler
|
@deftp {CPS Expression} $prompt escape? tag handler
|
||||||
|
@ -758,30 +754,73 @@ the continuation labelled @var{handler}, which should be a
|
||||||
@code{pop-prompt} primcalls.
|
@code{pop-prompt} primcalls.
|
||||||
@end deftp
|
@end deftp
|
||||||
|
|
||||||
The remaining element of the CPS language in Guile is the continuation.
|
@cindex higher-order CPS
|
||||||
In CPS, all continuations have unique labels. Since this aspect is
|
@cindex CPS, higher-order
|
||||||
common to all continuation types, all continuations are contained in a
|
@cindex first-order CPS
|
||||||
@code{$cont} instance:
|
@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
|
@deftp {CPS Expression} $fun body
|
||||||
Declare a continuation labelled @var{k}. All references to the
|
Continue with a procedure. @var{body} names the entry point of the
|
||||||
continuation will use this label.
|
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
|
@end deftp
|
||||||
|
|
||||||
The most common kind of continuation binds some number of values, and
|
@deftp {CPS Expression} $rec names vars funs
|
||||||
then evaluates a sub-term. @code{$kargs} is this kind of simple
|
Continue with a set of mutually recursive procedures denoted by
|
||||||
@code{lambda}.
|
@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
|
||||||
@deftp {CPS Continuation} $kargs names syms body
|
@var{funs} is a list of @code{$fun} values. Note that the @code{$kargs}
|
||||||
Bind the incoming values to the variables @var{syms}, with original
|
continuation should also define @var{names}/@var{vars} bindings.
|
||||||
names @var{names}, and then evaluate the sub-term @var{body}.
|
|
||||||
@end deftp
|
@end deftp
|
||||||
|
|
||||||
Variable names (the names in the @var{syms} of a @code{$kargs}) should
|
The contification pass will attempt to transform the functions declared
|
||||||
be unique among all other variable names. To bind a value to a variable
|
in a @code{$rec} into local continuations. Any remaining @code{$fun}
|
||||||
and then evaluate some term, you would continue with the value to a
|
instances are later removed by the closure conversion pass. By default,
|
||||||
@code{$kargs} that declares one variable. The bound value would then be
|
a closure is represented as an object built by a @code{$closure}
|
||||||
available for use within the body of the @code{$kargs}.
|
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
|
@deftp {CPS Continuation} $kreceive arity k
|
||||||
Receive values on the stack. Parse them according to @var{arity}, and
|
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.
|
@var{kw} list are source names, not unique variable names.
|
||||||
@end deftp
|
@end deftp
|
||||||
|
|
||||||
Additionally, there are three specific kinds of continuations that can
|
Additionally, there are three specific kinds of continuations that are
|
||||||
only be declared at function entries.
|
only used in function entries.
|
||||||
|
|
||||||
@deftp {CPS Continuation} $kfun src meta self tail clauses
|
@deftp {CPS Continuation} $kfun src meta self tail clauses
|
||||||
Declare a function entry. @var{src} is the source information for the
|
Declare a function entry. @var{src} is the source information for the
|
||||||
procedure declaration, and @var{meta} is the metadata alist as described
|
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
|
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.
|
the procedure being called, and which may be used for self-references.
|
||||||
@var{tail} declares the @code{$cont} wrapping the @code{$ktail} for this
|
@var{tail} is the label of the @code{$ktail} for this function,
|
||||||
function, corresponding to the function's tail continuation.
|
corresponding to the function's tail continuation. @var{clause} is the
|
||||||
@var{clause} is the first @code{$kclause} @code{$cont} instance for the
|
label of the first @code{$kclause} for the first @code{case-lambda}
|
||||||
first @code{case-lambda} clause in the function, or otherwise @code{#f}.
|
clause in the function, or otherwise @code{#f}.
|
||||||
@end deftp
|
@end deftp
|
||||||
|
|
||||||
@deftp {CPS Continuation} $ktail
|
@deftp {CPS Continuation} $ktail
|
||||||
|
@ -826,10 +865,10 @@ A tail continuation.
|
||||||
|
|
||||||
@deftp {CPS Continuation} $kclause arity cont alternate
|
@deftp {CPS Continuation} $kclause arity cont alternate
|
||||||
A clause of a function with a given arity. Applications of a function
|
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
|
with a compatible set of actual arguments will continue to the
|
||||||
@code{$kargs} @code{$cont} instance representing the clause body. If
|
continuation labelled @var{cont}, a @code{$kargs} instance representing
|
||||||
the arguments are incompatible, control proceeds to @var{alternate},
|
the clause body. If the arguments are incompatible, control proceeds to
|
||||||
which is a @code{$kclause} @code{$cont} for the next clause, or
|
@var{alternate}, which is a @code{$kclause} for the next clause, or
|
||||||
@code{#f} if there is no next clause.
|
@code{#f} if there is no next clause.
|
||||||
@end deftp
|
@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}
|
Deconstruction and matching is handled adequately by the @code{match}
|
||||||
form from @code{(ice-9 match)}. @xref{Pattern Matching}. Construction
|
form from @code{(ice-9 match)}. @xref{Pattern Matching}. Construction
|
||||||
is handled by a set of mutually recursive builder macros:
|
is handled by a set of mutually builder macros:
|
||||||
@code{build-cps-term}, @code{build-cps-cont}, and @code{build-cps-exp}.
|
@code{build-term}, @code{build-cont}, and @code{build-exp}.
|
||||||
|
|
||||||
In the following interface definitions, consider variables containing
|
In the following interface definitions, consider @code{term} and
|
||||||
@code{cont} to be recursively build by @code{build-cps-cont}, and
|
@code{exp} to be built by @code{build-term} or @code{build-exp},
|
||||||
likewise for @code{term} and @code{exp}. Consider any other name to be
|
respectively. Consider any other name to be evaluated as a Scheme
|
||||||
evaluated as a Scheme expression. Many of these forms recognize
|
expression. Many of these forms recognize @code{unquote} in some
|
||||||
@code{unquote} in some contexts, to splice in a previously-built value;
|
contexts, to splice in a previously-built value; see the specifications
|
||||||
see the specifications below for full details.
|
below for full details.
|
||||||
|
|
||||||
@deffn {Scheme Syntax} build-cps-term ,val
|
@deffn {Scheme Syntax} build-term ,val
|
||||||
@deffnx {Scheme Syntax} build-cps-term ($letk (cont ...) term)
|
@deffnx {Scheme Syntax} build-term ($continue k src exp)
|
||||||
@deffnx {Scheme Syntax} build-cps-term ($letrec names syms funs term)
|
@deffnx {Scheme Syntax} build-exp ,val
|
||||||
@deffnx {Scheme Syntax} build-cps-term ($continue k src exp)
|
@deffnx {Scheme Syntax} build-exp ($const val)
|
||||||
@deffnx {Scheme Syntax} build-cps-term ($program conts)
|
@deffnx {Scheme Syntax} build-exp ($prim name)
|
||||||
@deffnx {Scheme Syntax} build-cps-exp ,val
|
@deffnx {Scheme Syntax} build-exp ($branch kt exp)
|
||||||
@deffnx {Scheme Syntax} build-cps-exp ($const val)
|
@deffnx {Scheme Syntax} build-exp ($fun kentry)
|
||||||
@deffnx {Scheme Syntax} build-cps-exp ($prim name)
|
@deffnx {Scheme Syntax} build-exp ($rec names syms funs)
|
||||||
@deffnx {Scheme Syntax} build-cps-exp ($fun src meta free body)
|
@deffnx {Scheme Syntax} build-exp ($closure k nfree)
|
||||||
@deffnx {Scheme Syntax} build-cps-exp ($call proc (arg ...))
|
@deffnx {Scheme Syntax} build-exp ($call proc (arg ...))
|
||||||
@deffnx {Scheme Syntax} build-cps-exp ($call proc args)
|
@deffnx {Scheme Syntax} build-exp ($call proc args)
|
||||||
@deffnx {Scheme Syntax} build-cps-exp ($primcall name (arg ...))
|
@deffnx {Scheme Syntax} build-exp ($callk k proc (arg ...))
|
||||||
@deffnx {Scheme Syntax} build-cps-exp ($primcall name args)
|
@deffnx {Scheme Syntax} build-exp ($callk k proc args)
|
||||||
@deffnx {Scheme Syntax} build-cps-exp ($values (arg ...))
|
@deffnx {Scheme Syntax} build-exp ($primcall name (arg ...))
|
||||||
@deffnx {Scheme Syntax} build-cps-exp ($values args)
|
@deffnx {Scheme Syntax} build-exp ($primcall name args)
|
||||||
@deffnx {Scheme Syntax} build-cps-exp ($prompt escape? tag handler)
|
@deffnx {Scheme Syntax} build-exp ($values (arg ...))
|
||||||
@deffnx {Scheme Syntax} build-cps-cont ,val
|
@deffnx {Scheme Syntax} build-exp ($values args)
|
||||||
@deffnx {Scheme Syntax} build-cps-cont (k ($kargs (name ...) (sym ...) term))
|
@deffnx {Scheme Syntax} build-exp ($prompt escape? tag handler)
|
||||||
@deffnx {Scheme Syntax} build-cps-cont (k ($kargs names syms term))
|
@deffnx {Scheme Syntax} build-cont ,val
|
||||||
@deffnx {Scheme Syntax} build-cps-cont (k ($kif kt kf))
|
@deffnx {Scheme Syntax} build-cont ($kargs (name ...) (sym ...) term)
|
||||||
@deffnx {Scheme Syntax} build-cps-cont (k ($kreceive req rest kargs))
|
@deffnx {Scheme Syntax} build-cont ($kargs names syms term)
|
||||||
@deffnx {Scheme Syntax} build-cps-cont (k ($kentry self tail-cont ,clauses))
|
@deffnx {Scheme Syntax} build-cont ($kreceive req rest kargs)
|
||||||
@deffnx {Scheme Syntax} build-cps-cont (k ($kentry self tail-cont (cont ...)))
|
@deffnx {Scheme Syntax} build-cont ($kfun src meta self ktail kclause)
|
||||||
@deffnx {Scheme Syntax} build-cps-cont (k ($kclause ,arity cont))
|
@deffnx {Scheme Syntax} build-cont ($kclause ,arity kbody kalt)
|
||||||
@deffnx {Scheme Syntax} build-cps-cont (k ($kclause (req opt rest kw aok?) cont))
|
@deffnx {Scheme Syntax} build-cont ($kclause (req opt rest kw aok?) kbody)
|
||||||
Construct a CPS term, expression, or continuation.
|
Construct a CPS term, expression, or continuation.
|
||||||
@end deffn
|
@end deffn
|
||||||
|
|
||||||
|
@ -886,19 +925,187 @@ There are a few more miscellaneous interfaces as well.
|
||||||
A procedural constructor for @code{$arity} objects.
|
A procedural constructor for @code{$arity} objects.
|
||||||
@end deffn
|
@end deffn
|
||||||
|
|
||||||
@deffn {Scheme Syntax} let-gensyms (sym ...) body ...
|
@deffn {Scheme Syntax} rewrite-term val (pat term) ...
|
||||||
Bind @var{sym...} to fresh names, and evaluate @var{body...}.
|
@deffnx {Scheme Syntax} rewrite-exp val (pat exp) ...
|
||||||
@end deffn
|
@deffnx {Scheme Syntax} rewrite-cont val (pat cont) ...
|
||||||
|
|
||||||
@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) ...
|
|
||||||
Match @var{val} against the series of patterns @var{pat...}, using
|
Match @var{val} against the series of patterns @var{pat...}, using
|
||||||
@code{match}. The body of the matching clause should be a template in
|
@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
|
the syntax of @code{build-term}, @code{build-exp}, or @code{build-cont},
|
||||||
@code{build-cps-cont}, respectively.
|
respectively.
|
||||||
@end deffn
|
@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
|
@node Compiling CPS
|
||||||
@subsubsection 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
|
converted to being boxed values on the heap. @xref{Variables and the
|
||||||
VM}.
|
VM}.
|
||||||
|
|
||||||
After CPS conversion, Guile runs some optimization passes. The major
|
After CPS conversion, Guile runs some optimization passes over the CPS.
|
||||||
optimization performed on CPS is contification, in which functions that
|
Most optimization in Guile is done on the CPS language. The one major
|
||||||
are always called with the same continuation are incorporated directly
|
exception is partial evaluation, which for historic reasons is done on
|
||||||
into a function's body. This opens up space for more optimizations, and
|
Tree-IL.
|
||||||
turns procedure calls into @code{goto}. It can also make loops out of
|
|
||||||
recursive function nests.
|
|
||||||
|
|
||||||
At the time of this writing (2014), most high-level optimization in
|
The major optimization performed on CPS is contification, in which
|
||||||
Guile is done on Tree-IL. We would like to rewrite many of these passes
|
functions that are always called with the same continuation are
|
||||||
to operate on CPS instead, as it is easier to reason about CPS.
|
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
|
The rest of the optimization passes are really cleanups and
|
||||||
canonicalizations. CPS spans the gap between high-level languages and
|
canonicalizations. CPS spans the gap between high-level languages and
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
@c -*-texinfo-*-
|
@c -*-texinfo-*-
|
||||||
@c This is part of the GNU Guile Reference Manual.
|
@c This is part of the GNU Guile Reference Manual.
|
||||||
@c Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004, 2010
|
@c Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004, 2010, 2015
|
||||||
@c Free Software Foundation, Inc.
|
@c Free Software Foundation, Inc.
|
||||||
@c See the file guile.texi for copying conditions.
|
@c See the file guile.texi for copying conditions.
|
||||||
|
|
||||||
|
@ -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
|
problem. The alternative, an explicitly maintained list of local
|
||||||
variable addresses, is effectively much less reliable, due to programmer
|
variable addresses, is effectively much less reliable, due to programmer
|
||||||
error. Interested readers should see the BDW-GC web page at
|
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.
|
information.
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
@c -*-texinfo-*-
|
@c -*-texinfo-*-
|
||||||
@c This is part of the GNU Guile Reference Manual.
|
@c This is part of the GNU Guile Reference Manual.
|
||||||
@c Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004, 2005, 2010, 2011, 2013, 2014
|
@c Copyright (C) 1996, 1997, 2000-2005, 2010, 2011, 2013, 2014,
|
||||||
@c Free Software Foundation, Inc.
|
@c 2016 Free Software Foundation, Inc.
|
||||||
@c See the file guile.texi for copying conditions.
|
@c See the file guile.texi for copying conditions.
|
||||||
|
|
||||||
@node Invoking Guile
|
@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
|
@var{module-name} @var{symbol})}, and in that case, the symbol is
|
||||||
looked up in the module named @var{module-name}.
|
looked up in the module named @var{module-name}.
|
||||||
|
|
||||||
For compatibility with some versions of Guile 1.4, you can also use the
|
As a shorthand you can use the form @code{(symbol ...)}, that is, a list
|
||||||
form @code{(symbol ...)} (that is, a list of only symbols that doesn't
|
of only symbols that doesn't start with @code{@@}. It is equivalent to
|
||||||
start with @code{@@}), which is equivalent to @code{(@@ (symbol ...)
|
@code{(@@ @var{module-name} main)}, where @var{module-name} is
|
||||||
main)}, or @code{(symbol ...) symbol} (that is, a list of only symbols
|
@code{(symbol ...)} form. @xref{Using Guile Modules} and @ref{Scripting
|
||||||
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
|
|
||||||
Examples}.
|
Examples}.
|
||||||
|
|
||||||
@item -ds
|
@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
|
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
|
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
|
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
|
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
|
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
|
Guile prompt. Alternately you can fire up Emacs and connect to the
|
||||||
process; see @ref{Using Guile in Emacs} for more details.
|
process; see @ref{Using Guile in Emacs} for more details.
|
||||||
|
|
||||||
Note that opening a port allows anyone who can connect to that port---in
|
@quotation Note
|
||||||
the TCP case, any local user---to do anything Guile can do, as the user
|
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
|
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
|
multi-user machines. Of course, if you do not pass @option{--listen} to
|
||||||
Guile, no port will be opened.
|
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
|
That said, @option{--listen} is great for interactive debugging and
|
||||||
development.
|
development.
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
This manual documents Guile version @value{VERSION}.
|
This manual documents Guile version @value{VERSION}.
|
||||||
|
|
||||||
Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004, 2005, 2009,
|
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
|
Permission is granted to copy, distribute and/or modify this document
|
||||||
under the terms of the GNU Free Documentation License, Version 1.3 or
|
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.
|
* The SCM Type:: The fundamental data type for C code.
|
||||||
* Initialization:: Initializing Guile.
|
* Initialization:: Initializing Guile.
|
||||||
* Snarfing Macros:: Macros for snarfing initialization actions.
|
* Snarfing Macros:: Macros for snarfing initialization actions.
|
||||||
* Simple Data Types:: Numbers, strings, booleans and so on.
|
* Data Types:: Representing values in Guile.
|
||||||
* Compound Data Types:: Data types for holding other data.
|
|
||||||
* Foreign Objects:: Defining new data types in C.
|
* Foreign Objects:: Defining new data types in C.
|
||||||
* Smobs:: Use foreign objects instead.
|
* Smobs:: Use foreign objects instead.
|
||||||
* Procedures:: Procedures.
|
* Procedures:: Procedures.
|
||||||
|
@ -328,7 +327,6 @@ available through both Scheme and C interfaces.
|
||||||
@include api-init.texi
|
@include api-init.texi
|
||||||
@include api-snarf.texi
|
@include api-snarf.texi
|
||||||
@include api-data.texi
|
@include api-data.texi
|
||||||
@include api-compound.texi
|
|
||||||
@include api-foreign-objects.texi
|
@include api-foreign-objects.texi
|
||||||
@include api-smobs.texi
|
@include api-smobs.texi
|
||||||
@include api-procedures.texi
|
@include api-procedures.texi
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
@c -*-texinfo-*-
|
@c -*-texinfo-*-
|
||||||
@c This is part of the GNU Guile Reference Manual.
|
@c This is part of the GNU Guile Reference Manual.
|
||||||
@c Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004, 2005, 2010,
|
@c Copyright (C) 1996-1997, 2000-2005, 2010-2011, 2013-2016
|
||||||
@c 2011, 2013, 2014 Free Software Foundation, Inc.
|
@c Free Software Foundation, Inc.
|
||||||
@c See the file guile.texi for copying conditions.
|
@c See the file guile.texi for copying conditions.
|
||||||
|
|
||||||
@node General Libguile Concepts
|
@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}
|
stacks, and values in machine registers. Other references to @code{SCM}
|
||||||
objects, such as those in other random data structures in the C heap
|
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
|
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
|
@code{scm_permanent_object}. Collectively, these values form the ``root
|
||||||
set'' of garbage collection; any value on the heap that is referenced
|
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
|
directly or indirectly by a member of the root set is preserved, and all
|
||||||
other objects are eligible for reclamation.
|
other objects are eligible for reclamation.
|
||||||
|
|
||||||
The Scheme stack and heap are scanned precisely; that is to say, Guile
|
In Guile, garbage collection has two logical phases: the @dfn{mark
|
||||||
knows about all inter-object pointers on the Scheme stack and heap.
|
phase}, in which the collector discovers the set of all live objects,
|
||||||
This is not the case, unfortunately, for pointers on the C stack and
|
and the @dfn{sweep phase}, in which the collector reclaims the resources
|
||||||
static data segment. For this reason we have to scan the C stack and
|
associated with dead objects. The mark phase pauses the program and
|
||||||
static data segment @dfn{conservatively}; any value that looks like a
|
traces all @code{SCM} object references, starting with the root set.
|
||||||
pointer to a GC-managed object is treated as such, whether it actually
|
The sweep phase actually runs concurrently with the main program,
|
||||||
is a reference or not. Thus, scanning the C stack and static data
|
incrementally reclaiming memory as needed by allocation.
|
||||||
segment is guaranteed to find all actual references, but it might also
|
|
||||||
find words that only accidentally look like references. These ``false
|
In the mark phase, the garbage collector traces the Scheme stack and
|
||||||
positives'' might keep @code{SCM} objects alive that would otherwise be
|
heap @dfn{precisely}. Because the Scheme stack and heap are managed by
|
||||||
considered dead. While this might waste memory, keeping an object
|
Guile, Guile can know precisely where in those data structures it might
|
||||||
around longer than it strictly needs to is harmless. This is why this
|
find references to other heap objects. This is not the case,
|
||||||
technique is called ``conservative garbage collection''. In practice,
|
unfortunately, for pointers on the C stack and static data segment.
|
||||||
the wasted memory seems to be no problem, as the static C root set is
|
Instead of requiring the user to inform Guile about all variables in C
|
||||||
almost always finite and small, given that the Scheme stack is separate
|
that might point to heap objects, Guile traces the C stack and static
|
||||||
from the C stack.
|
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 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
|
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,
|
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
|
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
|
Since signal handling in Guile relies on safe points, you need to make
|
||||||
sure that your functions do offer enough of them. Normally, calling
|
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
|
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
|
for threads, the finalizer may be called from any thread that is running
|
||||||
Guile. In Guile 2.0, finalizers are invoked via ``asyncs'', which
|
Guile. In Guile 2.0, finalizers are invoked via ``asyncs'', which
|
||||||
interleaves them with running Scheme code; @pxref{System asyncs}. In
|
interleaves them with running Scheme code; @pxref{Asyncs}. In Guile 2.2
|
||||||
Guile 2.2 there will be a dedicated finalization thread, to ensure that
|
there will be a dedicated finalization thread, to ensure that the
|
||||||
the finalization doesn't run within the critical section of any other
|
finalization doesn't run within the critical section of any other thread
|
||||||
thread known to Guile.
|
known to Guile.
|
||||||
|
|
||||||
In either case, finalizers run concurrently with the main program, and
|
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
|
so they need to be async-safe and thread-safe. If for some reason this
|
||||||
|
|
|
@ -47,7 +47,7 @@ follows,
|
||||||
@table @asis
|
@table @asis
|
||||||
@item @nicode{#:display?} @var{flag}
|
@item @nicode{#:display?} @var{flag}
|
||||||
If @var{flag} is true then print using @code{display}. The default is
|
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}
|
@item @nicode{#:per-line-prefix} @var{string}
|
||||||
Print the given @var{string} as a prefix on each line. The default is
|
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}
|
@item @nicode{#:width} @var{columns}
|
||||||
Print within the given @var{columns}. The default is 79.
|
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 table
|
||||||
@end deffn
|
@end deffn
|
||||||
|
|
||||||
|
@ -106,7 +109,7 @@ follows,
|
||||||
@table @asis
|
@table @asis
|
||||||
@item @nicode{#:display?} @var{flag}
|
@item @nicode{#:display?} @var{flag}
|
||||||
If @var{flag} is true then print using @code{display}. The default is
|
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}
|
@item @nicode{#:width} @var{columns}
|
||||||
Print within the given @var{columns}. The default is 79.
|
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}.
|
@var{minpad}, @var{padchar}.
|
||||||
|
|
||||||
@nicode{~a} outputs an argument like @code{display}, @nicode{~s}
|
@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
|
@example
|
||||||
(format #t "~a" "foo") @print{} foo
|
(format #t "~a" "foo") @print{} foo
|
||||||
|
@ -242,9 +245,9 @@ no minimum or multiple).
|
||||||
Character. Parameter: @var{charnum}.
|
Character. Parameter: @var{charnum}.
|
||||||
|
|
||||||
Output a character. The default is to simply output, as per
|
Output a character. The default is to simply output, as per
|
||||||
@code{write-char} (@pxref{Writing}). @nicode{~@@c} prints in
|
@code{write-char} (@pxref{Venerable Port Interfaces}). @nicode{~@@c}
|
||||||
@code{write} style. @nicode{~:c} prints control characters (ASCII 0
|
prints in @code{write} style. @nicode{~:c} prints control characters
|
||||||
to 31) in @nicode{^X} form.
|
(ASCII 0 to 31) in @nicode{^X} form.
|
||||||
|
|
||||||
@example
|
@example
|
||||||
(format #t "~c" #\z) @print{} z
|
(format #t "~c" #\z) @print{} z
|
||||||
|
@ -760,8 +763,9 @@ already so.
|
||||||
(format #f "a~3,5'*@@tx") @result{} "a****x"
|
(format #f "a~3,5'*@@tx") @result{} "a****x"
|
||||||
@end example
|
@end example
|
||||||
|
|
||||||
@nicode{~t} is implemented using @code{port-column} (@pxref{Reading}),
|
@nicode{~t} is implemented using @code{port-column} (@pxref{Textual
|
||||||
so it works even there has been other output before @code{format}.
|
I/O}), so it works even there has been other output before
|
||||||
|
@code{format}.
|
||||||
|
|
||||||
@item @nicode{~~}
|
@item @nicode{~~}
|
||||||
Tilde character. Parameter: @var{n}.
|
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.
|
Force output. No parameters.
|
||||||
|
|
||||||
At the end of output, call @code{force-output} to flush any buffers on
|
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.
|
the format string, but the force is done at the end of output.
|
||||||
|
|
||||||
When output is to a string (destination @code{#f}), @nicode{~!} does
|
When output is to a string (destination @code{#f}), @nicode{~!} does
|
||||||
|
@ -1112,10 +1116,10 @@ originating format, or similar.
|
||||||
@sp 1
|
@sp 1
|
||||||
Guile contains a @code{format} procedure even when the module
|
Guile contains a @code{format} procedure even when the module
|
||||||
@code{(ice-9 format)} is not loaded. The default @code{format} is
|
@code{(ice-9 format)} is not loaded. The default @code{format} is
|
||||||
@code{simple-format} (@pxref{Writing}), it doesn't support all escape
|
@code{simple-format} (@pxref{Simple Output}), it doesn't support all
|
||||||
sequences documented in this section, and will signal an error if you
|
escape sequences documented in this section, and will signal an error if
|
||||||
try to use one of them. The reason for two versions is that the full
|
you try to use one of them. The reason for two versions is that the
|
||||||
@code{format} is fairly large and requires some time to load.
|
full @code{format} is fairly large and requires some time to load.
|
||||||
@code{simple-format} is often adequate too.
|
@code{simple-format} is often adequate too.
|
||||||
|
|
||||||
|
|
||||||
|
@ -1661,10 +1665,10 @@ returned.
|
||||||
@end deffn
|
@end deffn
|
||||||
|
|
||||||
@deffn {Scheme Procedure} port->stream port readproc
|
@deffn {Scheme Procedure} port->stream port readproc
|
||||||
Return a stream which is the values obtained by reading from
|
Return a stream which is the values obtained by reading from @var{port}
|
||||||
@var{port} using @var{readproc}. Each read call is
|
using @var{readproc}. Each read call is @code{(@var{readproc}
|
||||||
@code{(@var{readproc} @var{port})}, and it should return an EOF object
|
@var{port})}, and it should return an EOF object (@pxref{Binary I/O}) at
|
||||||
(@pxref{Reading}) at the end of input.
|
the end of input.
|
||||||
|
|
||||||
For example a stream of characters from a file,
|
For example a stream of characters from a file,
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,12 @@
|
||||||
@node getopt-long
|
@node getopt-long
|
||||||
@section The (ice-9 getopt-long) Module
|
@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:
|
The @code{(ice-9 getopt-long)} module exports two procedures:
|
||||||
@code{getopt-long} and @code{option-ref}.
|
@code{getopt-long} and @code{option-ref}.
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
@c -*-texinfo-*-
|
@c -*-texinfo-*-
|
||||||
@c This is part of the GNU Guile Reference Manual.
|
@c This is part of the GNU Guile Reference Manual.
|
||||||
@c Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004, 2006, 2007,
|
@c Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004, 2006, 2007,
|
||||||
@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.
|
@c See the file guile.texi for copying conditions.
|
||||||
|
|
||||||
@node POSIX
|
@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)}.
|
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.
|
Each open file port has an associated operating system file descriptor.
|
||||||
File descriptors are generally not useful in Scheme programs; however
|
File descriptors are generally not useful in Scheme programs; however
|
||||||
they may be needed when interfacing with foreign code and the Unix
|
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
|
ports will not result in its garbage collection: it could be retrieved
|
||||||
with @code{fdopen} or @code{fdes->ports}.
|
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
|
@deffn {Scheme Procedure} port-revealed port
|
||||||
@deffnx {C Function} scm_port_revealed (port)
|
@deffnx {C Function} scm_port_revealed (port)
|
||||||
Return the revealed count for @var{port}.
|
Return the revealed count for @var{port}.
|
||||||
|
@ -299,7 +303,7 @@ a port.
|
||||||
|
|
||||||
@deffn {Scheme Procedure} close fd_or_port
|
@deffn {Scheme Procedure} close fd_or_port
|
||||||
@deffnx {C Function} scm_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
|
but also works on file descriptors. A side
|
||||||
effect of closing a file descriptor is that any ports using that file
|
effect of closing a file descriptor is that any ports using that file
|
||||||
descriptor are moved to a different file descriptor and have
|
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.
|
return value is unspecified.
|
||||||
@end deffn
|
@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
|
@deffn {Scheme Procedure} pipe
|
||||||
@deffnx {C Function} scm_pipe ()
|
@deffnx {C Function} scm_pipe ()
|
||||||
@cindex pipe
|
@cindex pipe
|
||||||
Return a newly created pipe: a pair of ports which are linked
|
Return a newly created pipe: a pair of ports which are linked together
|
||||||
together on the local machine. The @acronym{CAR} is the input
|
on the local machine. The @acronym{CAR} is the input port and the
|
||||||
port and the @acronym{CDR} is the output port. Data written (and
|
@acronym{CDR} is the output port. Data written (and flushed) to the
|
||||||
flushed) to the output port can be read from the input port.
|
output port can be read from the input port. Pipes are commonly used
|
||||||
Pipes are commonly used for communication with a newly forked
|
for communication with a newly forked child process. The need to flush
|
||||||
child process. The need to flush the output port can be
|
the output port can be avoided by making it unbuffered using
|
||||||
avoided by making it unbuffered using @code{setvbuf}.
|
@code{setvbuf} (@pxref{Buffering}).
|
||||||
|
|
||||||
@defvar PIPE_BUF
|
@defvar PIPE_BUF
|
||||||
A write of up to @code{PIPE_BUF} many bytes to a pipe is atomic,
|
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.
|
The return value is unspecified.
|
||||||
@end deffn
|
@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
|
@deffn {Scheme Procedure} port-for-each proc
|
||||||
@deffnx {C Function} scm_port_for_each (SCM proc)
|
@deffnx {C Function} scm_port_for_each (SCM proc)
|
||||||
@deffnx {C Function} scm_c_port_for_each (void (*proc)(void *, SCM), void *data)
|
@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.
|
cookie.
|
||||||
@end deffn
|
@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]
|
@deffn {Scheme Procedure} fcntl port/fd cmd [value]
|
||||||
@deffnx {C Function} scm_fcntl (object, cmd, value)
|
@deffnx {C Function} scm_fcntl (object, cmd, value)
|
||||||
Apply @var{cmd} on @var{port/fd}, either a port or file descriptor.
|
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
|
exceptional conditions on a collection of ports or file
|
||||||
descriptors, or waiting for a timeout to occur.
|
descriptors, or waiting for a timeout to occur.
|
||||||
|
|
||||||
When an error occurs, of if it is interrupted by a signal, this
|
When an error occurs, this procedure throws a @code{system-error}
|
||||||
procedure throws a @code{system-error} exception
|
exception (@pxref{Conventions, @code{system-error}}). Note that
|
||||||
(@pxref{Conventions, @code{system-error}}). In case of an
|
@code{select} may return early for other reasons, for example due to
|
||||||
interruption, the associated error number is @var{EINTR}.
|
pending interrupts. @xref{Asyncs}, for more on interrupts.
|
||||||
|
|
||||||
@var{reads}, @var{writes} and @var{excepts} can be lists or
|
@var{reads}, @var{writes} and @var{excepts} can be lists or
|
||||||
vectors, with each member a port or a file descriptor.
|
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.
|
An additional @code{select!} interface is provided.
|
||||||
@end deffn
|
@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
|
@node File System
|
||||||
@subsection File System
|
@subsection File System
|
||||||
@cindex 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]
|
@deffn {Scheme Procedure} mkdir path [mode]
|
||||||
@deffnx {C Function} scm_mkdir (path, mode)
|
@deffnx {C Function} scm_mkdir (path, mode)
|
||||||
Create a new directory named by @var{path}. If @var{mode} is omitted
|
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
|
then the permissions of the directory are set to @code{#o777}
|
||||||
umask (@pxref{Processes}). Otherwise they are set to the decimal
|
masked with the current umask (@pxref{Processes, @code{umask}}).
|
||||||
value specified with @var{mode}. The return value is unspecified.
|
Otherwise they are set to the value specified with @var{mode}.
|
||||||
|
The return value is unspecified.
|
||||||
@end deffn
|
@end deffn
|
||||||
|
|
||||||
@deffn {Scheme Procedure} rmdir path
|
@deffn {Scheme Procedure} rmdir path
|
||||||
|
@ -966,7 +973,7 @@ another name if the file exists (error @code{EEXIST}).
|
||||||
@code{mkstemp!} below does that.
|
@code{mkstemp!} below does that.
|
||||||
@end deffn
|
@end deffn
|
||||||
|
|
||||||
@deffn {Scheme Procedure} mkstemp! tmpl
|
@deffn {Scheme Procedure} mkstemp! tmpl [mode]
|
||||||
@deffnx {C Function} scm_mkstemp (tmpl)
|
@deffnx {C Function} scm_mkstemp (tmpl)
|
||||||
@cindex temporary file
|
@cindex temporary file
|
||||||
Create a new unique file in the file system and return a new buffered
|
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))))
|
(chmod port (logand #o666 (lognot (umask))))
|
||||||
...)
|
...)
|
||||||
@end example
|
@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
|
@end deffn
|
||||||
|
|
||||||
@deffn {Scheme Procedure} tmpfile
|
@deffn {Scheme Procedure} tmpfile
|
||||||
|
@ -1966,29 +1977,8 @@ Currently this procedure is only defined on GNU variants
|
||||||
GNU C Library Reference Manual}).
|
GNU C Library Reference Manual}).
|
||||||
@end deffn
|
@end deffn
|
||||||
|
|
||||||
@deffn {Scheme Procedure} total-processor-count
|
@xref{Threads}, for information on how get the number of processors
|
||||||
@deffnx {C Function} scm_total_processor_count ()
|
available on a system.
|
||||||
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
|
|
||||||
|
|
||||||
|
|
||||||
@node Signals
|
@node Signals
|
||||||
|
@ -1997,11 +1987,11 @@ information.
|
||||||
|
|
||||||
The following procedures raise, handle and wait for signals.
|
The following procedures raise, handle and wait for signals.
|
||||||
|
|
||||||
Scheme code signal handlers are run via a system async (@pxref{System
|
Scheme code signal handlers are run via an async (@pxref{Asyncs}), so
|
||||||
asyncs}), so they're called in the handler's thread at the next safe
|
they're called in the handler's thread at the next safe opportunity.
|
||||||
opportunity. Generally this is after any currently executing
|
Generally this is after any currently executing primitive procedure
|
||||||
primitive procedure finishes (which could be a long time for
|
finishes (which could be a long time for primitives that wait for an
|
||||||
primitives that wait for an external event).
|
external event).
|
||||||
|
|
||||||
@deffn {Scheme Procedure} kill pid sig
|
@deffn {Scheme Procedure} kill pid sig
|
||||||
@deffnx {C Function} scm_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).
|
from that call).
|
||||||
@end defvar
|
@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
|
The return value is a pair with information about the old handler as
|
||||||
described above.
|
described above.
|
||||||
|
|
||||||
|
@ -2156,12 +2162,12 @@ expiry will be signalled.
|
||||||
A real-time timer, counting down elapsed real time. At zero it raises
|
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
|
@code{SIGALRM}. This is like @code{alarm} above, but with a higher
|
||||||
resolution period.
|
resolution period.
|
||||||
@end defvar
|
@end defvar
|
||||||
|
|
||||||
@defvar ITIMER_VIRTUAL
|
@defvar ITIMER_VIRTUAL
|
||||||
A virtual-time timer, counting down while the current process is
|
A virtual-time timer, counting down while the current process is
|
||||||
actually using CPU. At zero it raises @code{SIGVTALRM}.
|
actually using CPU. At zero it raises @code{SIGVTALRM}.
|
||||||
@end defvar
|
@end defvar
|
||||||
|
|
||||||
@defvar ITIMER_PROF
|
@defvar ITIMER_PROF
|
||||||
A profiling timer, counting down while the process is running (like
|
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
|
This timer is intended for profiling where a program is spending its
|
||||||
time (by looking where it is when the timer goes off).
|
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,
|
@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
|
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
|
Although the timers are programmed in microseconds, the actual
|
||||||
accuracy might not be that high.
|
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
|
@end deffn
|
||||||
|
|
||||||
|
|
||||||
|
@ -2249,7 +2262,7 @@ controlling terminal. The return value is unspecified.
|
||||||
The following procedures are similar to the @code{popen} and
|
The following procedures are similar to the @code{popen} and
|
||||||
@code{pclose} system routines. The code is in a separate ``popen''
|
@code{pclose} system routines. The code is in a separate ``popen''
|
||||||
module@footnote{This module is only available on systems where the
|
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
|
@lisp
|
||||||
(use-modules (ice-9 popen))
|
(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
|
standard input is inherited from @code{current-input-port}. For an
|
||||||
output pipe, the child's standard input is the pipe and standard
|
output pipe, the child's standard input is the pipe and standard
|
||||||
output is inherited from @code{current-output-port}. In all cases
|
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}).
|
@code{current-error-port} (@pxref{Default Ports}).
|
||||||
|
|
||||||
If those @code{current-X-ports} are not files of some kind, and hence
|
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.
|
used instead.
|
||||||
|
|
||||||
Care should be taken with @code{OPEN_BOTH}, a deadlock will occur if
|
Care should be taken with @code{OPEN_BOTH}, a deadlock will occur if
|
||||||
both parent and child are writing, and waiting until the write
|
both parent and child are writing, and waiting until the write completes
|
||||||
completes before doing any reading. Each direction has
|
before doing any reading. Each direction has @code{PIPE_BUF} bytes of
|
||||||
@code{PIPE_BUF} bytes of buffering (@pxref{Ports and File
|
buffering (@pxref{Buffering}), which will be enough for small writes,
|
||||||
Descriptors}), which will be enough for small writes, but not for say
|
but not for say putting a big file through a filter.
|
||||||
putting a big file through a filter.
|
|
||||||
@end deffn
|
@end deffn
|
||||||
|
|
||||||
@deffn {Scheme Procedure} open-input-pipe command
|
@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
|
it can reap a pipe's child process, causing an error from a subsequent
|
||||||
@code{close-pipe}.
|
@code{close-pipe}.
|
||||||
|
|
||||||
@code{close-port} (@pxref{Closing}) can close a pipe, but it doesn't
|
@code{close-port} (@pxref{Ports}) can close a pipe, but it doesn't reap
|
||||||
reap the child process.
|
the child process.
|
||||||
|
|
||||||
The garbage collector will close a pipe no longer in use, and reap the
|
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
|
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}.
|
Socket ports can be created using @code{socket} and @code{socketpair}.
|
||||||
The ports are initially unbuffered, to make reading and writing to the
|
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
|
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
|
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
|
it's strongly recommended that socket ports be closed explicitly when
|
||||||
|
@ -3191,6 +3203,15 @@ supporting that.
|
||||||
@end defvar
|
@end defvar
|
||||||
@end deffn
|
@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
|
@deffn {Scheme Procedure} shutdown sock how
|
||||||
@deffnx {C Function} scm_shutdown (sock, how)
|
@deffnx {C Function} scm_shutdown (sock, how)
|
||||||
Sockets can be closed simply by using @code{close-port}. The
|
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_INET6 ipv6addr port [flowinfo [scopeid]]
|
||||||
@deffnx {Scheme Procedure} connect sock AF_UNIX path
|
@deffnx {Scheme Procedure} connect sock AF_UNIX path
|
||||||
@deffnx {C Function} scm_connect (sock, fam, address, args)
|
@deffnx {C Function} scm_connect (sock, fam, address, args)
|
||||||
Initiate a connection on socket port @var{sock} to a given address.
|
Initiate a connection on socket port @var{sock} to a given address. The
|
||||||
The destination is either a socket address object, or arguments the
|
destination is either a socket address object, or arguments the same as
|
||||||
same as @code{make-socket-address} would take to make such an object
|
@code{make-socket-address} would take to make such an object
|
||||||
(@pxref{Network Socket Address}). The return value is unspecified.
|
(@pxref{Network Socket Address}). Return true unless the socket was
|
||||||
|
configured as non-blocking and the connection could not be made
|
||||||
|
immediately.
|
||||||
|
|
||||||
@example
|
@example
|
||||||
(connect sock AF_INET INADDR_LOOPBACK 23)
|
(connect sock AF_INET INADDR_LOOPBACK 23)
|
||||||
|
@ -3261,18 +3284,33 @@ the queue.
|
||||||
The return value is unspecified.
|
The return value is unspecified.
|
||||||
@end deffn
|
@end deffn
|
||||||
|
|
||||||
@deffn {Scheme Procedure} accept sock
|
@deffn {Scheme Procedure} accept sock [flags]
|
||||||
@deffnx {C Function} scm_accept (sock)
|
@deffnx {C Function} scm_accept (sock)
|
||||||
Accept a connection from socket port @var{sock} which has been enabled
|
Accept a connection from socket port @var{sock} which has been enabled
|
||||||
for listening with @code{listen} above. If there are no incoming
|
for listening with @code{listen} above.
|
||||||
connections in the queue, wait until one is available (unless
|
|
||||||
@code{O_NONBLOCK} has been set on the socket, @pxref{Ports and File
|
If there are no incoming connections in the queue, there are two
|
||||||
Descriptors,@code{fcntl}}).
|
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,
|
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
|
connected and ready to communicate. The @code{cdr} is a socket address
|
||||||
address object (@pxref{Network Socket Address}) which is where the
|
object (@pxref{Network Socket Address}) which is where the remote
|
||||||
remote connection is from (like @code{getpeername} below).
|
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
|
All communication takes place using the new socket returned. The
|
||||||
given @var{sock} remains bound and listening, and @code{accept} may be
|
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.
|
ongoing to fix this.
|
||||||
|
|
||||||
@item
|
@item
|
||||||
Guile does not prevent use of textual I/O procedures on binary ports.
|
Guile does not prevent use of textual I/O procedures on binary ports, or
|
||||||
More generally, it does not make a sharp distinction between binary and
|
vice versa. All ports in Guile support both binary and textual I/O.
|
||||||
textual ports (@pxref{R6RS Port Manipulation, binary-port?}).
|
@xref{Encoding}, for full details.
|
||||||
|
|
||||||
@item
|
@item
|
||||||
Guile's implementation of @code{equal?} may fail to terminate when
|
Guile's implementation of @code{equal?} may fail to terminate when
|
||||||
|
@ -147,8 +147,10 @@ Language Scheme}).
|
||||||
* rnrs exceptions:: Handling exceptional situations.
|
* rnrs exceptions:: Handling exceptional situations.
|
||||||
* rnrs conditions:: Data structures for exceptions.
|
* 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.
|
* rnrs io ports:: Support for port-based I/O.
|
||||||
|
* R6RS File Ports:: Working with files.
|
||||||
* rnrs io simple:: High-level I/O API.
|
* rnrs io simple:: High-level I/O API.
|
||||||
|
|
||||||
* rnrs files:: Functions for working with files.
|
* 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}.
|
@xref{SRFI-1 Filtering and Partitioning}, for @code{partition}.
|
||||||
@end deffn
|
@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{}
|
@deffn {Scheme Procedure} fold-left combine nil list1 list2 @dots{}
|
||||||
@deffnx {Scheme Procedure} fold-right combine nil list1 list2 @dots{}
|
This procedure is like @code{fold} from SRFI-1, but @var{combine} is
|
||||||
These procedures are identical to the @code{fold} and @code{fold-right}
|
called with the seed as the first argument. @xref{SRFI-1 Fold and Map},
|
||||||
procedures provided by SRFI-1. @xref{SRFI-1 Fold and Map}, for
|
for documentation.
|
||||||
documentation.
|
|
||||||
@end deffn
|
@end deffn
|
||||||
|
|
||||||
@deffn {Scheme Procedure} remp proc list
|
@deffn {Scheme Procedure} remp proc list
|
||||||
|
@ -1343,7 +1349,7 @@ A subtype of @code{&violation} that indicates a reference to an unbound
|
||||||
identifier.
|
identifier.
|
||||||
@end deffn
|
@end deffn
|
||||||
|
|
||||||
@node I/O Conditions
|
@node R6RS I/O Conditions
|
||||||
@subsubsection I/O Conditions
|
@subsubsection I/O Conditions
|
||||||
|
|
||||||
These condition types are exported by both the
|
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}.
|
the port @var{port}.
|
||||||
@end deffn
|
@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
|
@node rnrs io ports
|
||||||
@subsubsection rnrs io ports
|
@subsubsection rnrs io ports
|
||||||
|
|
||||||
The @code{(rnrs io ports (6))} library provides various procedures and
|
@cindex R6RS
|
||||||
syntactic forms for use in writing to and reading from ports. This
|
@cindex R6RS ports
|
||||||
functionality is documented in its own section of the manual;
|
Guile's binary and textual port interface was heavily inspired by R6RS,
|
||||||
(@pxref{R6RS I/O Ports}).
|
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
|
@node rnrs io simple
|
||||||
@subsubsection rnrs io simple
|
@subsubsection rnrs io simple
|
||||||
|
|
||||||
The @code{(rnrs io simple (6))} library provides convenience functions
|
The @code{(rnrs io simple (6))} library provides convenience functions
|
||||||
for performing textual I/O on ports. This library also exports all of
|
for performing textual I/O on ports. This library also exports all of
|
||||||
the condition types and associated procedures described in (@pxref{I/O
|
the condition types and associated procedures described in (@pxref{R6RS
|
||||||
Conditions}). In the context of this section, when stating that a
|
I/O Conditions}). In the context of this section, when stating that a
|
||||||
procedure behaves ``identically'' to the corresponding procedure in
|
procedure behaves ``identically'' to the corresponding procedure in
|
||||||
Guile's core library, this is modulo the behavior wrt. conditions: such
|
Guile's core library, this is modulo the behavior wrt. conditions: such
|
||||||
procedures raise the appropriate R6RS conditions in case of error, but
|
procedures raise the appropriate R6RS conditions in case of error, but
|
||||||
|
@ -1451,9 +1984,8 @@ appropriate R6RS conditions.
|
||||||
|
|
||||||
@deffn {Scheme Procedure} eof-object
|
@deffn {Scheme Procedure} eof-object
|
||||||
@deffnx {Scheme Procedure} eof-object? obj
|
@deffnx {Scheme Procedure} eof-object? obj
|
||||||
These procedures are identical to the ones provided by the
|
These procedures are identical to the ones provided by the @code{(rnrs
|
||||||
@code{(rnrs io ports (6))} library. @xref{R6RS I/O Ports}, for
|
io ports (6))} library. @xref{rnrs io ports}, for documentation.
|
||||||
documentation.
|
|
||||||
@end deffn
|
@end deffn
|
||||||
|
|
||||||
@deffn {Scheme Procedure} input-port? obj
|
@deffn {Scheme Procedure} input-port? obj
|
||||||
|
@ -1474,8 +2006,8 @@ library. @xref{File Ports}, for documentation.
|
||||||
|
|
||||||
@deffn {Scheme Procedure} close-input-port input-port
|
@deffn {Scheme Procedure} close-input-port input-port
|
||||||
@deffnx {Scheme Procedure} close-output-port output-port
|
@deffnx {Scheme Procedure} close-output-port output-port
|
||||||
These procedures are identical to the ones provided by Guile's core
|
Closes the given @var{input-port} or @var{output-port}. These are
|
||||||
library. @xref{Closing}, for documentation.
|
legacy interfaces; just use @code{close-port}.
|
||||||
@end deffn
|
@end deffn
|
||||||
|
|
||||||
@deffn {Scheme Procedure} peek-char
|
@deffn {Scheme Procedure} peek-char
|
||||||
|
@ -1483,7 +2015,7 @@ library. @xref{Closing}, for documentation.
|
||||||
@deffnx {Scheme Procedure} read-char
|
@deffnx {Scheme Procedure} read-char
|
||||||
@deffnx {Scheme Procedure} read-char textual-input-port
|
@deffnx {Scheme Procedure} read-char textual-input-port
|
||||||
These procedures are identical to the ones provided by Guile's core
|
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
|
@end deffn
|
||||||
|
|
||||||
@deffn {Scheme Procedure} read
|
@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 obj textual-output-port
|
||||||
@deffnx {Scheme Procedure} write-char char
|
@deffnx {Scheme Procedure} write-char char
|
||||||
@deffnx {Scheme Procedure} write-char char textual-output-port
|
@deffnx {Scheme Procedure} write-char char textual-output-port
|
||||||
These procedures are identical to the ones provided by Guile's core
|
These procedures are identical to the ones provided by Guile's core
|
||||||
library. @xref{Writing}, for documentation.
|
library. @xref{Venerable Port Interfaces}, and @xref{Scheme Write}, for
|
||||||
|
documentation.
|
||||||
@end deffn
|
@end deffn
|
||||||
|
|
||||||
@node rnrs files
|
@node rnrs files
|
||||||
|
|
|
@ -108,6 +108,8 @@ history-file yes Use history file.
|
||||||
history-length 200 History length.
|
history-length 200 History length.
|
||||||
bounce-parens 500 Time (ms) to show matching opening parenthesis
|
bounce-parens 500 Time (ms) to show matching opening parenthesis
|
||||||
(0 = off).
|
(0 = off).
|
||||||
|
bracketed-paste yes Disable interpretation of control characters
|
||||||
|
in pastes.
|
||||||
@end smalllisp
|
@end smalllisp
|
||||||
|
|
||||||
The readline options interface can only be used @emph{after} loading
|
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
|
(It could be argued that the alternative @code{define} forms are rather
|
||||||
confusing, especially for newcomers to the Scheme language, as they hide
|
confusing, especially for newcomers to the Scheme language, as they hide
|
||||||
both the role of @code{lambda} and the fact that procedures are values
|
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
|
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
|
example of another of Scheme's powerful features: the ability to specify
|
||||||
arbitrary syntactic transformations at run time, which can be applied to
|
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
|
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
|
series of reports known as @dfn{RnRS}. @dfn{RnRS} is shorthand for the
|
||||||
@iftex
|
@iftex
|
||||||
@dfn{Revised$^n$ Report on the Algorithmic Language Scheme}.
|
@dfn{Revised@math{^n} Report on the Algorithmic Language Scheme}.
|
||||||
@end iftex
|
@end iftex
|
||||||
@ifnottex
|
@ifnottex
|
||||||
@dfn{Revised^n Report on the Algorithmic Language Scheme}.
|
@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
|
Load the file @file{/u/jimb/ex4}, and then call the function
|
||||||
@code{main}, passing it the list @code{("/u/jimb/ex4" "foo")}.
|
@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
|
@item guile -l first -ds -l last -s script
|
||||||
Load the files @file{first}, @file{script}, and @file{last}, in that
|
Load the files @file{first}, @file{script}, and @file{last}, in that
|
||||||
order. The @code{-ds} switch says when to process the @code{-s}
|
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
|
@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
|
containing @var{n} objects each. It's easy to write @code{choose} given
|
||||||
@code{fact}, so we might write the script this way:
|
@code{fact}, so we might write the script this way:
|
||||||
|
|
||||||
@example
|
@example
|
||||||
#!/usr/local/bin/guile \
|
#!/usr/local/bin/guile \
|
||||||
-l fact -e main -s
|
-l fact -e main -s
|
||||||
|
@ -402,6 +408,79 @@ $ ./choose 50 100
|
||||||
100891344545564193334812497256
|
100891344545564193334812497256
|
||||||
@end example
|
@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 Local Variables:
|
||||||
@c TeX-master: "guile.texi"
|
@c TeX-master: "guile.texi"
|
||||||
|
|
|
@ -294,8 +294,12 @@ Disassemble a file.
|
||||||
Time execution.
|
Time execution.
|
||||||
@end deffn
|
@end deffn
|
||||||
|
|
||||||
@deffn {REPL Command} profile exp
|
@deffn {REPL Command} profile exp [#:hz hz=100] @
|
||||||
Profile execution.
|
[#: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
|
@end deffn
|
||||||
|
|
||||||
@deffn {REPL Command} trace exp [#:width w] [#:max-indent i]
|
@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.
|
then show it.
|
||||||
@end deffn
|
@end deffn
|
||||||
|
|
||||||
@deffn {REPL Command} procedure
|
|
||||||
Print the procedure for the selected frame.
|
|
||||||
@end deffn
|
|
||||||
|
|
||||||
@deffn {REPL Command} locals
|
@deffn {REPL Command} locals
|
||||||
Show local variables.
|
Show local variables.
|
||||||
|
|
||||||
|
@ -793,7 +793,7 @@ packages will be
|
||||||
|
|
||||||
Note that a @code{.go} file will only be loaded in preference to a
|
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
|
@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.
|
Paths}, for more on the loading process.
|
||||||
|
|
||||||
Finally, although this section is only about Scheme, sometimes you need
|
Finally, although this section is only about Scheme, sometimes you need
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
@c -*-texinfo-*-
|
@c -*-texinfo-*-
|
||||||
@c This is part of the GNU Guile Reference Manual.
|
@c This is part of the GNU Guile Reference Manual.
|
||||||
@c Copyright (C) 1996, 1997, 2000-2004, 2006, 2007-2014
|
@c Copyright (C) 1996, 1997, 2000-2004, 2006, 2007-2014, 2017
|
||||||
@c Free Software Foundation, Inc.
|
@c Free Software Foundation, Inc.
|
||||||
@c See the file guile.texi for copying conditions.
|
@c See the file guile.texi for copying conditions.
|
||||||
|
|
||||||
|
@ -150,6 +150,7 @@ The Guile core has the following features,
|
||||||
@example
|
@example
|
||||||
guile
|
guile
|
||||||
guile-2 ;; starting from Guile 2.x
|
guile-2 ;; starting from Guile 2.x
|
||||||
|
guile-2.2 ;; starting from Guile 2.2
|
||||||
r5rs
|
r5rs
|
||||||
srfi-0
|
srfi-0
|
||||||
srfi-4
|
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
|
This SRFI is a syntax for defining new record types and creating
|
||||||
predicate, constructor, and field getter and setter functions. It is
|
predicate, constructor, and field getter and setter functions. It is
|
||||||
documented in the ``Compound Data Types'' section of the manual
|
documented in the ``Data Types'' section of the manual (@pxref{SRFI-9
|
||||||
(@pxref{SRFI-9 Records}).
|
Records}).
|
||||||
|
|
||||||
|
|
||||||
@node SRFI-10
|
@node SRFI-10
|
||||||
|
@ -1834,9 +1835,9 @@ documented in the ``Compound Data Types'' section of the manual
|
||||||
@cindex hash-comma
|
@cindex hash-comma
|
||||||
@cindex #,()
|
@cindex #,()
|
||||||
This SRFI implements a reader extension @code{#,()} called hash-comma.
|
This SRFI implements a reader extension @code{#,()} called hash-comma.
|
||||||
It allows the reader to give new kinds of objects, for use both in
|
It allows the reader to give new kinds of objects, for use both in data
|
||||||
data and as constants or literals in source code. This feature is
|
and as constants or literals in source code. This feature is available
|
||||||
available with
|
with
|
||||||
|
|
||||||
@example
|
@example
|
||||||
(use-modules (srfi srfi-10))
|
(use-modules (srfi srfi-10))
|
||||||
|
@ -1894,73 +1895,46 @@ addition,
|
||||||
(display #,(sum 123 456)) @print{} 579
|
(display #,(sum 123 456)) @print{} 579
|
||||||
@end example
|
@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
|
Once @code{(srfi srfi-10)} has loaded, @nicode{#,()} is available
|
||||||
globally, there's no need to use @code{(srfi srfi-10)} in later
|
globally, there's no need to use @code{(srfi srfi-10)} in later
|
||||||
modules. Similarly the tags registered are global and can be used
|
modules. Similarly the tags registered are global and can be used
|
||||||
anywhere once registered.
|
anywhere once registered.
|
||||||
|
|
||||||
There's no attempt to record what previous @nicode{#,()} forms have
|
We do not recommend @nicode{#,()} reader extensions, however, and for
|
||||||
been seen, if two identical forms occur then two calls are made to the
|
three reasons.
|
||||||
handler procedure. The handler might like to maintain a cache or
|
|
||||||
similar to avoid making copies of large objects, depending on expected
|
|
||||||
usage.
|
|
||||||
|
|
||||||
In code the best uses of @nicode{#,()} are generally when there's a
|
First of all, this SRFI is not modular: the tag is matched by name, not
|
||||||
lot of objects of a particular kind as literals or constants. If
|
as an identifier within a scope. Defining a reader extension in one
|
||||||
there's just a few then some local variables and initializers are
|
part of a program can thus affect unrelated parts of a program because
|
||||||
fine, but that becomes tedious and error prone when there's a lot, and
|
the tag is not scoped.
|
||||||
the anonymous and compact syntax of @nicode{#,()} is much better.
|
|
||||||
|
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
|
@node SRFI-11
|
||||||
|
@ -2087,14 +2061,12 @@ library. The functions and variables described here are provided by
|
||||||
(use-modules (srfi srfi-18))
|
(use-modules (srfi srfi-18))
|
||||||
@end example
|
@end example
|
||||||
|
|
||||||
As a general rule, the data types and functions in this SRFI-18
|
SRFI-18 defines facilities for threads, mutexes, condition variables,
|
||||||
implementation are compatible with the types and functions in Guile's
|
time, and exception handling. Because these facilities are at a higher
|
||||||
core threading code. For example, mutexes created with the SRFI-18
|
level than Guile's primitives, they are implemented as a layer on top of
|
||||||
@code{make-mutex} function can be passed to the built-in Guile
|
what Guile provides. In particular this means that a Guile mutex is not
|
||||||
function @code{lock-mutex} (@pxref{Mutexes and Condition Variables}),
|
a SRFI-18 mutex, and a Guile thread is not a SRFI-18 thread, and so on.
|
||||||
and mutexes created with the built-in Guile function @code{make-mutex}
|
Guile provides a set of primitives and SRFI-18 is one of the systems built in terms of those primitives.
|
||||||
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.
|
|
||||||
|
|
||||||
@menu
|
@menu
|
||||||
* SRFI-18 Threads:: Executing code
|
* 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
|
@code{make-thread} begins in a blocked state and will not start
|
||||||
execution until @code{thread-start!} is called on it. Second, SRFI-18
|
execution until @code{thread-start!} is called on it. Second, SRFI-18
|
||||||
threads are constructed with a top-level exception handler that
|
threads are constructed with a top-level exception handler that
|
||||||
captures any exceptions that are thrown on thread exit. In all other
|
captures any exceptions that are thrown on thread exit.
|
||||||
regards, SRFI-18 threads are identical to normal Guile threads.
|
|
||||||
|
SRFI-18 threads are disjoint from Guile's primitive threads.
|
||||||
|
@xref{Threads}, for more on Guile's primitive facility.
|
||||||
|
|
||||||
@defun current-thread
|
@defun current-thread
|
||||||
Returns the thread that called this function. This is the same
|
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
|
@node SRFI-18 Mutexes
|
||||||
@subsubsection SRFI-18 Mutexes
|
@subsubsection SRFI-18 Mutexes
|
||||||
|
|
||||||
The behavior of Guile's built-in mutexes is parameterized via a set of
|
SRFI-18 mutexes are disjoint from Guile's primitive mutexes.
|
||||||
flags passed to the @code{make-mutex} procedure in the core
|
@xref{Mutexes and Condition Variables}, for more on Guile's primitive
|
||||||
(@pxref{Mutexes and Condition Variables}). To satisfy the requirements
|
facility.
|
||||||
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
|
|
||||||
|
|
||||||
@defun make-mutex [name]
|
@defun make-mutex [name]
|
||||||
Returns a new mutex, optionally assigning it the object name
|
Returns a new mutex, optionally assigning it the object name @var{name},
|
||||||
@var{name}, which may be any Scheme object. The returned mutex will be
|
which may be any Scheme object. The returned mutex will be created with
|
||||||
created with the configuration described above. Note that the name
|
the configuration described above.
|
||||||
@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.
|
|
||||||
@end defun
|
@end defun
|
||||||
|
|
||||||
@defun mutex-name mutex
|
@defun mutex-name mutex
|
||||||
Returns the name assigned to @var{mutex} at the time of its creation,
|
Returns the name assigned to @var{mutex} at the time of its creation, or
|
||||||
or @code{#f} if it was not given a name.
|
@code{#f} if it was not given a name.
|
||||||
@end defun
|
@end defun
|
||||||
|
|
||||||
@defun mutex-specific mutex
|
@defun mutex-specific mutex
|
||||||
@defunx mutex-specific-set! mutex obj
|
Return the ``object-specific'' property of @var{mutex}, or @code{#f} if
|
||||||
Get or set the ``object-specific'' property of @var{mutex}. In Guile's
|
none is set.
|
||||||
implementation of SRFI-18, this value is stored as an object property,
|
@end defun
|
||||||
and will be @code{#f} if not set.
|
|
||||||
|
@defun mutex-specific-set! mutex obj
|
||||||
|
Set the ``object-specific'' property of @var{mutex}.
|
||||||
@end defun
|
@end defun
|
||||||
|
|
||||||
@defun mutex-state mutex
|
@defun mutex-state mutex
|
||||||
|
@ -2248,8 +2209,8 @@ Returns information about the state of @var{mutex}. Possible values
|
||||||
are:
|
are:
|
||||||
@itemize @bullet
|
@itemize @bullet
|
||||||
@item
|
@item
|
||||||
thread @code{T}: the mutex is in the locked/owned state and thread T
|
thread @var{t}: the mutex is in the locked/owned state and thread
|
||||||
is the owner of the mutex
|
@var{t} is the owner of the mutex
|
||||||
@item
|
@item
|
||||||
symbol @code{not-owned}: the mutex is in the locked/not-owned state
|
symbol @code{not-owned}: the mutex is in the locked/not-owned state
|
||||||
@item
|
@item
|
||||||
|
@ -2263,17 +2224,14 @@ unlocked/not-abandoned state
|
||||||
@defun mutex-lock! mutex [timeout [thread]]
|
@defun mutex-lock! mutex [timeout [thread]]
|
||||||
Lock @var{mutex}, optionally specifying a time object @var{timeout}
|
Lock @var{mutex}, optionally specifying a time object @var{timeout}
|
||||||
after which to abort the lock attempt and a thread @var{thread} giving
|
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
|
a new owner for @var{mutex} different than the current thread.
|
||||||
procedure has the same behavior as the @code{lock-mutex} procedure in
|
|
||||||
the core library.
|
|
||||||
@end defun
|
@end defun
|
||||||
|
|
||||||
@defun mutex-unlock! mutex [condition-variable [timeout]]
|
@defun mutex-unlock! mutex [condition-variable [timeout]]
|
||||||
Unlock @var{mutex}, optionally specifying a condition variable
|
Unlock @var{mutex}, optionally specifying a condition variable
|
||||||
@var{condition-variable} on which to wait, either indefinitely or,
|
@var{condition-variable} on which to wait, either indefinitely or,
|
||||||
optionally, until the time object @var{timeout} has passed, to be
|
optionally, until the time object @var{timeout} has passed, to be
|
||||||
signalled. This procedure has the same behavior as the
|
signalled.
|
||||||
@code{unlock-mutex} procedure in the core library.
|
|
||||||
@end defun
|
@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.
|
SRFI-18 does not specify a ``wait'' function for condition variables.
|
||||||
Waiting on a condition variable can be simulated using the SRFI-18
|
Waiting on a condition variable can be simulated using the SRFI-18
|
||||||
@code{mutex-unlock!} function described in the previous section, or
|
@code{mutex-unlock!} function described in the previous section.
|
||||||
Guile's built-in @code{wait-condition-variable} procedure can be used.
|
|
||||||
|
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
|
@defun condition-variable? obj
|
||||||
Returns @code{#t} if @var{obj} is a condition variable, @code{#f}
|
Returns @code{#t} if @var{obj} is a condition variable, @code{#f}
|
||||||
otherwise. This is the same procedure as the same-named built-in
|
otherwise.
|
||||||
procedure
|
|
||||||
(@pxref{Mutexes and Condition Variables, @code{condition-variable?}}).
|
|
||||||
@end defun
|
@end defun
|
||||||
|
|
||||||
@defun make-condition-variable [name]
|
@defun make-condition-variable [name]
|
||||||
Returns a new condition variable, optionally assigning it the object
|
Returns a new condition variable, optionally assigning it the object
|
||||||
name @var{name}, which may be any Scheme object. This procedure
|
name @var{name}, which may be any Scheme object.
|
||||||
replaces a procedure of the same name in the core library.
|
|
||||||
@end defun
|
@end defun
|
||||||
|
|
||||||
@defun condition-variable-name condition-variable
|
@defun condition-variable-name condition-variable
|
||||||
|
@ -2304,21 +2262,19 @@ creation, or @code{#f} if it was not given a name.
|
||||||
@end defun
|
@end defun
|
||||||
|
|
||||||
@defun condition-variable-specific condition-variable
|
@defun condition-variable-specific condition-variable
|
||||||
@defunx condition-variable-specific-set! condition-variable obj
|
Return the ``object-specific'' property of @var{condition-variable}, or
|
||||||
Get or set the ``object-specific'' property of
|
@code{#f} if none is set.
|
||||||
@var{condition-variable}. In Guile's implementation of SRFI-18, this
|
@end defun
|
||||||
value is stored as an object property, and will be @code{#f} if not
|
|
||||||
set.
|
@defun condition-variable-specific-set! condition-variable obj
|
||||||
|
Set the ``object-specific'' property of @var{condition-variable}.
|
||||||
@end defun
|
@end defun
|
||||||
|
|
||||||
@defun condition-variable-signal! condition-variable
|
@defun condition-variable-signal! condition-variable
|
||||||
@defunx condition-variable-broadcast! condition-variable
|
@defunx condition-variable-broadcast! condition-variable
|
||||||
Wake up one thread that is waiting for @var{condition-variable}, in
|
Wake up one thread that is waiting for @var{condition-variable}, in
|
||||||
the case of @code{condition-variable-signal!}, or all threads waiting
|
the case of @code{condition-variable-signal!}, or all threads waiting
|
||||||
for it, in the case of @code{condition-variable-broadcast!}. The
|
for it, in the case of @code{condition-variable-broadcast!}.
|
||||||
behavior of these procedures is equivalent to that of the procedures
|
|
||||||
@code{signal-condition-variable} and
|
|
||||||
@code{broadcast-condition-variable} in the core library.
|
|
||||||
@end defun
|
@end defun
|
||||||
|
|
||||||
|
|
||||||
|
@ -2427,17 +2383,6 @@ functions and variables described here are provided by
|
||||||
(use-modules (srfi srfi-19))
|
(use-modules (srfi srfi-19))
|
||||||
@end example
|
@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
|
@menu
|
||||||
* SRFI-19 Introduction::
|
* SRFI-19 Introduction::
|
||||||
* SRFI-19 Time::
|
* 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
|
timezone. A date object is immutable, its fields can be read but they
|
||||||
cannot be modified once the object is created.
|
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
|
@defun date? obj
|
||||||
Return @code{#t} if @var{obj} is a date object, or @code{#f} if not.
|
Return @code{#t} if @var{obj} is a date object, or @code{#f} if not.
|
||||||
@end defun
|
@end defun
|
||||||
|
@ -3302,8 +3257,8 @@ Insert a newline.
|
||||||
Insert a tilde.
|
Insert a tilde.
|
||||||
@end table
|
@end table
|
||||||
|
|
||||||
This procedure is the same as calling @code{simple-format} (@pxref{Writing})
|
This procedure is the same as calling @code{simple-format}
|
||||||
with @code{#f} as the destination.
|
(@pxref{Simple Output}) with @code{#f} as the destination.
|
||||||
@end deffn
|
@end deffn
|
||||||
|
|
||||||
@node SRFI-30
|
@node SRFI-30
|
||||||
|
|
|
@ -1,225 +1,121 @@
|
||||||
@c -*-texinfo-*-
|
@c -*-texinfo-*-
|
||||||
@c This is part of the GNU Guile Reference Manual.
|
@c This is part of the GNU Guile Reference Manual.
|
||||||
@c Copyright (C) 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.
|
@c See the file guile.texi for copying conditions.
|
||||||
|
|
||||||
@node Statprof
|
@node Statprof
|
||||||
@section 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:
|
A simple use of statprof would look like this:
|
||||||
|
|
||||||
@example
|
@example
|
||||||
(statprof-reset 0 50000 #t)
|
(use-modules (statprof))
|
||||||
(statprof-start)
|
(statprof (lambda ()
|
||||||
(do-something)
|
(map 1+ (iota 1000000))
|
||||||
(statprof-stop)
|
#f))
|
||||||
(statprof-display)
|
|
||||||
@end example
|
@end example
|
||||||
|
|
||||||
This would reset statprof, clearing all accumulated statistics, then
|
This would run the thunk with statistical profiling, finally displaying
|
||||||
start profiling, run some code, stop profiling, and finally display a
|
a flat table of statistics which could look something like this:
|
||||||
gprof flat-style table of statistics which will look something like
|
|
||||||
this:
|
|
||||||
|
|
||||||
@example
|
@example
|
||||||
% cumulative self self total
|
% cumulative self
|
||||||
time seconds seconds calls ms/call ms/call name
|
time seconds seconds procedure
|
||||||
35.29 0.23 0.23 2002 0.11 0.11 -
|
57.14 39769.73 0.07 ice-9/boot-9.scm:249:5:map1
|
||||||
23.53 0.15 0.15 2001 0.08 0.08 positive?
|
28.57 0.04 0.04 ice-9/boot-9.scm:1165:0:iota
|
||||||
23.53 0.15 0.15 2000 0.08 0.08 +
|
14.29 0.02 0.02 1+
|
||||||
11.76 0.23 0.08 2000 0.04 0.11 do-nothing
|
0.00 0.12 0.00 <current input>:2:10
|
||||||
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
|
Sample count: 7
|
||||||
...
|
Total time: 0.123490713 seconds (0.201983993 seconds in GC)
|
||||||
@end example
|
@end example
|
||||||
|
|
||||||
All of the numerical data with the exception of the calls column is
|
All of the numerical data with the exception of the calls column is
|
||||||
statistically approximate. In the following column descriptions, and in
|
statistically approximate. In the following column descriptions, and in
|
||||||
all of statprof, "time" refers to execution time (both user and system),
|
all of statprof, ``time'' refers to execution time (both user and
|
||||||
not wall clock time.
|
system), not wall clock time.
|
||||||
|
|
||||||
@table @asis
|
The @code{% time} column indicates the percentage of the run-time time
|
||||||
@item % time
|
spent inside the procedure itself (not counting children). It is
|
||||||
The percent of the time spent inside the procedure itself (not counting
|
calculated as @code{self seconds}, measuring the amount of time spent in
|
||||||
children).
|
the procedure, divided by the total run-time.
|
||||||
|
|
||||||
@item cumulative seconds
|
@code{cumulative seconds} also counts time spent in children of a
|
||||||
The total number of seconds spent in the procedure, including children.
|
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
|
Finally, the GC time measures the time spent in the garbage collector.
|
||||||
The total number of seconds spent in the procedure itself (not counting
|
On systems with multiple cores, this time can be larger than the run
|
||||||
children).
|
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
|
Statprof's main mode of operation is as a statistical profiler. However
|
||||||
The total number of times the procedure was called.
|
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
|
@example
|
||||||
The average time taken by the procedure itself on each call, in ms.
|
(use-modules (statprof))
|
||||||
|
(statprof (lambda ()
|
||||||
|
(map 1+ (iota 1000000))
|
||||||
|
#f)
|
||||||
|
#:count-calls? #t)
|
||||||
|
@end example
|
||||||
|
|
||||||
@item total ms/call
|
The result has an additional @code{calls} column:
|
||||||
The average time taken by each call to the procedure, including time
|
|
||||||
spent in child functions.
|
|
||||||
|
|
||||||
@item name
|
@example
|
||||||
The name of the procedure.
|
% 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
|
@heading Implementation notes
|
||||||
the procedures, so it won't confuse different procedures with the same
|
|
||||||
name. They will show up as two different rows in the output.
|
|
||||||
|
|
||||||
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
|
The profiler works by setting the unix profiling signal
|
||||||
@code{ITIMER_PROF} to go off after the interval you define in the call
|
@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
|
to @code{statprof-reset}. When the signal fires, a sampling routine
|
||||||
run which looks at the current procedure that's executing, and then
|
runs which crawls up the stack, recording all instruction pointers into
|
||||||
crawls up the stack, and for each procedure encountered, increments that
|
a buffer. After the sample is complete, the profiler resets profiling
|
||||||
procedure's sample count. Note that if a procedure is encountered
|
timer to fire again after the appropriate interval.
|
||||||
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.
|
|
||||||
|
|
||||||
Meanwhile, the profiler keeps track, via @code{get-internal-run-time},
|
Later, when profiling stops, that log buffer is analyzed to produce the
|
||||||
how much CPU time (system and user -- which is also what
|
``self seconds'' and ``cumulative seconds'' statistics. A procedure at
|
||||||
@code{ITIMER_PROF} tracks), has elapsed while code has been executing
|
the top of the stack counts toward ``self'' samples, and everything on
|
||||||
within a statprof-start/stop block.
|
the stack counts towards ``cumulative'' samples.
|
||||||
|
|
||||||
The profiler also tries to avoid counting or timing its own code as much
|
While the profiler is running it measures how much CPU time (system and
|
||||||
as possible.
|
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
|
@heading 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.
|
|
||||||
|
|
||||||
@end defun
|
@deffn {Scheme Procedure} statprof thunk @
|
||||||
|
[#:loop loop=1] [#:hz hz=100] @
|
||||||
@anchor{statprof statprof-start}@defun statprof-start
|
[#:port port=(current-output-port)] @
|
||||||
Start the profiler.@code{}
|
[#:count-calls? count-calls?=#f] @
|
||||||
|
[#:display-style display-style='flat]
|
||||||
@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?]
|
|
||||||
Profile the execution of @var{thunk}, and return its return values.
|
Profile the execution of @var{thunk}, and return its return values.
|
||||||
|
|
||||||
The stack will be sampled @var{hz} times per second, and the thunk
|
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.
|
If @var{count-calls?} is true, all procedure calls will be recorded.
|
||||||
This operation is somewhat expensive.
|
This operation is somewhat expensive.
|
||||||
|
|
||||||
If @var{full-stacks?} is true, at each sample, statprof will store away
|
After the @var{thunk} has been profiled, print out a profile to
|
||||||
the whole call tree, for later analysis. Use
|
@var{port}. If @var{display-style} is @code{flat}, the results will be
|
||||||
@code{statprof-fetch-stacks} or @code{statprof-fetch-call-tree} to
|
printed as a flat profile. Otherwise if @var{display-style} is
|
||||||
retrieve the last-stored stacks.
|
@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
|
Profiling can also be enabled and disabled manually.
|
||||||
Profile the expressions in the body, and return the body's return
|
|
||||||
value.
|
|
||||||
|
|
||||||
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
|
@table @code
|
||||||
@item #:loop
|
@item flat
|
||||||
Execute the body @var{loop} number of times, or @code{#f} for no looping
|
Display a traditional gprof-style flat profile.
|
||||||
|
@item anomalies
|
||||||
default: @code{#f}
|
Find statistical anomalies in the data.
|
||||||
|
@item tree
|
||||||
@item #:hz
|
Display a tree profile.
|
||||||
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}
|
|
||||||
|
|
||||||
@end table
|
@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?]
|
@deffn {Scheme Procedure} statprof-fetch-call-tree [#:precise precise?=#f]
|
||||||
Do an allocation profile of the execution of @var{thunk}.
|
@verbatim
|
||||||
|
Return a call tree for the previous statprof run.
|
||||||
|
|
||||||
The stack will be sampled soon after every garbage collection, yielding
|
The return value is a list of nodes. A node is a list of the form:
|
||||||
an approximate idea of what is causing allocation in your program.
|
@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
|
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}
|
@var{loop} parameter, to cause @var{thunk} to be called @var{loop}
|
||||||
times.
|
times.
|
||||||
|
@end deffn
|
||||||
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
|
|
||||||
|
|
|
@ -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
|
example above matches an element @code{e} with an attribute @code{i} and three
|
||||||
children.
|
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}
|
binds @var{d} to @code{1}, @var{a} to @code{3}, @var{b} to @code{4}, and @var{c}
|
||||||
to @code{5}.
|
to @code{5}.
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,12 @@
|
||||||
@c -*-texinfo-*-
|
@c -*-texinfo-*-
|
||||||
@c This is part of the GNU Guile Reference Manual.
|
@c This is part of the GNU Guile Reference Manual.
|
||||||
@c Copyright (C) 2013 Free Software Foundation, Inc.
|
@c Copyright (C) 2013, 2017 Free Software Foundation, Inc.
|
||||||
@c See the file guile.texi for copying conditions.
|
@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
|
@node SXML
|
||||||
@section SXML
|
@section SXML
|
||||||
|
|
||||||
|
@ -17,7 +21,7 @@ fragment:
|
||||||
may be represented with the following SXML:
|
may be represented with the following SXML:
|
||||||
|
|
||||||
@example
|
@example
|
||||||
(parrot (@@ (type "African Grey)) (name "Alfie"))
|
(parrot (@@ (type "African Grey")) (name "Alfie"))
|
||||||
@end example
|
@end example
|
||||||
|
|
||||||
SXML is very general, and is capable of representing all of XML.
|
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.
|
parsers, serializers, and transformers.
|
||||||
|
|
||||||
@menu
|
@menu
|
||||||
* SXML Overview:: XML, as it was meant to be
|
* SXML Overview:: XML, as it was meant to be
|
||||||
* Reading and Writing XML:: Convenient XML parsing and serializing
|
* Reading and Writing XML:: Convenient XML parsing and serializing
|
||||||
* SSAX:: Custom functional-style XML parsers
|
* SSAX:: Custom functional-style XML parsers
|
||||||
* Transforming SXML:: Munging SXML with @code{pre-post-order}
|
* Transforming SXML:: Munging SXML with @code{pre-post-order}
|
||||||
* SXML Tree Fold:: Fold-based SXML transformations
|
* SXML Tree Fold:: Fold-based SXML transformations
|
||||||
* SXPath:: XPath for SXML
|
* 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 ssax input-parse:: The SSAX tokenizer, optimized for Guile
|
* sxml apply-templates:: A more XSLT-like approach to SXML transformations
|
||||||
@end menu
|
@end menu
|
||||||
|
|
||||||
@node SXML Overview
|
@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
|
whitespace, and validation. This module therefore is intended to be a
|
||||||
framework, a set of ``Lego blocks'' you can use to build a parser
|
framework, a set of ``Lego blocks'' you can use to build a parser
|
||||||
following any discipline and performing validation to any degree. As an
|
following any discipline and performing validation to any degree. As an
|
||||||
example of the parser construction, this file includes a semi-validating
|
example of the parser construction, the source file includes a
|
||||||
SXML parser.
|
semi-validating SXML parser.
|
||||||
|
|
||||||
SSAX has a ``sequential'' feel of SAX yet a ``functional style'' of DOM.
|
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
|
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
|
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
|
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
|
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:
|
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
|
@code{SSAX:make-elem-parser} or @code{SSAX:make-parser}. In the latter
|
||||||
case, the user must provide functions of specific signatures, which are
|
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
|
@example
|
||||||
bindings := (<binding>...)
|
bindings := (<binding>...)
|
||||||
binding := (<tag> <bandler-pair>...)
|
binding := (<tag> <handler-pair>...)
|
||||||
| (*default* . <post-handler>)
|
| (*default* . <post-handler>)
|
||||||
| (*text* . <text-handler>)
|
| (*text* . <text-handler>)
|
||||||
tag := <symbol>
|
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
|
Similarly to XPath, SXPath defines full and abbreviated notations for
|
||||||
location paths. In both cases, the abbreviated notation can be
|
location paths. In both cases, the abbreviated notation can be
|
||||||
mechanically expanded into the full form by simple rewriting rules. In
|
mechanically expanded into the full form by simple rewriting rules. In
|
||||||
case of SXPath the corresponding rules are given as comments to a sxpath
|
the case of SXPath the corresponding rules are given in the
|
||||||
function, below. The regression test suite at the end of this file shows
|
documentation of the @code{sxpath} procedure.
|
||||||
a representative sample of SXPaths in both notations, juxtaposed with
|
@xref{sxpath-procedure-docs,,SXPath procedure documentation}.
|
||||||
the corresponding XPath expressions. Most of the samples are borrowed
|
|
||||||
literally from the XPath specification, while the others are adjusted
|
The regression test suite at the end of the file @file{SXPATH-old.scm}
|
||||||
for our running example, tree1.
|
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
|
@deffn {Scheme Procedure} nodeset? x
|
||||||
|
Return @code{#t} if @var{x} is a nodeset.
|
||||||
@end deffn
|
@end deffn
|
||||||
|
|
||||||
@deffn {Scheme Procedure} node-typeof? crit
|
@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
|
@end deffn
|
||||||
|
|
||||||
@deffn {Scheme Procedure} node-eq? other
|
@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
|
@end deffn
|
||||||
|
|
||||||
@deffn {Scheme Procedure} node-equal? other
|
@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
|
@end deffn
|
||||||
|
|
||||||
@deffn {Scheme Procedure} node-pos n
|
@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
|
@end deffn
|
||||||
|
|
||||||
@deffn {Scheme Procedure} filter pred?
|
@deffn {Scheme Procedure} filter pred?
|
||||||
@verbatim
|
A filter applicator, which introduces a filtering context. The argument
|
||||||
-- Scheme Procedure: filter pred list
|
converter @var{pred?} is considered a predicate, with either @code{#f}
|
||||||
Return all the elements of 2nd arg LIST that satisfy predicate
|
or @code{nil} meaning failure.
|
||||||
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
|
|
||||||
@end deffn
|
@end deffn
|
||||||
|
|
||||||
@deffn {Scheme Procedure} take-until pred?
|
@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
|
@end deffn
|
||||||
|
|
||||||
@deffn {Scheme Procedure} take-after pred?
|
@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
|
@end deffn
|
||||||
|
|
||||||
@deffn {Scheme Procedure} map-union proc lst
|
@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
|
@end deffn
|
||||||
|
|
||||||
@deffn {Scheme Procedure} node-reverse node-or-nodeset
|
@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
|
@end deffn
|
||||||
|
|
||||||
@deffn {Scheme Procedure} node-trace title
|
@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
|
@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?
|
@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
|
@end deffn
|
||||||
|
|
||||||
@deffn {Scheme Procedure} node-self pred?
|
@deffn {Scheme Procedure} node-self pred?
|
||||||
@verbatim
|
Similar to @code{select-kids} except that the predicate @var{pred?} is
|
||||||
-- Scheme Procedure: filter pred list
|
applied to the node itself rather than to its children. The resulting
|
||||||
Return all the elements of 2nd arg LIST that satisfy predicate
|
nodeset will contain either one component, or will be empty if the node
|
||||||
PRED. The list is not disordered - elements that appear in the
|
failed the predicate.
|
||||||
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
|
|
||||||
@end deffn
|
@end deffn
|
||||||
|
|
||||||
@deffn {Scheme Procedure} node-join . selectors
|
@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
|
@end deffn
|
||||||
|
|
||||||
@deffn {Scheme Procedure} node-reduce . converters
|
@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
|
@end deffn
|
||||||
|
|
||||||
@deffn {Scheme Procedure} node-or . converters
|
@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
|
@end deffn
|
||||||
|
|
||||||
@deffn {Scheme Procedure} node-closure test-pred?
|
@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
|
@end deffn
|
||||||
|
|
||||||
@deffn {Scheme Procedure} node-parent rootnode
|
@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
|
@end deffn
|
||||||
|
|
||||||
|
@anchor{sxpath-procedure-docs}
|
||||||
@deffn {Scheme Procedure} sxpath path
|
@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
|
@end deffn
|
||||||
|
|
||||||
@node sxml ssax input-parse
|
@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:
|
The generic URI syntax is as follows:
|
||||||
|
|
||||||
@example
|
@example
|
||||||
URI := scheme ":" ["//" [userinfo "@@"] host [":" port]] path \
|
URI-reference := [scheme ":"] ["//" [userinfo "@@"] host [":" port]] path \
|
||||||
[ "?" query ] [ "#" fragment ]
|
[ "?" query ] [ "#" fragment ]
|
||||||
@end example
|
@end example
|
||||||
|
|
||||||
For example, in the URI, @indicateurl{http://www.gnu.org/help/}, the
|
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
|
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
|
@code{/help/}, and there is no userinfo, port, query, or fragment.
|
||||||
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.
|
|
||||||
|
|
||||||
Userinfo is something of an abstraction, as some legacy URI schemes
|
Userinfo is something of an abstraction, as some legacy URI schemes
|
||||||
allowed userinfo of the form @code{@var{username}:@var{passwd}}. But
|
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
|
this practice, so it calls anything before the @code{@@} sign
|
||||||
@dfn{userinfo}.
|
@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
|
@example
|
||||||
(use-modules (web uri))
|
(use-modules (web uri))
|
||||||
@end example
|
@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
|
module. Load it into your Guile, using a form like the above, to have
|
||||||
access to them.
|
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 @
|
@deffn {Scheme Procedure} build-uri scheme @
|
||||||
[#:userinfo=@code{#f}] [#:host=@code{#f}] [#:port=@code{#f}] @
|
[#:userinfo=@code{#f}] [#:host=@code{#f}] [#:port=@code{#f}] @
|
||||||
[#:path=@code{""}] [#:query=@code{#f}] [#:fragment=@code{#f}] @
|
[#:path=@code{""}] [#:query=@code{#f}] [#:fragment=@code{#f}] @
|
||||||
[#:validate?=@code{#t}]
|
[#:validate?=@code{#t}]
|
||||||
Construct a URI object. @var{scheme} should be a symbol, @var{port}
|
Construct a URI. @var{scheme} should be a symbol, @var{port} either a
|
||||||
either a positive, exact integer or @code{#f}, and the rest of the
|
positive, exact integer or @code{#f}, and the rest of the fields are
|
||||||
fields are either strings or @code{#f}. If @var{validate?} is true,
|
either strings or @code{#f}. If @var{validate?} is true, also run some
|
||||||
also run some consistency checks to make sure that the constructed URI
|
consistency checks to make sure that the constructed URI is valid.
|
||||||
is valid.
|
|
||||||
@end deffn
|
@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
|
@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-userinfo uri
|
||||||
@deffnx {Scheme Procedure} uri-host uri
|
@deffnx {Scheme Procedure} uri-host uri
|
||||||
@deffnx {Scheme Procedure} uri-port uri
|
@deffnx {Scheme Procedure} uri-port uri
|
||||||
@deffnx {Scheme Procedure} uri-path uri
|
@deffnx {Scheme Procedure} uri-path uri
|
||||||
@deffnx {Scheme Procedure} uri-query uri
|
@deffnx {Scheme Procedure} uri-query uri
|
||||||
@deffnx {Scheme Procedure} uri-fragment uri
|
@deffnx {Scheme Procedure} uri-fragment uri
|
||||||
A predicate and field accessors for the URI record type. The URI scheme
|
Field accessors for the URI record type. The URI scheme will be a
|
||||||
will be a symbol, or @code{#f} if the object is a URI reference but not
|
symbol, or @code{#f} if the object is a relative-ref (see below). The
|
||||||
a URI. The port will be either a positive, exact integer or @code{#f},
|
port will be either a positive, exact integer or @code{#f}, and the rest
|
||||||
and the rest of the fields will be either strings or @code{#f} if not
|
of the fields will be either strings or @code{#f} if not present.
|
||||||
present.
|
|
||||||
@end deffn
|
@end deffn
|
||||||
|
|
||||||
@deffn {Scheme Procedure} string->uri string
|
@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.
|
could not be parsed.
|
||||||
@end deffn
|
@end deffn
|
||||||
|
|
||||||
@deffn {Scheme Procedure} string->uri-reference string
|
@deffn {Scheme Procedure} uri->string uri [#:include-fragment?=@code{#t}]
|
||||||
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
|
|
||||||
Serialize @var{uri} to a string. If the URI has a port that is the
|
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
|
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
|
@end deffn
|
||||||
|
|
||||||
@deffn {Scheme Procedure} declare-default-port! scheme port
|
@deffn {Scheme Procedure} declare-default-port! scheme port
|
||||||
Declare a default port for the given URI scheme.
|
Declare a default port for the given URI scheme.
|
||||||
@end deffn
|
@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
|
Percent-decode the given @var{str}, according to @var{encoding}, which
|
||||||
should be the name of a character encoding.
|
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
|
@xref{Ports, @code{set-port-encoding!}}, for more information on
|
||||||
character encodings.
|
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
|
Returns a string of the decoded characters, or a bytevector if
|
||||||
@var{encoding} was @code{#f}.
|
@var{encoding} was @code{#f}.
|
||||||
@end deffn
|
@end deffn
|
||||||
|
@ -318,6 +297,70 @@ For example, the list @code{("scrambled eggs" "biscuits&gravy")} encodes
|
||||||
as @code{"scrambled%20eggs/biscuits%26gravy"}.
|
as @code{"scrambled%20eggs/biscuits%26gravy"}.
|
||||||
@end deffn
|
@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
|
@node HTTP
|
||||||
@subsection The Hyper-Text Transfer Protocol
|
@subsection The Hyper-Text Transfer Protocol
|
||||||
|
|
||||||
|
@ -747,9 +790,9 @@ a resource.
|
||||||
@deftypevr {HTTP Header} List content-type
|
@deftypevr {HTTP Header} List content-type
|
||||||
The MIME type of a resource, as a symbol, along with any parameters.
|
The MIME type of a resource, as a symbol, along with any parameters.
|
||||||
@example
|
@example
|
||||||
(parse-header 'content-length "text/plain")
|
(parse-header 'content-type "text/plain")
|
||||||
@result{} (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"))
|
@result{} (text/plain (charset . "utf-8"))
|
||||||
@end example
|
@end example
|
||||||
Note that the @code{charset} parameter is something is a misnomer, and
|
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
|
@end example
|
||||||
|
|
||||||
@deffn {Scheme Procedure} open-socket-for-uri uri
|
@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
|
@end deffn
|
||||||
|
|
||||||
@deffn {Scheme Procedure} http-get uri arg...
|
@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
|
#+AUTHOR: Ludovic Courtès
|
||||||
#+STARTUP: content
|
#+STARTUP: content
|
||||||
#+EMAIL: ludo@gnu.org
|
#+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
|
* Preparing & uploading the tarball
|
||||||
|
|
||||||
|
@ -69,17 +69,16 @@ if in doubt.
|
||||||
|
|
||||||
`libguile/libguile.map' should also be updated as new public symbols are
|
`libguile/libguile.map' should also be updated as new public symbols are
|
||||||
added. Ideally, new symbols should get under a new version
|
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.
|
symbol---e.g., `GUILE_2.2.3' for symbols introduced in Guile 2.2.3.
|
||||||
However, this has not been done for Guile <= 2.0.2.
|
|
||||||
|
|
||||||
** Tag v2.0.x
|
** Tag v2.2.x
|
||||||
|
|
||||||
Create a signed Git tag, like this:
|
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
|
The tag *must* be `v2.2.X'. For the sake of consistency, always use
|
||||||
"GNU Guile 2.0.X." as the tag comment.
|
"GNU Guile 2.2.X." as the tag comment.
|
||||||
|
|
||||||
** Push the tag and changes
|
** Push the tag and changes
|
||||||
|
|
||||||
|
@ -98,7 +97,7 @@ reports the new version number.
|
||||||
|
|
||||||
** Upload
|
** 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.
|
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:
|
expected:
|
||||||
|
|
||||||
$ mkdir t && cd t && \
|
$ mkdir t && cd t && \
|
||||||
wget ftp.gnu.org/gnu/guile/guile-2.0.X.tar.gz && \
|
wget ftp.gnu.org/gnu/guile/guile-2.2.X.tar.gz && \
|
||||||
wget ftp.gnu.org/gnu/guile/guile-2.0.X.tar.xz
|
wget ftp.gnu.org/gnu/guile/guile-2.2.X.tar.xz
|
||||||
$ diff guile-2.0.X.tar.gz ../guile-2.0.X.tar.gz
|
$ diff guile-2.2.X.tar.gz ../guile-2.2.X.tar.gz
|
||||||
$ diff guile-2.0.X.tar.xz ../guile-2.0.X.tar.xz
|
$ diff guile-2.2.X.tar.xz ../guile-2.2.X.tar.xz
|
||||||
|
|
||||||
You're almost done!
|
You're almost done!
|
||||||
|
|
||||||
|
@ -138,17 +137,17 @@ Announcements").
|
||||||
Use `build-aux/gendocs', add to the manual/ directory of the web site.
|
Use `build-aux/gendocs', add to the manual/ directory of the web site.
|
||||||
|
|
||||||
$ cd doc/ref
|
$ 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
|
** Prepare the email announcement
|
||||||
|
|
||||||
$ build-aux/announce-gen --release-type=stable --package-name=guile \
|
$ 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 \
|
--gpg-key-id=MY-KEY --url-directory=ftp://ftp.gnu.org/gnu/guile \
|
||||||
--bootstrap-tools=autoconf,automake,libtool,gnulib,makeinfo \
|
--bootstrap-tools=autoconf,automake,libtool,gnulib,makeinfo \
|
||||||
--gnulib-version=$( cd ~/src/gnulib ; git describe )
|
--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
|
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
|
projects.) It must include a description of what Guile is (not everyone
|
||||||
reading info-gnu may know about it.) Use the text of previous
|
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,
|
Copying and distribution of this file, with or without modification,
|
||||||
are permitted in any medium without royalty provided the copyright
|
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>.
|
at <http://lists.gnu.org/archive/html/bug-gnulib/2012-07/msg00079.html>.
|
||||||
Remove when integrated in Gnulib.
|
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
|
--- a/build-aux/git-version-gen
|
||||||
+++ b/build-aux/git-version-gen
|
+++ b/build-aux/git-version-gen
|
||||||
@@ -86,6 +86,7 @@ Print a version string.
|
@@ -86,6 +86,7 @@ Print a version string.
|
||||||
Options:
|
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*')
|
+ --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
|
@@ -97,11 +98,15 @@ Running without arguments will suffice in most cases."
|
||||||
@@ -96,11 +97,15 @@ Running without arguments will suffice in most cases."
|
|
||||||
prefix=v
|
prefix=v
|
||||||
fallback=
|
fallback=
|
||||||
|
|
||||||
|
@ -23,12 +25,12 @@ Remove when integrated in Gnulib.
|
||||||
case $1 in
|
case $1 in
|
||||||
--help) echo "$usage"; exit 0;;
|
--help) echo "$usage"; exit 0;;
|
||||||
--version) echo "$version"; exit 0;;
|
--version) echo "$version"; exit 0;;
|
||||||
--prefix) shift; prefix="$1";;
|
--prefix) shift; prefix=${1?};;
|
||||||
+ --match) shift; match="$1";;
|
+ --match) shift; match="$1";;
|
||||||
--fallback) shift; fallback="$1";;
|
--fallback) shift; fallback=${1?};;
|
||||||
-*)
|
-*)
|
||||||
echo "$0: Unknown option '$1'." >&2
|
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
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
@ -36,7 +38,7 @@ Remove when integrated in Gnulib.
|
||||||
tag_sed_script="${tag_sed_script:-s/x/x/}"
|
tag_sed_script="${tag_sed_script:-s/x/x/}"
|
||||||
|
|
||||||
nl='
|
nl='
|
||||||
@@ -154,7 +160,7 @@ then
|
@@ -155,7 +161,7 @@ then
|
||||||
# directory, and "git describe" output looks sensible, use that to
|
# directory, and "git describe" output looks sensible, use that to
|
||||||
# derive a version string.
|
# derive a version string.
|
||||||
elif test "`git log -1 --pretty=format:x . 2>&1`" = x \
|
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,
|
/* Copyright (C) 1997,1999,2000,2001, 2002, 2003, 2006, 2007, 2008,
|
||||||
* 2009, 2010, 2013 Free Software Foundation, Inc.
|
* 2009, 2010, 2013 Free Software Foundation, Inc.
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation; either version 3, or (at your option)
|
* the Free Software Foundation; either version 3, or (at your option)
|
||||||
* any later version.
|
* any later version.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this software; see the file COPYING. If not, write to
|
* along with this software; see the file COPYING. If not, write to
|
||||||
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||||
|
@ -47,12 +47,14 @@ scm_t_option scm_readline_opts[] = {
|
||||||
"History length." },
|
"History length." },
|
||||||
{ SCM_OPTION_INTEGER, "bounce-parens", 500,
|
{ SCM_OPTION_INTEGER, "bounce-parens", 500,
|
||||||
"Time (ms) to show matching opening parenthesis (0 = off)."},
|
"Time (ms) to show matching opening parenthesis (0 = off)."},
|
||||||
|
{ SCM_OPTION_BOOLEAN, "bracketed-paste", 1,
|
||||||
|
"Disable interpretation of control characters in pastes." },
|
||||||
{ 0 }
|
{ 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
extern void stifle_history (int max);
|
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),
|
(SCM setting),
|
||||||
"")
|
"")
|
||||||
#define FUNC_NAME s_scm_readline_options
|
#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 ans = scm_options (setting,
|
||||||
scm_readline_opts,
|
scm_readline_opts,
|
||||||
FUNC_NAME);
|
FUNC_NAME);
|
||||||
stifle_history (SCM_HISTORY_LENGTH);
|
if (!SCM_UNBNDP (setting)) {
|
||||||
|
stifle_history (SCM_HISTORY_LENGTH);
|
||||||
|
}
|
||||||
return ans;
|
return ans;
|
||||||
}
|
}
|
||||||
#undef FUNC_NAME
|
#undef FUNC_NAME
|
||||||
|
@ -107,13 +111,13 @@ void
|
||||||
rl_free_line_state ()
|
rl_free_line_state ()
|
||||||
{
|
{
|
||||||
register HIST_ENTRY *entry;
|
register HIST_ENTRY *entry;
|
||||||
|
|
||||||
free_undo_list ();
|
free_undo_list ();
|
||||||
|
|
||||||
entry = current_history ();
|
entry = current_history ();
|
||||||
if (entry)
|
if (entry)
|
||||||
entry->data = (char *)NULL;
|
entry->data = (char *)NULL;
|
||||||
|
|
||||||
_rl_kill_kbd_macro ();
|
_rl_kill_kbd_macro ();
|
||||||
rl_clear_message ();
|
rl_clear_message ();
|
||||||
_rl_init_argument ();
|
_rl_init_argument ();
|
||||||
|
@ -145,15 +149,15 @@ static void unwind_readline (void *unused);
|
||||||
static void reentry_barrier (void);
|
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),
|
(SCM text, SCM inp, SCM outp, SCM read_hook),
|
||||||
"")
|
"")
|
||||||
#define FUNC_NAME s_scm_readline
|
#define FUNC_NAME s_scm_readline
|
||||||
{
|
{
|
||||||
SCM ans;
|
SCM ans;
|
||||||
|
|
||||||
reentry_barrier ();
|
reentry_barrier ();
|
||||||
|
|
||||||
before_read = SCM_BOOL_F;
|
before_read = SCM_BOOL_F;
|
||||||
|
|
||||||
if (!SCM_UNBNDP (text))
|
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);
|
scm_wrong_type_arg (s_scm_readline, SCM_ARG1, text);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!((SCM_UNBNDP (inp) && SCM_OPINFPORTP (scm_current_input_port ()))
|
if (!((SCM_UNBNDP (inp) && SCM_OPINFPORTP (scm_current_input_port ()))
|
||||||
|| SCM_OPINFPORTP (inp)))
|
|| 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",
|
"Input port is not open or not a file port",
|
||||||
SCM_EOL);
|
SCM_EOL);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!((SCM_UNBNDP (outp) && SCM_OPOUTFPORTP (scm_current_output_port ()))
|
if (!((SCM_UNBNDP (outp) && SCM_OPOUTFPORTP (scm_current_output_port ()))
|
||||||
|| SCM_OPOUTFPORTP (outp)))
|
|| SCM_OPOUTFPORTP (outp)))
|
||||||
{
|
{
|
||||||
|
@ -197,7 +201,7 @@ SCM_DEFINE (scm_readline, "%readline", 0, 4, 0,
|
||||||
|
|
||||||
scm_dynwind_begin (0);
|
scm_dynwind_begin (0);
|
||||||
scm_dynwind_unwind_handler (unwind_readline, NULL, 0);
|
scm_dynwind_unwind_handler (unwind_readline, NULL, 0);
|
||||||
|
|
||||||
ans = internal_readline (text);
|
ans = internal_readline (text);
|
||||||
|
|
||||||
scm_dynwind_end ();
|
scm_dynwind_end ();
|
||||||
|
@ -249,7 +253,7 @@ internal_readline (SCM text)
|
||||||
s = readline (prompt);
|
s = readline (prompt);
|
||||||
if (s)
|
if (s)
|
||||||
ret = scm_from_port_string (s, output_port);
|
ret = scm_from_port_string (s, output_port);
|
||||||
else
|
else
|
||||||
ret = SCM_EOF_VAL;
|
ret = SCM_EOF_VAL;
|
||||||
|
|
||||||
if (!SCM_UNBNDP (text))
|
if (!SCM_UNBNDP (text))
|
||||||
|
@ -287,10 +291,10 @@ scm_readline_init_ports (SCM inp, SCM outp)
|
||||||
{
|
{
|
||||||
if (SCM_UNBNDP (inp))
|
if (SCM_UNBNDP (inp))
|
||||||
inp = scm_current_input_port ();
|
inp = scm_current_input_port ();
|
||||||
|
|
||||||
if (SCM_UNBNDP (outp))
|
if (SCM_UNBNDP (outp))
|
||||||
outp = scm_current_output_port ();
|
outp = scm_current_output_port ();
|
||||||
|
|
||||||
if (!SCM_OPINFPORTP (inp)) {
|
if (!SCM_OPINFPORTP (inp)) {
|
||||||
scm_misc_error (0,
|
scm_misc_error (0,
|
||||||
"Input port is not open or not a file port",
|
"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),
|
(SCM text),
|
||||||
"")
|
"")
|
||||||
#define FUNC_NAME s_scm_add_history
|
#define FUNC_NAME s_scm_add_history
|
||||||
|
@ -327,7 +331,7 @@ SCM_DEFINE (scm_add_history, "add-history", 1, 0, 0,
|
||||||
#undef FUNC_NAME
|
#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),
|
(SCM file),
|
||||||
"")
|
"")
|
||||||
#define FUNC_NAME s_scm_read_history
|
#define FUNC_NAME s_scm_read_history
|
||||||
|
@ -343,7 +347,7 @@ SCM_DEFINE (scm_read_history, "read-history", 1, 0, 0,
|
||||||
#undef FUNC_NAME
|
#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),
|
(SCM file),
|
||||||
"")
|
"")
|
||||||
#define FUNC_NAME s_scm_write_history
|
#define FUNC_NAME s_scm_write_history
|
||||||
|
@ -358,7 +362,7 @@ SCM_DEFINE (scm_write_history, "write-history", 1, 0, 0,
|
||||||
}
|
}
|
||||||
#undef FUNC_NAME
|
#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.")
|
"Clear the history buffer of the readline machinery.")
|
||||||
#define FUNC_NAME s_scm_clear_history
|
#define FUNC_NAME s_scm_clear_history
|
||||||
|
@ -369,7 +373,7 @@ SCM_DEFINE (scm_clear_history, "clear-history", 0, 0, 0,
|
||||||
#undef FUNC_NAME
|
#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),
|
(SCM text, SCM continuep),
|
||||||
"")
|
"")
|
||||||
#define FUNC_NAME s_scm_filename_completion_function
|
#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 t = scm_from_locale_string (text);
|
||||||
SCM c = scm_from_bool (continuep);
|
SCM c = scm_from_bool (continuep);
|
||||||
res = scm_apply (compfunc, scm_list_2 (t, c), SCM_EOL);
|
res = scm_apply (compfunc, scm_list_2 (t, c), SCM_EOL);
|
||||||
|
|
||||||
if (scm_is_false (res))
|
if (scm_is_false (res))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
return scm_to_locale_string (res);
|
return scm_to_locale_string (res);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -525,7 +529,7 @@ scm_init_readline ()
|
||||||
rl_getc_function = current_input_getc;
|
rl_getc_function = current_input_getc;
|
||||||
#if defined (_RL_FUNCTION_TYPEDEF)
|
#if defined (_RL_FUNCTION_TYPEDEF)
|
||||||
rl_completion_entry_function = (rl_compentry_func_t*) completion_function;
|
rl_completion_entry_function = (rl_compentry_func_t*) completion_function;
|
||||||
#else
|
#else
|
||||||
rl_completion_entry_function = (Function*) completion_function;
|
rl_completion_entry_function = (Function*) completion_function;
|
||||||
#endif
|
#endif
|
||||||
rl_basic_word_break_characters = " \t\n\"'`;()";
|
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
|
#if defined (HAVE_DECL_RL_CATCH_SIGNALS) && HAVE_DECL_RL_CATCH_SIGNALS
|
||||||
rl_catch_signals = 0;
|
rl_catch_signals = 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* But let readline handle SIGWINCH. */
|
/* But let readline handle SIGWINCH. */
|
||||||
#if defined (HAVE_DECL_RL_CATCH_SIGWINCH) && HAVE_DECL_RL_CATCH_SIGWINCH
|
#if defined (HAVE_DECL_RL_CATCH_SIGWINCH) && HAVE_DECL_RL_CATCH_SIGWINCH
|
||||||
rl_catch_sigwinch = 1;
|
rl_catch_sigwinch = 1;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
reentry_barrier_mutex = scm_make_mutex ();
|
reentry_barrier_mutex = scm_make_mutex ();
|
||||||
scm_init_opts (scm_readline_options,
|
scm_init_opts (scm_readline_options,
|
||||||
scm_readline_opts);
|
scm_readline_opts);
|
||||||
|
rl_variable_bind ("enable-bracketed-paste",
|
||||||
|
SCM_READLINE_BRACKETED_PASTE ? "on" : "off");
|
||||||
|
|
||||||
#if HAVE_RL_GET_KEYMAP
|
#if HAVE_RL_GET_KEYMAP
|
||||||
init_bouncing_parens();
|
init_bouncing_parens();
|
||||||
#endif
|
#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_FILE_P scm_readline_opts[0].val
|
||||||
#define SCM_HISTORY_LENGTH scm_readline_opts[1].val
|
#define SCM_HISTORY_LENGTH scm_readline_opts[1].val
|
||||||
#define SCM_READLINE_BOUNCE_PARENS scm_readline_opts[2].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 SCM scm_readline_options (SCM setting);
|
||||||
SCM_RL_API void scm_readline_init_ports (SCM inp, SCM outp);
|
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!
|
## DO NOT EDIT! GENERATED AUTOMATICALLY!
|
||||||
## Process this file with automake to produce Makefile.in.
|
## 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
|
# 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
|
# 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.
|
# the same distribution terms as the rest of that program.
|
||||||
#
|
#
|
||||||
# Generated by gnulib-tool.
|
# 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 =
|
SUBDIRS =
|
||||||
noinst_HEADERS =
|
noinst_HEADERS =
|
||||||
|
@ -63,6 +63,7 @@ libgnu_la_LDFLAGS += $(ISNANL_LIBM)
|
||||||
libgnu_la_LDFLAGS += $(LDEXP_LIBM)
|
libgnu_la_LDFLAGS += $(LDEXP_LIBM)
|
||||||
libgnu_la_LDFLAGS += $(LIBSOCKET)
|
libgnu_la_LDFLAGS += $(LIBSOCKET)
|
||||||
libgnu_la_LDFLAGS += $(LIB_CLOCK_GETTIME)
|
libgnu_la_LDFLAGS += $(LIB_CLOCK_GETTIME)
|
||||||
|
libgnu_la_LDFLAGS += $(LIB_GETLOGIN)
|
||||||
libgnu_la_LDFLAGS += $(LIB_POLL)
|
libgnu_la_LDFLAGS += $(LIB_POLL)
|
||||||
libgnu_la_LDFLAGS += $(LIB_SELECT)
|
libgnu_la_LDFLAGS += $(LIB_SELECT)
|
||||||
libgnu_la_LDFLAGS += $(LOG1P_LIBM)
|
libgnu_la_LDFLAGS += $(LOG1P_LIBM)
|
||||||
|
@ -92,6 +93,12 @@ EXTRA_libgnu_la_SOURCES += accept.c
|
||||||
|
|
||||||
## end gnulib module accept
|
## end gnulib module accept
|
||||||
|
|
||||||
|
## begin gnulib module accept4
|
||||||
|
|
||||||
|
libgnu_la_SOURCES += accept4.c
|
||||||
|
|
||||||
|
## end gnulib module accept4
|
||||||
|
|
||||||
## begin gnulib module alignof
|
## begin gnulib module alignof
|
||||||
|
|
||||||
|
|
||||||
|
@ -101,9 +108,11 @@ EXTRA_DIST += alignof.h
|
||||||
|
|
||||||
## begin gnulib module alloca
|
## begin gnulib module alloca
|
||||||
|
|
||||||
|
if gl_GNULIB_ENABLED_alloca
|
||||||
|
|
||||||
libgnu_la_LIBADD += @LTALLOCA@
|
libgnu_la_LIBADD += @LTALLOCA@
|
||||||
libgnu_la_DEPENDENCIES += @LTALLOCA@
|
libgnu_la_DEPENDENCIES += @LTALLOCA@
|
||||||
|
endif
|
||||||
EXTRA_DIST += alloca.c
|
EXTRA_DIST += alloca.c
|
||||||
|
|
||||||
EXTRA_libgnu_la_SOURCES += alloca.c
|
EXTRA_libgnu_la_SOURCES += alloca.c
|
||||||
|
@ -176,6 +185,15 @@ EXTRA_DIST += arpa_inet.in.h
|
||||||
|
|
||||||
## end gnulib module arpa_inet
|
## 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
|
## begin gnulib module binary-io
|
||||||
|
|
||||||
libgnu_la_SOURCES += binary-io.h binary-io.c
|
libgnu_la_SOURCES += binary-io.h binary-io.c
|
||||||
|
@ -193,7 +211,9 @@ EXTRA_libgnu_la_SOURCES += bind.c
|
||||||
|
|
||||||
## begin gnulib module btowc
|
## begin gnulib module btowc
|
||||||
|
|
||||||
|
if gl_GNULIB_ENABLED_btowc
|
||||||
|
|
||||||
|
endif
|
||||||
EXTRA_DIST += btowc.c
|
EXTRA_DIST += btowc.c
|
||||||
|
|
||||||
EXTRA_libgnu_la_SOURCES += btowc.c
|
EXTRA_libgnu_la_SOURCES += btowc.c
|
||||||
|
@ -406,7 +426,9 @@ EXTRA_DIST += dosname.h
|
||||||
|
|
||||||
## begin gnulib module dup2
|
## begin gnulib module dup2
|
||||||
|
|
||||||
|
if gl_GNULIB_ENABLED_dup2
|
||||||
|
|
||||||
|
endif
|
||||||
EXTRA_DIST += dup2.c
|
EXTRA_DIST += dup2.c
|
||||||
|
|
||||||
EXTRA_libgnu_la_SOURCES += dup2.c
|
EXTRA_libgnu_la_SOURCES += dup2.c
|
||||||
|
@ -493,12 +515,23 @@ EXTRA_DIST += fcntl.in.h
|
||||||
|
|
||||||
## begin gnulib module fd-hook
|
## begin gnulib module fd-hook
|
||||||
|
|
||||||
|
if gl_GNULIB_ENABLED_43fe87a341d9b4b93c47c3ad819a5239
|
||||||
libgnu_la_SOURCES += fd-hook.c
|
libgnu_la_SOURCES += fd-hook.c
|
||||||
|
|
||||||
|
endif
|
||||||
EXTRA_DIST += fd-hook.h
|
EXTRA_DIST += fd-hook.h
|
||||||
|
|
||||||
## end gnulib module fd-hook
|
## 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
|
## begin gnulib module float
|
||||||
|
|
||||||
BUILT_SOURCES += $(FLOAT_H)
|
BUILT_SOURCES += $(FLOAT_H)
|
||||||
|
@ -645,8 +678,10 @@ EXTRA_libgnu_la_SOURCES += getsockopt.c
|
||||||
|
|
||||||
## begin gnulib module gettext-h
|
## begin gnulib module gettext-h
|
||||||
|
|
||||||
|
if gl_GNULIB_ENABLED_be453cec5eecf5731a274f2de7f2db36
|
||||||
libgnu_la_SOURCES += gettext.h
|
libgnu_la_SOURCES += gettext.h
|
||||||
|
|
||||||
|
endif
|
||||||
## end gnulib module gettext-h
|
## end gnulib module gettext-h
|
||||||
|
|
||||||
## begin gnulib module gettimeofday
|
## begin gnulib module gettimeofday
|
||||||
|
@ -699,9 +734,22 @@ EXTRA_DIST += $(top_srcdir)/build-aux/gnupload
|
||||||
## begin gnulib module gperf
|
## begin gnulib module gperf
|
||||||
|
|
||||||
GPERF = 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
|
## 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
|
## begin gnulib module havelib
|
||||||
|
|
||||||
|
|
||||||
|
@ -748,19 +796,19 @@ EXTRA_DIST += iconv.in.h
|
||||||
## begin gnulib module iconv_open
|
## begin gnulib module iconv_open
|
||||||
|
|
||||||
iconv_open-aix.h: iconv_open-aix.gperf
|
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
|
mv $(srcdir)/iconv_open-aix.h-t $(srcdir)/iconv_open-aix.h
|
||||||
iconv_open-hpux.h: iconv_open-hpux.gperf
|
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
|
mv $(srcdir)/iconv_open-hpux.h-t $(srcdir)/iconv_open-hpux.h
|
||||||
iconv_open-irix.h: iconv_open-irix.gperf
|
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
|
mv $(srcdir)/iconv_open-irix.h-t $(srcdir)/iconv_open-irix.h
|
||||||
iconv_open-osf.h: iconv_open-osf.gperf
|
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
|
mv $(srcdir)/iconv_open-osf.h-t $(srcdir)/iconv_open-osf.h
|
||||||
iconv_open-solaris.h: iconv_open-solaris.gperf
|
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
|
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
|
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
|
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
|
## 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
|
## begin gnulib module isfinite
|
||||||
|
|
||||||
|
|
||||||
|
@ -820,7 +877,9 @@ EXTRA_libgnu_la_SOURCES += isnan.c isnand.c
|
||||||
|
|
||||||
## begin gnulib module isnand-nolibm
|
## begin gnulib module isnand-nolibm
|
||||||
|
|
||||||
|
if gl_GNULIB_ENABLED_b1df7117b479d2da59d76deba468ee21
|
||||||
|
|
||||||
|
endif
|
||||||
EXTRA_DIST += float+.h isnan.c isnand-nolibm.h isnand.c
|
EXTRA_DIST += float+.h isnan.c isnand-nolibm.h isnand.c
|
||||||
|
|
||||||
EXTRA_libgnu_la_SOURCES += isnan.c 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
|
## begin gnulib module isnanf-nolibm
|
||||||
|
|
||||||
|
if gl_GNULIB_ENABLED_3f0e593033d1fc2c127581960f641b66
|
||||||
|
|
||||||
|
endif
|
||||||
EXTRA_DIST += float+.h isnan.c isnanf-nolibm.h isnanf.c
|
EXTRA_DIST += float+.h isnan.c isnanf-nolibm.h isnanf.c
|
||||||
|
|
||||||
EXTRA_libgnu_la_SOURCES += isnan.c 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
|
## begin gnulib module isnanl-nolibm
|
||||||
|
|
||||||
|
if gl_GNULIB_ENABLED_dbdf22868a5367f28bf18e0013ac6f8f
|
||||||
|
|
||||||
|
endif
|
||||||
EXTRA_DIST += float+.h isnan.c isnanl-nolibm.h isnanl.c
|
EXTRA_DIST += float+.h isnan.c isnanl-nolibm.h isnanl.c
|
||||||
|
|
||||||
EXTRA_libgnu_la_SOURCES += isnan.c isnanl.c
|
EXTRA_libgnu_la_SOURCES += isnan.c isnanl.c
|
||||||
|
@ -913,6 +976,34 @@ EXTRA_DIST += libunistring.valgrind
|
||||||
|
|
||||||
## end gnulib module libunistring
|
## 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
|
## begin gnulib module link
|
||||||
|
|
||||||
|
|
||||||
|
@ -1042,7 +1133,9 @@ EXTRA_DIST += locale.in.h
|
||||||
|
|
||||||
## begin gnulib module localeconv
|
## begin gnulib module localeconv
|
||||||
|
|
||||||
|
if gl_GNULIB_ENABLED_localeconv
|
||||||
|
|
||||||
|
endif
|
||||||
EXTRA_DIST += localeconv.c
|
EXTRA_DIST += localeconv.c
|
||||||
|
|
||||||
EXTRA_libgnu_la_SOURCES += localeconv.c
|
EXTRA_libgnu_la_SOURCES += localeconv.c
|
||||||
|
@ -1051,7 +1144,9 @@ EXTRA_libgnu_la_SOURCES += localeconv.c
|
||||||
|
|
||||||
## begin gnulib module log
|
## begin gnulib module log
|
||||||
|
|
||||||
|
if gl_GNULIB_ENABLED_log
|
||||||
|
|
||||||
|
endif
|
||||||
EXTRA_DIST += log.c
|
EXTRA_DIST += log.c
|
||||||
|
|
||||||
EXTRA_libgnu_la_SOURCES += 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_TRUNCF''@|$(HAVE_DECL_TRUNCF)|g' \
|
||||||
-e 's|@''HAVE_DECL_TRUNCL''@|$(HAVE_DECL_TRUNCL)|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_CBRTL''@|$(REPLACE_CBRTL)|g' \
|
||||||
-e 's|@''REPLACE_CEIL''@|$(REPLACE_CEIL)|g' \
|
-e 's|@''REPLACE_CEIL''@|$(REPLACE_CEIL)|g' \
|
||||||
-e 's|@''REPLACE_CEILF''@|$(REPLACE_CEILF)|g' \
|
-e 's|@''REPLACE_CEILF''@|$(REPLACE_CEILF)|g' \
|
||||||
-e 's|@''REPLACE_CEILL''@|$(REPLACE_CEILL)|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_EXPM1''@|$(REPLACE_EXPM1)|g' \
|
||||||
-e 's|@''REPLACE_EXPM1F''@|$(REPLACE_EXPM1F)|g' \
|
-e 's|@''REPLACE_EXPM1F''@|$(REPLACE_EXPM1F)|g' \
|
||||||
-e 's|@''REPLACE_EXP2''@|$(REPLACE_EXP2)|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_ROUNDL''@|$(REPLACE_ROUNDL)|g' \
|
||||||
-e 's|@''REPLACE_SIGNBIT''@|$(REPLACE_SIGNBIT)|g' \
|
-e 's|@''REPLACE_SIGNBIT''@|$(REPLACE_SIGNBIT)|g' \
|
||||||
-e 's|@''REPLACE_SIGNBIT_USING_GCC''@|$(REPLACE_SIGNBIT_USING_GCC)|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_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_TRUNC''@|$(REPLACE_TRUNC)|g' \
|
||||||
-e 's|@''REPLACE_TRUNCF''@|$(REPLACE_TRUNCF)|g' \
|
-e 's|@''REPLACE_TRUNCF''@|$(REPLACE_TRUNCF)|g' \
|
||||||
-e 's|@''REPLACE_TRUNCL''@|$(REPLACE_TRUNCL)|g' \
|
-e 's|@''REPLACE_TRUNCL''@|$(REPLACE_TRUNCL)|g' \
|
||||||
|
@ -1394,7 +1501,9 @@ EXTRA_DIST += math.in.h
|
||||||
|
|
||||||
## begin gnulib module mbrtowc
|
## begin gnulib module mbrtowc
|
||||||
|
|
||||||
|
if gl_GNULIB_ENABLED_mbrtowc
|
||||||
|
|
||||||
|
endif
|
||||||
EXTRA_DIST += mbrtowc.c
|
EXTRA_DIST += mbrtowc.c
|
||||||
|
|
||||||
EXTRA_libgnu_la_SOURCES += mbrtowc.c
|
EXTRA_libgnu_la_SOURCES += mbrtowc.c
|
||||||
|
@ -1403,7 +1512,9 @@ EXTRA_libgnu_la_SOURCES += mbrtowc.c
|
||||||
|
|
||||||
## begin gnulib module mbsinit
|
## begin gnulib module mbsinit
|
||||||
|
|
||||||
|
if gl_GNULIB_ENABLED_mbsinit
|
||||||
|
|
||||||
|
endif
|
||||||
EXTRA_DIST += mbsinit.c
|
EXTRA_DIST += mbsinit.c
|
||||||
|
|
||||||
EXTRA_libgnu_la_SOURCES += mbsinit.c
|
EXTRA_libgnu_la_SOURCES += mbsinit.c
|
||||||
|
@ -1412,7 +1523,9 @@ EXTRA_libgnu_la_SOURCES += mbsinit.c
|
||||||
|
|
||||||
## begin gnulib module mbtowc
|
## begin gnulib module mbtowc
|
||||||
|
|
||||||
|
if gl_GNULIB_ENABLED_mbtowc
|
||||||
|
|
||||||
|
endif
|
||||||
EXTRA_DIST += mbtowc-impl.h mbtowc.c
|
EXTRA_DIST += mbtowc-impl.h mbtowc.c
|
||||||
|
|
||||||
EXTRA_libgnu_la_SOURCES += mbtowc.c
|
EXTRA_libgnu_la_SOURCES += mbtowc.c
|
||||||
|
@ -1421,7 +1534,9 @@ EXTRA_libgnu_la_SOURCES += mbtowc.c
|
||||||
|
|
||||||
## begin gnulib module memchr
|
## begin gnulib module memchr
|
||||||
|
|
||||||
|
if gl_GNULIB_ENABLED_memchr
|
||||||
|
|
||||||
|
endif
|
||||||
EXTRA_DIST += memchr.c memchr.valgrind
|
EXTRA_DIST += memchr.c memchr.valgrind
|
||||||
|
|
||||||
EXTRA_libgnu_la_SOURCES += memchr.c
|
EXTRA_libgnu_la_SOURCES += memchr.c
|
||||||
|
@ -1437,14 +1552,36 @@ EXTRA_libgnu_la_SOURCES += mkdir.c
|
||||||
|
|
||||||
## end gnulib module mkdir
|
## 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
|
## begin gnulib module msvc-inval
|
||||||
|
|
||||||
|
@ -1557,7 +1694,9 @@ EXTRA_libgnu_la_SOURCES += open.c
|
||||||
|
|
||||||
## begin gnulib module pathmax
|
## begin gnulib module pathmax
|
||||||
|
|
||||||
|
if gl_GNULIB_ENABLED_pathmax
|
||||||
|
|
||||||
|
endif
|
||||||
EXTRA_DIST += pathmax.h
|
EXTRA_DIST += pathmax.h
|
||||||
|
|
||||||
## end gnulib module pathmax
|
## end gnulib module pathmax
|
||||||
|
@ -1626,7 +1765,9 @@ EXTRA_libgnu_la_SOURCES += putenv.c
|
||||||
|
|
||||||
## begin gnulib module raise
|
## begin gnulib module raise
|
||||||
|
|
||||||
|
if gl_GNULIB_ENABLED_raise
|
||||||
|
|
||||||
|
endif
|
||||||
EXTRA_DIST += raise.c
|
EXTRA_DIST += raise.c
|
||||||
|
|
||||||
EXTRA_libgnu_la_SOURCES += raise.c
|
EXTRA_libgnu_la_SOURCES += raise.c
|
||||||
|
@ -1698,7 +1839,9 @@ EXTRA_libgnu_la_SOURCES += rmdir.c
|
||||||
|
|
||||||
## begin gnulib module round
|
## begin gnulib module round
|
||||||
|
|
||||||
|
if gl_GNULIB_ENABLED_round
|
||||||
|
|
||||||
|
endif
|
||||||
EXTRA_DIST += round.c
|
EXTRA_DIST += round.c
|
||||||
|
|
||||||
EXTRA_libgnu_la_SOURCES += round.c
|
EXTRA_libgnu_la_SOURCES += round.c
|
||||||
|
@ -1725,14 +1868,18 @@ EXTRA_libgnu_la_SOURCES += safe-read.c
|
||||||
|
|
||||||
## begin gnulib module same-inode
|
## begin gnulib module same-inode
|
||||||
|
|
||||||
|
if gl_GNULIB_ENABLED_9bc5f216d57e231e4834049d67d0db62
|
||||||
|
|
||||||
|
endif
|
||||||
EXTRA_DIST += same-inode.h
|
EXTRA_DIST += same-inode.h
|
||||||
|
|
||||||
## end gnulib module same-inode
|
## end gnulib module same-inode
|
||||||
|
|
||||||
## begin gnulib module secure_getenv
|
## begin gnulib module secure_getenv
|
||||||
|
|
||||||
|
if gl_GNULIB_ENABLED_secure_getenv
|
||||||
|
|
||||||
|
endif
|
||||||
EXTRA_DIST += secure_getenv.c
|
EXTRA_DIST += secure_getenv.c
|
||||||
|
|
||||||
EXTRA_libgnu_la_SOURCES += secure_getenv.c
|
EXTRA_libgnu_la_SOURCES += secure_getenv.c
|
||||||
|
@ -1837,7 +1984,9 @@ EXTRA_DIST += signal.in.h
|
||||||
|
|
||||||
## begin gnulib module signbit
|
## begin gnulib module signbit
|
||||||
|
|
||||||
|
if gl_GNULIB_ENABLED_signbit
|
||||||
|
|
||||||
|
endif
|
||||||
EXTRA_DIST += float+.h signbitd.c signbitf.c signbitl.c
|
EXTRA_DIST += float+.h signbitd.c signbitf.c signbitl.c
|
||||||
|
|
||||||
EXTRA_libgnu_la_SOURCES += 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
|
## begin gnulib module size_max
|
||||||
|
|
||||||
|
if gl_GNULIB_ENABLED_size_max
|
||||||
libgnu_la_SOURCES += size_max.h
|
libgnu_la_SOURCES += size_max.h
|
||||||
|
|
||||||
|
endif
|
||||||
## end gnulib module size_max
|
## end gnulib module size_max
|
||||||
|
|
||||||
## begin gnulib module snippet/_Noreturn
|
## 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
|
## 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
|
## begin gnulib module snippet/warn-on-use
|
||||||
|
|
||||||
BUILT_SOURCES += warn-on-use.h
|
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
|
## begin gnulib module snprintf
|
||||||
|
|
||||||
|
if gl_GNULIB_ENABLED_snprintf
|
||||||
|
|
||||||
|
endif
|
||||||
EXTRA_DIST += snprintf.c
|
EXTRA_DIST += snprintf.c
|
||||||
|
|
||||||
EXTRA_libgnu_la_SOURCES += snprintf.c
|
EXTRA_libgnu_la_SOURCES += snprintf.c
|
||||||
|
@ -1976,15 +2104,19 @@ EXTRA_libgnu_la_SOURCES += socket.c
|
||||||
|
|
||||||
## begin gnulib module sockets
|
## begin gnulib module sockets
|
||||||
|
|
||||||
|
if gl_GNULIB_ENABLED_sockets
|
||||||
libgnu_la_SOURCES += sockets.h sockets.c
|
libgnu_la_SOURCES += sockets.h sockets.c
|
||||||
|
|
||||||
|
endif
|
||||||
EXTRA_DIST += w32sock.h
|
EXTRA_DIST += w32sock.h
|
||||||
|
|
||||||
## end gnulib module sockets
|
## end gnulib module sockets
|
||||||
|
|
||||||
## begin gnulib module stat
|
## begin gnulib module stat
|
||||||
|
|
||||||
|
if gl_GNULIB_ENABLED_stat
|
||||||
|
|
||||||
|
endif
|
||||||
EXTRA_DIST += stat.c
|
EXTRA_DIST += stat.c
|
||||||
|
|
||||||
EXTRA_libgnu_la_SOURCES += 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_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \
|
||||||
-e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \
|
-e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \
|
||||||
-e 's|@''NEXT_STDDEF_H''@|$(NEXT_STDDEF_H)|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|@''HAVE_WCHAR_T''@|$(HAVE_WCHAR_T)|g' \
|
||||||
-e 's|@''REPLACE_NULL''@|$(REPLACE_NULL)|g' \
|
-e 's|@''REPLACE_NULL''@|$(REPLACE_NULL)|g' \
|
||||||
< $(srcdir)/stddef.in.h; \
|
< $(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_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \
|
||||||
-e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \
|
-e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \
|
||||||
-e 's|@''NEXT_STDINT_H''@|$(NEXT_STDINT_H)|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_SYS_TYPES_H''@/$(HAVE_SYS_TYPES_H)/g' \
|
||||||
-e 's/@''HAVE_INTTYPES_H''@/$(HAVE_INTTYPES_H)/g' \
|
-e 's/@''HAVE_INTTYPES_H''@/$(HAVE_INTTYPES_H)/g' \
|
||||||
-e 's/@''HAVE_SYS_INTTYPES_H''@/$(HAVE_SYS_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/@''BITSIZEOF_WINT_T''@/$(BITSIZEOF_WINT_T)/g' \
|
||||||
-e 's/@''HAVE_SIGNED_WINT_T''@/$(HAVE_SIGNED_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/@''WINT_T_SUFFIX''@/$(WINT_T_SUFFIX)/g' \
|
||||||
|
-e 's/@''GNULIB_OVERRIDES_WINT_T''@/$(GNULIB_OVERRIDES_WINT_T)/g' \
|
||||||
< $(srcdir)/stdint.in.h; \
|
< $(srcdir)/stdint.in.h; \
|
||||||
} > $@-t && \
|
} > $@-t && \
|
||||||
mv $@-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''@/$(GNULIB_PTSNAME)/g' \
|
||||||
-e 's/@''GNULIB_PTSNAME_R''@/$(GNULIB_PTSNAME_R)/g' \
|
-e 's/@''GNULIB_PTSNAME_R''@/$(GNULIB_PTSNAME_R)/g' \
|
||||||
-e 's/@''GNULIB_PUTENV''@/$(GNULIB_PUTENV)/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''@/$(GNULIB_RANDOM)/g' \
|
||||||
-e 's/@''GNULIB_RANDOM_R''@/$(GNULIB_RANDOM_R)/g' \
|
-e 's/@''GNULIB_RANDOM_R''@/$(GNULIB_RANDOM_R)/g' \
|
||||||
-e 's/@''GNULIB_REALLOC_POSIX''@/$(GNULIB_REALLOC_POSIX)/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_POSIX_OPENPT''@|$(HAVE_POSIX_OPENPT)|g' \
|
||||||
-e 's|@''HAVE_PTSNAME''@|$(HAVE_PTSNAME)|g' \
|
-e 's|@''HAVE_PTSNAME''@|$(HAVE_PTSNAME)|g' \
|
||||||
-e 's|@''HAVE_PTSNAME_R''@|$(HAVE_PTSNAME_R)|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''@|$(HAVE_RANDOM)|g' \
|
||||||
-e 's|@''HAVE_RANDOM_H''@|$(HAVE_RANDOM_H)|g' \
|
-e 's|@''HAVE_RANDOM_H''@|$(HAVE_RANDOM_H)|g' \
|
||||||
-e 's|@''HAVE_RANDOM_R''@|$(HAVE_RANDOM_R)|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''@|$(REPLACE_PTSNAME)|g' \
|
||||||
-e 's|@''REPLACE_PTSNAME_R''@|$(REPLACE_PTSNAME_R)|g' \
|
-e 's|@''REPLACE_PTSNAME_R''@|$(REPLACE_PTSNAME_R)|g' \
|
||||||
-e 's|@''REPLACE_PUTENV''@|$(REPLACE_PUTENV)|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_RANDOM_R''@|$(REPLACE_RANDOM_R)|g' \
|
||||||
-e 's|@''REPLACE_REALLOC''@|$(REPLACE_REALLOC)|g' \
|
-e 's|@''REPLACE_REALLOC''@|$(REPLACE_REALLOC)|g' \
|
||||||
-e 's|@''REPLACE_REALPATH''@|$(REPLACE_REALPATH)|g' \
|
-e 's|@''REPLACE_REALPATH''@|$(REPLACE_REALPATH)|g' \
|
||||||
|
@ -2358,7 +2496,9 @@ EXTRA_DIST += stdlib.in.h
|
||||||
|
|
||||||
## begin gnulib module strdup-posix
|
## begin gnulib module strdup-posix
|
||||||
|
|
||||||
|
if gl_GNULIB_ENABLED_f9850631dca91859e9cddac9359921c0
|
||||||
|
|
||||||
|
endif
|
||||||
EXTRA_DIST += strdup.c
|
EXTRA_DIST += strdup.c
|
||||||
|
|
||||||
EXTRA_libgnu_la_SOURCES += strdup.c
|
EXTRA_libgnu_la_SOURCES += strdup.c
|
||||||
|
@ -2367,7 +2507,9 @@ EXTRA_libgnu_la_SOURCES += strdup.c
|
||||||
|
|
||||||
## begin gnulib module streq
|
## begin gnulib module streq
|
||||||
|
|
||||||
|
if gl_GNULIB_ENABLED_streq
|
||||||
|
|
||||||
|
endif
|
||||||
EXTRA_DIST += streq.h
|
EXTRA_DIST += streq.h
|
||||||
|
|
||||||
## end gnulib module streq
|
## end gnulib module streq
|
||||||
|
@ -2786,8 +2928,10 @@ EXTRA_DIST += sys_uio.in.h
|
||||||
|
|
||||||
## begin gnulib module tempname
|
## begin gnulib module tempname
|
||||||
|
|
||||||
|
if gl_GNULIB_ENABLED_tempname
|
||||||
libgnu_la_SOURCES += tempname.c
|
libgnu_la_SOURCES += tempname.c
|
||||||
|
|
||||||
|
endif
|
||||||
EXTRA_DIST += tempname.h
|
EXTRA_DIST += tempname.h
|
||||||
|
|
||||||
## end gnulib module tempname
|
## 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_STRPTIME''@/$(GNULIB_STRPTIME)/g' \
|
||||||
-e 's/@''GNULIB_TIMEGM''@/$(GNULIB_TIMEGM)/g' \
|
-e 's/@''GNULIB_TIMEGM''@/$(GNULIB_TIMEGM)/g' \
|
||||||
-e 's/@''GNULIB_TIME_R''@/$(GNULIB_TIME_R)/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_DECL_LOCALTIME_R''@|$(HAVE_DECL_LOCALTIME_R)|g' \
|
||||||
-e 's|@''HAVE_NANOSLEEP''@|$(HAVE_NANOSLEEP)|g' \
|
-e 's|@''HAVE_NANOSLEEP''@|$(HAVE_NANOSLEEP)|g' \
|
||||||
-e 's|@''HAVE_STRPTIME''@|$(HAVE_STRPTIME)|g' \
|
-e 's|@''HAVE_STRPTIME''@|$(HAVE_STRPTIME)|g' \
|
||||||
-e 's|@''HAVE_TIMEGM''@|$(HAVE_TIMEGM)|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_GMTIME''@|$(REPLACE_GMTIME)|g' \
|
||||||
-e 's|@''REPLACE_LOCALTIME''@|$(REPLACE_LOCALTIME)|g' \
|
-e 's|@''REPLACE_LOCALTIME''@|$(REPLACE_LOCALTIME)|g' \
|
||||||
-e 's|@''REPLACE_LOCALTIME_R''@|$(REPLACE_LOCALTIME_R)|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|@''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|@''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|@''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 '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \
|
||||||
-e '/definition of _GL_ARG_NONNULL/r $(ARG_NONNULL_H)' \
|
-e '/definition of _GL_ARG_NONNULL/r $(ARG_NONNULL_H)' \
|
||||||
-e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_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
|
## begin gnulib module time_r
|
||||||
|
|
||||||
|
if gl_GNULIB_ENABLED_time_r
|
||||||
|
|
||||||
|
endif
|
||||||
EXTRA_DIST += time_r.c
|
EXTRA_DIST += time_r.c
|
||||||
|
|
||||||
EXTRA_libgnu_la_SOURCES += time_r.c
|
EXTRA_libgnu_la_SOURCES += time_r.c
|
||||||
|
|
||||||
## end gnulib module time_r
|
## 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
|
## 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_GETDTABLESIZE''@|$(HAVE_GETDTABLESIZE)|g' \
|
||||||
-e 's|@''HAVE_GETGROUPS''@|$(HAVE_GETGROUPS)|g' \
|
-e 's|@''HAVE_GETGROUPS''@|$(HAVE_GETGROUPS)|g' \
|
||||||
-e 's|@''HAVE_GETHOSTNAME''@|$(HAVE_GETHOSTNAME)|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_GETPAGESIZE''@|$(HAVE_GETPAGESIZE)|g' \
|
||||||
-e 's|@''HAVE_GROUP_MEMBER''@|$(HAVE_GROUP_MEMBER)|g' \
|
-e 's|@''HAVE_GROUP_MEMBER''@|$(HAVE_GROUP_MEMBER)|g' \
|
||||||
-e 's|@''HAVE_LCHOWN''@|$(HAVE_LCHOWN)|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_FCHDIR''@|$(HAVE_DECL_FCHDIR)|g' \
|
||||||
-e 's|@''HAVE_DECL_FDATASYNC''@|$(HAVE_DECL_FDATASYNC)|g' \
|
-e 's|@''HAVE_DECL_FDATASYNC''@|$(HAVE_DECL_FDATASYNC)|g' \
|
||||||
-e 's|@''HAVE_DECL_GETDOMAINNAME''@|$(HAVE_DECL_GETDOMAINNAME)|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_GETLOGIN_R''@|$(HAVE_DECL_GETLOGIN_R)|g' \
|
||||||
-e 's|@''HAVE_DECL_GETPAGESIZE''@|$(HAVE_DECL_GETPAGESIZE)|g' \
|
-e 's|@''HAVE_DECL_GETPAGESIZE''@|$(HAVE_DECL_GETPAGESIZE)|g' \
|
||||||
-e 's|@''HAVE_DECL_GETUSERSHELL''@|$(HAVE_DECL_GETUSERSHELL)|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_PWRITE''@|$(REPLACE_PWRITE)|g' \
|
||||||
-e 's|@''REPLACE_READ''@|$(REPLACE_READ)|g' \
|
-e 's|@''REPLACE_READ''@|$(REPLACE_READ)|g' \
|
||||||
-e 's|@''REPLACE_READLINK''@|$(REPLACE_READLINK)|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_RMDIR''@|$(REPLACE_RMDIR)|g' \
|
||||||
-e 's|@''REPLACE_SLEEP''@|$(REPLACE_SLEEP)|g' \
|
-e 's|@''REPLACE_SLEEP''@|$(REPLACE_SLEEP)|g' \
|
||||||
-e 's|@''REPLACE_SYMLINK''@|$(REPLACE_SYMLINK)|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_TTYNAME_R''@|$(REPLACE_TTYNAME_R)|g' \
|
||||||
-e 's|@''REPLACE_UNLINK''@|$(REPLACE_UNLINK)|g' \
|
-e 's|@''REPLACE_UNLINK''@|$(REPLACE_UNLINK)|g' \
|
||||||
-e 's|@''REPLACE_UNLINKAT''@|$(REPLACE_UNLINKAT)|g' \
|
-e 's|@''REPLACE_UNLINKAT''@|$(REPLACE_UNLINKAT)|g' \
|
||||||
|
@ -3016,77 +3187,16 @@ EXTRA_DIST += unistd.in.h
|
||||||
|
|
||||||
## end gnulib module unistd
|
## 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
|
endif
|
||||||
|
EXTRA_DIST += unsetenv.c
|
||||||
|
|
||||||
## end gnulib module unistr/u8-mbtouc
|
EXTRA_libgnu_la_SOURCES += unsetenv.c
|
||||||
|
|
||||||
## begin gnulib module unistr/u8-mbtouc-unsafe
|
## end gnulib module unsetenv
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
## begin gnulib module useless-if-before-free
|
## 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
|
## 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_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
|
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|@''HAVE_FEATURES_H''@|$(HAVE_FEATURES_H)|g' \
|
||||||
-e 's|@''NEXT_WCHAR_H''@|$(NEXT_WCHAR_H)|g' \
|
-e 's|@''NEXT_WCHAR_H''@|$(NEXT_WCHAR_H)|g' \
|
||||||
-e 's|@''HAVE_WCHAR_H''@|$(HAVE_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_BTOWC''@/$(GNULIB_BTOWC)/g' \
|
||||||
-e 's/@''GNULIB_WCTOB''@/$(GNULIB_WCTOB)/g' \
|
-e 's/@''GNULIB_WCTOB''@/$(GNULIB_WCTOB)/g' \
|
||||||
-e 's/@''GNULIB_MBSINIT''@/$(GNULIB_MBSINIT)/g' \
|
-e 's/@''GNULIB_MBSINIT''@/$(GNULIB_MBSINIT)/g' \
|
||||||
|
@ -3250,7 +3363,9 @@ EXTRA_DIST += wchar.in.h
|
||||||
|
|
||||||
## begin gnulib module wcrtomb
|
## begin gnulib module wcrtomb
|
||||||
|
|
||||||
|
if gl_GNULIB_ENABLED_wcrtomb
|
||||||
|
|
||||||
|
endif
|
||||||
EXTRA_DIST += wcrtomb.c
|
EXTRA_DIST += wcrtomb.c
|
||||||
|
|
||||||
EXTRA_libgnu_la_SOURCES += wcrtomb.c
|
EXTRA_libgnu_la_SOURCES += wcrtomb.c
|
||||||
|
@ -3259,6 +3374,7 @@ EXTRA_libgnu_la_SOURCES += wcrtomb.c
|
||||||
|
|
||||||
## begin gnulib module wctype-h
|
## begin gnulib module wctype-h
|
||||||
|
|
||||||
|
if gl_GNULIB_ENABLED_3dcce957eadc896e63ab5f137947b410
|
||||||
BUILT_SOURCES += wctype.h
|
BUILT_SOURCES += wctype.h
|
||||||
libgnu_la_SOURCES += wctype-h.c
|
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_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \
|
||||||
-e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \
|
-e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \
|
||||||
-e 's|@''NEXT_WCTYPE_H''@|$(NEXT_WCTYPE_H)|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_ISWBLANK''@/$(GNULIB_ISWBLANK)/g' \
|
||||||
-e 's/@''GNULIB_WCTYPE''@/$(GNULIB_WCTYPE)/g' \
|
-e 's/@''GNULIB_WCTYPE''@/$(GNULIB_WCTYPE)/g' \
|
||||||
-e 's/@''GNULIB_ISWCTYPE''@/$(GNULIB_ISWCTYPE)/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 $@
|
mv $@-t $@
|
||||||
MOSTLYCLEANFILES += wctype.h wctype.h-t
|
MOSTLYCLEANFILES += wctype.h wctype.h-t
|
||||||
|
|
||||||
|
endif
|
||||||
EXTRA_DIST += wctype.in.h
|
EXTRA_DIST += wctype.in.h
|
||||||
|
|
||||||
## end gnulib module wctype-h
|
## end gnulib module wctype-h
|
||||||
|
@ -3306,10 +3424,19 @@ EXTRA_libgnu_la_SOURCES += write.c
|
||||||
|
|
||||||
## end gnulib module write
|
## end gnulib module write
|
||||||
|
|
||||||
|
## begin gnulib module xalloc-oversized
|
||||||
|
|
||||||
|
|
||||||
|
EXTRA_DIST += xalloc-oversized.h
|
||||||
|
|
||||||
|
## end gnulib module xalloc-oversized
|
||||||
|
|
||||||
## begin gnulib module xsize
|
## begin gnulib module xsize
|
||||||
|
|
||||||
|
if gl_GNULIB_ENABLED_xsize
|
||||||
libgnu_la_SOURCES += xsize.h xsize.c
|
libgnu_la_SOURCES += xsize.h xsize.c
|
||||||
|
|
||||||
|
endif
|
||||||
## end gnulib module xsize
|
## end gnulib module xsize
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* accept.c --- wrappers for Windows accept function
|
/* 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
|
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
|
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.
|
/* 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
|
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
|
it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* Memory allocation on the stack.
|
/* 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.
|
Inc.
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify it
|
This program is free software; you can redistribute it and/or modify it
|
||||||
|
@ -51,6 +51,8 @@ extern "C"
|
||||||
void *_alloca (unsigned short);
|
void *_alloca (unsigned short);
|
||||||
# pragma intrinsic (_alloca)
|
# pragma intrinsic (_alloca)
|
||||||
# define alloca _alloca
|
# define alloca _alloca
|
||||||
|
# elif defined __MVS__
|
||||||
|
# include <stdlib.h>
|
||||||
# else
|
# else
|
||||||
# include <stddef.h>
|
# include <stddef.h>
|
||||||
# ifdef __cplusplus
|
# ifdef __cplusplus
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* A GNU-like <arpa/inet.h>.
|
/* 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
|
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
|
it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/* Formatted output to strings.
|
/* 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
|
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
|
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
|
/* 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.
|
Foundation, Inc.
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
#define BINARY_IO_INLINE _GL_EXTERN_INLINE
|
#define BINARY_IO_INLINE _GL_EXTERN_INLINE
|
||||||
#include "binary-io.h"
|
#include "binary-io.h"
|
||||||
|
typedef int dummy;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/* Binary mode I/O.
|
/* 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
|
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
|
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);
|
/* SET_BINARY (fd);
|
||||||
changes the file descriptor fd to perform binary I/O. */
|
changes the file descriptor fd to perform binary I/O. */
|
||||||
#ifdef __DJGPP__
|
#if defined __DJGPP__ || defined __EMX__
|
||||||
# include <unistd.h> /* declares isatty() */
|
# include <unistd.h> /* declares isatty() */
|
||||||
/* Avoid putting stdin/stdout in binary mode if it is connected to
|
/* Avoid putting stdin/stdout in binary mode if it is connected to
|
||||||
the console, because that would make it impossible for the user
|
the console, because that would make it impossible for the user
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* bind.c --- wrappers for Windows bind function
|
/* 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
|
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
|
it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/* Convert unibyte character to wide character.
|
/* 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.
|
Written by Bruno Haible <bruno@clisp.org>, 2008.
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/* byteswap.h - Byte swapping
|
/* 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.
|
Written by Oskar Liljeblad <oskar@osk.mine.nu>, 2005.
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
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>
|
#include <config.h>
|
||||||
|
#define C_CTYPE_INLINE _GL_EXTERN_INLINE
|
||||||
/* Specification. */
|
|
||||||
#define NO_C_CTYPE_MACROS
|
|
||||||
#include "c-ctype.h"
|
#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
|
<ctype.h> functions' behaviour depends on the current locale set via
|
||||||
setlocale.
|
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
|
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
|
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>
|
#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
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
@ -39,38 +46,6 @@ extern "C" {
|
||||||
characters. */
|
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) \
|
#if (' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \
|
||||||
&& ('%' == 37) && ('&' == 38) && ('\'' == 39) && ('(' == 40) \
|
&& ('%' == 37) && ('&' == 38) && ('\'' == 39) && ('(' == 40) \
|
||||||
&& (')' == 41) && ('*' == 42) && ('+' == 43) && (',' == 44) \
|
&& (')' == 41) && ('*' == 42) && ('+' == 43) && (',' == 44) \
|
||||||
|
@ -96,11 +71,84 @@ extern "C" {
|
||||||
&& ('{' == 123) && ('|' == 124) && ('}' == 125) && ('~' == 126)
|
&& ('{' == 123) && ('|' == 124) && ('}' == 125) && ('~' == 126)
|
||||||
/* The character set is ASCII or one of its variants or extensions, not EBCDIC.
|
/* The character set is ASCII or one of its variants or extensions, not EBCDIC.
|
||||||
Testing the value of '\n' and '\r' is not relevant. */
|
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
|
#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
|
/* 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
|
of the 'unsigned char' type, the functions here operate on values that are
|
||||||
|
@ -117,179 +165,202 @@ extern "C" {
|
||||||
if (c_isalpha (*s)) ...
|
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;
|
C_CTYPE_INLINE bool
|
||||||
extern bool c_isalpha (int c) _GL_ATTRIBUTE_CONST;
|
c_isalpha (int c)
|
||||||
extern bool c_isblank (int c) _GL_ATTRIBUTE_CONST;
|
{
|
||||||
extern bool c_iscntrl (int c) _GL_ATTRIBUTE_CONST;
|
switch (c)
|
||||||
extern bool c_isdigit (int c) _GL_ATTRIBUTE_CONST;
|
{
|
||||||
extern bool c_islower (int c) _GL_ATTRIBUTE_CONST;
|
_C_CTYPE_LOWER:
|
||||||
extern bool c_isgraph (int c) _GL_ATTRIBUTE_CONST;
|
_C_CTYPE_UPPER:
|
||||||
extern bool c_isprint (int c) _GL_ATTRIBUTE_CONST;
|
return true;
|
||||||
extern bool c_ispunct (int c) _GL_ATTRIBUTE_CONST;
|
default:
|
||||||
extern bool c_isspace (int c) _GL_ATTRIBUTE_CONST;
|
return false;
|
||||||
extern bool c_isupper (int c) _GL_ATTRIBUTE_CONST;
|
}
|
||||||
extern bool c_isxdigit (int c) _GL_ATTRIBUTE_CONST;
|
}
|
||||||
|
|
||||||
extern int c_tolower (int c) _GL_ATTRIBUTE_CONST;
|
/* The function isascii is not locale dependent.
|
||||||
extern int c_toupper (int c) _GL_ATTRIBUTE_CONST;
|
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__ \
|
C_CTYPE_INLINE bool
|
||||||
&& !defined __OPTIMIZE_SIZE__ && !defined NO_C_CTYPE_MACROS)
|
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
|
C_CTYPE_INLINE bool
|
||||||
#define c_isascii(c) \
|
c_isgraph (int c)
|
||||||
({ int __c = (c); \
|
{
|
||||||
(__c >= 0x00 && __c <= 0x7f); \
|
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_INLINE bool
|
||||||
&& C_CTYPE_CONSECUTIVE_UPPERCASE && C_CTYPE_CONSECUTIVE_LOWERCASE
|
c_islower (int c)
|
||||||
#if C_CTYPE_ASCII
|
{
|
||||||
#undef c_isalnum
|
switch (c)
|
||||||
#define c_isalnum(c) \
|
{
|
||||||
({ int __c = (c); \
|
_C_CTYPE_LOWER:
|
||||||
((__c >= '0' && __c <= '9') \
|
return true;
|
||||||
|| ((__c & ~0x20) >= 'A' && (__c & ~0x20) <= 'Z')); \
|
default:
|
||||||
})
|
return false;
|
||||||
#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
|
|
||||||
|
|
||||||
#if C_CTYPE_CONSECUTIVE_UPPERCASE && C_CTYPE_CONSECUTIVE_LOWERCASE
|
C_CTYPE_INLINE bool
|
||||||
#if C_CTYPE_ASCII
|
c_isprint (int c)
|
||||||
#undef c_isalpha
|
{
|
||||||
#define c_isalpha(c) \
|
switch (c)
|
||||||
({ int __c = (c); \
|
{
|
||||||
((__c & ~0x20) >= 'A' && (__c & ~0x20) <= 'Z'); \
|
case ' ':
|
||||||
})
|
_C_CTYPE_DIGIT:
|
||||||
#else
|
_C_CTYPE_LOWER:
|
||||||
#undef c_isalpha
|
_C_CTYPE_PUNCT:
|
||||||
#define c_isalpha(c) \
|
_C_CTYPE_UPPER:
|
||||||
({ int __c = (c); \
|
return true;
|
||||||
((__c >= 'A' && __c <= 'Z') || (__c >= 'a' && __c <= 'z')); \
|
default:
|
||||||
})
|
return false;
|
||||||
#endif
|
}
|
||||||
#endif
|
}
|
||||||
|
|
||||||
#undef c_isblank
|
C_CTYPE_INLINE bool
|
||||||
#define c_isblank(c) \
|
c_ispunct (int c)
|
||||||
({ int __c = (c); \
|
{
|
||||||
(__c == ' ' || __c == '\t'); \
|
switch (c)
|
||||||
})
|
{
|
||||||
|
_C_CTYPE_PUNCT:
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#if C_CTYPE_ASCII
|
C_CTYPE_INLINE bool
|
||||||
#undef c_iscntrl
|
c_isspace (int c)
|
||||||
#define c_iscntrl(c) \
|
{
|
||||||
({ int __c = (c); \
|
switch (c)
|
||||||
((__c & ~0x1f) == 0 || __c == 0x7f); \
|
{
|
||||||
})
|
case ' ': case '\t': case '\n': case '\v': case '\f': case '\r':
|
||||||
#endif
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#if C_CTYPE_CONSECUTIVE_DIGITS
|
C_CTYPE_INLINE bool
|
||||||
#undef c_isdigit
|
c_isupper (int c)
|
||||||
#define c_isdigit(c) \
|
{
|
||||||
({ int __c = (c); \
|
switch (c)
|
||||||
(__c >= '0' && __c <= '9'); \
|
{
|
||||||
})
|
_C_CTYPE_UPPER:
|
||||||
#endif
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#if C_CTYPE_CONSECUTIVE_LOWERCASE
|
C_CTYPE_INLINE bool
|
||||||
#undef c_islower
|
c_isxdigit (int c)
|
||||||
#define c_islower(c) \
|
{
|
||||||
({ int __c = (c); \
|
switch (c)
|
||||||
(__c >= 'a' && __c <= 'z'); \
|
{
|
||||||
})
|
_C_CTYPE_DIGIT:
|
||||||
#endif
|
_C_CTYPE_A_THRU_F:
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#if C_CTYPE_ASCII
|
C_CTYPE_INLINE int
|
||||||
#undef c_isgraph
|
c_tolower (int c)
|
||||||
#define c_isgraph(c) \
|
{
|
||||||
({ int __c = (c); \
|
switch (c)
|
||||||
(__c >= '!' && __c <= '~'); \
|
{
|
||||||
})
|
_C_CTYPE_UPPER:
|
||||||
#endif
|
return c - 'A' + 'a';
|
||||||
|
default:
|
||||||
#if C_CTYPE_ASCII
|
return c;
|
||||||
#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_toupper (int c)
|
||||||
|
{
|
||||||
|
switch (c)
|
||||||
|
{
|
||||||
|
_C_CTYPE_LOWER:
|
||||||
|
return c - 'a' + 'A';
|
||||||
|
default:
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
_GL_INLINE_HEADER_END
|
||||||
|
|
||||||
#endif /* C_CTYPE_H */
|
#endif /* C_CTYPE_H */
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/* Case-insensitive string comparison functions in C locale.
|
/* 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.
|
Foundation, Inc.
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
|
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