Compare commits
2 Commits
main
...
srfi13and1
Author | SHA1 | Date |
---|---|---|
![]() |
838b110f01 | |
![]() |
e5a2148d4a |
143
RELEASE
143
RELEASE
|
@ -9,6 +9,12 @@ release 0.5.3. (Emacs should display this document is in outline mode. Say
|
||||||
c-h m for instructions on how to move through it by sections (e.g., c-c c-n,
|
c-h m for instructions on how to move through it by sections (e.g., c-c c-n,
|
||||||
c-c c-p).)
|
c-c c-p).)
|
||||||
|
|
||||||
|
This release is the first new release of scsh in over a year. We've been
|
||||||
|
using it, and have had no problems. However, we only recommend eager users
|
||||||
|
download it. We'll upgrade it to a 0.5.3 release after a week or two, when
|
||||||
|
this release has been shaken out.
|
||||||
|
|
||||||
|
|
||||||
* Contents
|
* Contents
|
||||||
==========
|
==========
|
||||||
What is scsh
|
What is scsh
|
||||||
|
@ -21,7 +27,6 @@ The World-Wide What?
|
||||||
New in this release
|
New in this release
|
||||||
Scsh is now "open source."
|
Scsh is now "open source."
|
||||||
Scsh is now on Win32
|
Scsh is now on Win32
|
||||||
Scsh is now on Mac OS X
|
|
||||||
CVS repository will be public-readable
|
CVS repository will be public-readable
|
||||||
New char-sets and char-set operations
|
New char-sets and char-set operations
|
||||||
New regular expression system
|
New regular expression system
|
||||||
|
@ -34,8 +39,7 @@ Thanks
|
||||||
* What is scsh
|
* What is scsh
|
||||||
==============
|
==============
|
||||||
Scsh is a broad-spectrum systems-programming environment for Unix embedded
|
Scsh is a broad-spectrum systems-programming environment for Unix embedded
|
||||||
in R4RS Scheme. It has an open-source copyright, and runs on most major
|
in R4RS Scheme.
|
||||||
Unix systems.
|
|
||||||
|
|
||||||
** Scsh as a scripting language
|
** Scsh as a scripting language
|
||||||
-------------------------------
|
-------------------------------
|
||||||
|
@ -103,11 +107,11 @@ Unix platforms. We currently have scsh implementations for:
|
||||||
IRIX
|
IRIX
|
||||||
Linux
|
Linux
|
||||||
NetBSD
|
NetBSD
|
||||||
|
NeXTStep
|
||||||
Solaris
|
Solaris
|
||||||
SunOS
|
SunOS
|
||||||
Ultrix
|
Ultrix
|
||||||
Win32
|
Win32
|
||||||
Darwin/Mac OS X
|
|
||||||
|
|
||||||
Scsh code should run without change across these systems.
|
Scsh code should run without change across these systems.
|
||||||
Porting to new platforms is usually not difficult.
|
Porting to new platforms is usually not difficult.
|
||||||
|
@ -149,56 +153,74 @@ at MIT.
|
||||||
|
|
||||||
Bugs can be reported to
|
Bugs can be reported to
|
||||||
scsh-bugs@zurich.ai.mit.edu
|
scsh-bugs@zurich.ai.mit.edu
|
||||||
or via the Scsh project's bugs section on SourceForge:
|
|
||||||
http://sourceforge.net/projects/scsh/
|
|
||||||
|
|
||||||
If you do not netnews hierarchy, or wish to join the mailing
|
If you do not receive the alt netnews hierarchy, or wish to join the mailing
|
||||||
list for other reasons, send mail to
|
list for other reasons, send mail to
|
||||||
scsh-request@zurich.ai.mit.edu
|
scsh-request@zurich.ai.mit.edu
|
||||||
|
|
||||||
|
|
||||||
* The World-Wide What?
|
* The World-Wide What?
|
||||||
======================
|
======================
|
||||||
We even have one of those dot-com cyberweb things:
|
We even have one of those URL things:
|
||||||
http://www.swiss.ai.mit.edu/ftpdir/scsh/
|
http://www-swiss.ai.mit.edu/scsh/
|
||||||
We now manage the project using SourceForge:
|
|
||||||
http://sourceforge.net/projects/scsh/
|
|
||||||
|
|
||||||
* New in this release
|
* New in this release
|
||||||
=====================
|
=====================
|
||||||
|
** Scsh is now "open source."
|
||||||
|
We finally got around to tacking an ideologically hip copyright
|
||||||
|
onto the source. (Not that we ever cared before what you did with
|
||||||
|
the system...) The Scheme 48 authors have also graciously retrofitted
|
||||||
|
a BSD-style open-source copyright onto the underlying Scheme 48 0.36
|
||||||
|
platform for us. The whole system is now open source, top-to-bottom.
|
||||||
|
|
||||||
|
Take all the code you like; we'll just write more.
|
||||||
|
|
||||||
** Scsh is now on Win32
|
** Scsh is now on Win32
|
||||||
Scsh will now build and run using Cygwin 1.1. This was tested
|
Scsh will now build and run using Cygwin B20.1. This was only tested
|
||||||
on Windows NT 4.0 and Windows 2000, but presumably things could work
|
on Windows NT 4.0, but presumably things could work on other Cygwin
|
||||||
on other Cygwin platforms such as Win95 or Win98. Cygwin is available
|
platforms such as Win95 or Win98. Cygwin is available from:
|
||||||
from:
|
|
||||||
http://sourceware.cygnus.com/cygwin/
|
http://sourceware.cygnus.com/cygwin/
|
||||||
|
|
||||||
** Scsh is now on Mac OS X
|
** CVS repository will be public-readable
|
||||||
Scsh does now support Darwin and thus Mac OS X. This was simply
|
We will add further information to the web-site as soon as possible.
|
||||||
achived by treating Darwin as a BSD platform.
|
|
||||||
|
|
||||||
** CVS repository is now publically accessable
|
** New char-sets and char-set operations
|
||||||
The scsh sources have moved to scsh.sourceforge.net, and the
|
See the manual for more information on using character sets
|
||||||
the CVS repository is publically readable. Here's the magic:
|
for text processing. Also, see the ccp package in scsh/scsh/lib
|
||||||
|
for a new library providing character->character partial maps,
|
||||||
|
which are also useful for general string processing.
|
||||||
|
|
||||||
cvs -d:pserver:anonymous@cvs.scsh.sourceforge.net:/cvsroot/scsh co scsh
|
** New regular expression system
|
||||||
cvs -d:pserver:anonymous@cvs.scsh.sourceforge.net:/cvsroot/scsh co scsh-0.6
|
There's a whole new regexp package in scsh. There's a new,
|
||||||
|
s-expression-based notation for regexps, called SRE's. The new
|
||||||
|
notation has been integrated into the AWK macro and field-parser functions.
|
||||||
|
The older Posix notation is still supported for backwards compatibility.
|
||||||
|
|
||||||
(The 0.6 source tree builds with a modern Scheme 48 and thread support.
|
There's a whole chapter on regexps in the new manual; it has full details.
|
||||||
It has not been released.)
|
|
||||||
|
The previous AWK and field-reader system is provided in a
|
||||||
|
backwards-compatibility package. See package obsolete-awk-package
|
||||||
|
in scsh-package.scm.
|
||||||
|
|
||||||
** New libraries
|
** New libraries
|
||||||
Scsh now provides the SRFI-1, SRFI-13 and SRFI-14 libraries, giving
|
The SRFI-1 list library is available, in the list-lib package.
|
||||||
portable support for list, string and character-set operations.
|
There is a large, powerful string-processing library available
|
||||||
|
in the string-lib package. See the directory scsh/scsh/lib/ for
|
||||||
|
documentation and source.
|
||||||
|
|
||||||
These libraries make basic list and string hacking very straightforward.
|
These libraries make basic list and string hacking very straightforward.
|
||||||
|
|
||||||
** Database access via ODBC
|
** Renaming
|
||||||
Brian Carlstrom, Sam Thiebault and Olin Shivers have designed and
|
We are shifting from a reduce-foo convention to a more standard
|
||||||
implemented a portable interface to relational databases. The code
|
foo-fold convention. This has caused the following renamings:
|
||||||
back-ends to ODBC drivers for portability.
|
reduce-char-set => char-set-fold
|
||||||
|
reduce-port => port-fold
|
||||||
|
The older names are still bound, but are deprecated and will likely
|
||||||
|
go away in a future release.
|
||||||
|
|
||||||
|
String utilities INDEX and RINDEX are gone. Use the string-lib procedures
|
||||||
|
instead.
|
||||||
|
|
||||||
** Bugfixes
|
** Bugfixes
|
||||||
Over a year's worth of bug fixes. In particular, the old problems with the
|
Over a year's worth of bug fixes. In particular, the old problems with the
|
||||||
|
@ -213,25 +235,54 @@ We would like to thank the members of local-resistance cells for the
|
||||||
Underground everywhere for bug reports, bug fixes, design review and comments
|
Underground everywhere for bug reports, bug fixes, design review and comments
|
||||||
that were incorporated into this release. We really appreciate their help,
|
that were incorporated into this release. We really appreciate their help,
|
||||||
particularly in the task of porting scsh to new platforms.
|
particularly in the task of porting scsh to new platforms.
|
||||||
Friedrich Dominicus
|
|
||||||
Jay Nietling
|
Alan Bawden
|
||||||
Tim Bradshaw
|
Jim Blandy
|
||||||
Robert Brown
|
Per Bothner
|
||||||
Eric Marsden
|
Tom Breton
|
||||||
Paul Emsley
|
Christopher Browne
|
||||||
Pawel Turnau
|
Sean Doran
|
||||||
Hannu Koivisto
|
Ray Dillinger
|
||||||
|
Allyn Dimock
|
||||||
|
Scott Draves
|
||||||
|
Lutz Euler
|
||||||
|
Kevin Esler
|
||||||
|
Jeremy Fitzhardinge
|
||||||
|
Noah Friedman
|
||||||
|
Martin Gasbichler
|
||||||
Andy Gaynor
|
Andy Gaynor
|
||||||
Francisco Vides Fernandez
|
Ian Grant
|
||||||
Tim Burgess
|
Eric Hanchrow
|
||||||
Brian Denheyer
|
Karl Hegbloom
|
||||||
Harvey Stein
|
Johann Hibschman
|
||||||
Eric Hilsdale
|
Ian Horswill & the Northwestern Scheme wizards
|
||||||
|
Gary Houston
|
||||||
|
Graham Hughes
|
||||||
|
Jarmo Hurri
|
||||||
|
Lars Kellogg-Stedman
|
||||||
|
Andre Koehoerst
|
||||||
|
Hannu Koivisto
|
||||||
|
Shriram Krishnamurthi
|
||||||
|
Jakob Lichtenberg
|
||||||
|
Eric Marsden
|
||||||
|
Peter C. Olsen
|
||||||
|
Willliam Pippin
|
||||||
|
David Rush
|
||||||
|
Michael Schinz
|
||||||
|
Manuel Serrano
|
||||||
|
Mark Shirle
|
||||||
|
Bill Somerfeld
|
||||||
|
Mike Sperber
|
||||||
|
Harvey J. Stein
|
||||||
|
Pawel Turnau
|
||||||
|
Rob Warnock
|
||||||
|
Kenneth R. Westerback
|
||||||
|
|
||||||
We'd like to thank everyone else for their patience; this release seemed like
|
We'd like to thank everyone else for their patience; this release seemed like
|
||||||
a long time coming.
|
a long time coming.
|
||||||
|
|
||||||
Brought to you by the Scheme Underground. Go forth and write elegant systems
|
Brought to you by the Scheme Underground. Go forth and write elegant systems
|
||||||
programs.
|
programs.
|
||||||
-Olin Shivers, Brian Carlstrom, Martin Gasbichler & Mike Sperber
|
-Olin Shivers, Brian Carlstrom & Martin Gasbichler
|
||||||
|
Cambridge
|
||||||
|
29 September 1999
|
||||||
|
|
3
Thanks
3
Thanks
|
@ -10,6 +10,3 @@ Post-0.5.2-release bug reports:
|
||||||
Andy Gaynor
|
Andy Gaynor
|
||||||
Francisco Vides Fernandez
|
Francisco Vides Fernandez
|
||||||
Tim Burgess
|
Tim Burgess
|
||||||
Brian Denheyer
|
|
||||||
Harvey Stein
|
|
||||||
Eric Hilsdale
|
|
||||||
|
|
|
@ -16,11 +16,10 @@
|
||||||
# rm /zu/bdc/ftp/scsh/README~
|
# rm /zu/bdc/ftp/scsh/README~
|
||||||
#
|
#
|
||||||
VERSION=-0.5.3
|
VERSION=-0.5.3
|
||||||
FTPDIR=${HOME}/ftp/pub/scsh
|
FTPDIR=${HOME}/ftp/users/bdc
|
||||||
FTPDIR=${HOME}/ftp/pub/users/bdc
|
|
||||||
|
|
||||||
#CVSROOT=/projects/express/scsh-cvs
|
CVSROOT=/projects/express/scsh-cvs
|
||||||
#export CVSROOT
|
export CVSROOT
|
||||||
|
|
||||||
TMPSPACE=${HOME}/tmp
|
TMPSPACE=${HOME}/tmp
|
||||||
#-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
|
#-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,10 +1,6 @@
|
||||||
#! /bin/sh
|
#! /bin/sh
|
||||||
# Configuration validation subroutine script.
|
# Configuration validation subroutine script, version 1.1.
|
||||||
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
|
# Copyright (C) 1991, 92, 93, 94, 95, 1996 Free Software Foundation, Inc.
|
||||||
# Free Software Foundation, Inc.
|
|
||||||
|
|
||||||
timestamp='2001-03-09'
|
|
||||||
|
|
||||||
# This file is (in principle) common to ALL GNU software.
|
# This file is (in principle) common to ALL GNU software.
|
||||||
# The presence of a machine in this file suggests that SOME GNU software
|
# The presence of a machine in this file suggests that SOME GNU software
|
||||||
# can handle that machine. It does not imply ALL GNU software can.
|
# can handle that machine. It does not imply ALL GNU software can.
|
||||||
|
@ -29,8 +25,6 @@ timestamp='2001-03-09'
|
||||||
# configuration script generated by Autoconf, you may include it under
|
# configuration script generated by Autoconf, you may include it under
|
||||||
# the same distribution terms that you use for the rest of that program.
|
# the same distribution terms that you use for the rest of that program.
|
||||||
|
|
||||||
# Please send patches to <config-patches@gnu.org>.
|
|
||||||
#
|
|
||||||
# Configuration subroutine to validate and canonicalize a configuration type.
|
# Configuration subroutine to validate and canonicalize a configuration type.
|
||||||
# Supply the specified configuration type as an argument.
|
# Supply the specified configuration type as an argument.
|
||||||
# If it is invalid, we print an error message on stderr and exit with code 1.
|
# If it is invalid, we print an error message on stderr and exit with code 1.
|
||||||
|
@ -51,73 +45,30 @@ timestamp='2001-03-09'
|
||||||
# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
|
# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
|
||||||
# It is wrong to echo any other type of specification.
|
# It is wrong to echo any other type of specification.
|
||||||
|
|
||||||
me=`echo "$0" | sed -e 's,.*/,,'`
|
if [ x$1 = x ]
|
||||||
|
then
|
||||||
|
echo Configuration name missing. 1>&2
|
||||||
|
echo "Usage: $0 CPU-MFR-OPSYS" 1>&2
|
||||||
|
echo "or $0 ALIAS" 1>&2
|
||||||
|
echo where ALIAS is a recognized configuration type. 1>&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
usage="\
|
|
||||||
Usage: $0 [OPTION] CPU-MFR-OPSYS
|
|
||||||
$0 [OPTION] ALIAS
|
|
||||||
|
|
||||||
Canonicalize a configuration name.
|
|
||||||
|
|
||||||
Operation modes:
|
|
||||||
-h, --help print this help, then exit
|
|
||||||
-t, --time-stamp print date of last modification, then exit
|
|
||||||
-v, --version print version number, then exit
|
|
||||||
|
|
||||||
Report bugs and patches to <config-patches@gnu.org>."
|
|
||||||
|
|
||||||
version="\
|
|
||||||
GNU config.sub ($timestamp)
|
|
||||||
|
|
||||||
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
|
|
||||||
Free Software Foundation, Inc.
|
|
||||||
|
|
||||||
This is free software; see the source for copying conditions. There is NO
|
|
||||||
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
|
|
||||||
|
|
||||||
help="
|
|
||||||
Try \`$me --help' for more information."
|
|
||||||
|
|
||||||
# Parse command line
|
|
||||||
while test $# -gt 0 ; do
|
|
||||||
case $1 in
|
|
||||||
--time-stamp | --time* | -t )
|
|
||||||
echo "$timestamp" ; exit 0 ;;
|
|
||||||
--version | -v )
|
|
||||||
echo "$version" ; exit 0 ;;
|
|
||||||
--help | --h* | -h )
|
|
||||||
echo "$usage"; exit 0 ;;
|
|
||||||
-- ) # Stop option processing
|
|
||||||
shift; break ;;
|
|
||||||
- ) # Use stdin as input.
|
|
||||||
break ;;
|
|
||||||
-* )
|
|
||||||
echo "$me: invalid option $1$help"
|
|
||||||
exit 1 ;;
|
|
||||||
|
|
||||||
*local*)
|
|
||||||
# First pass through any local machine types.
|
# First pass through any local machine types.
|
||||||
|
case $1 in
|
||||||
|
*local*)
|
||||||
echo $1
|
echo $1
|
||||||
exit 0;;
|
exit 0
|
||||||
|
;;
|
||||||
*)
|
*)
|
||||||
break ;;
|
;;
|
||||||
esac
|
|
||||||
done
|
|
||||||
|
|
||||||
case $# in
|
|
||||||
0) echo "$me: missing argument$help" >&2
|
|
||||||
exit 1;;
|
|
||||||
1) ;;
|
|
||||||
*) echo "$me: too many arguments$help" >&2
|
|
||||||
exit 1;;
|
|
||||||
esac
|
esac
|
||||||
|
|
||||||
# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any).
|
# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any).
|
||||||
# Here we must recognize all the valid KERNEL-OS combinations.
|
# Here we must recognize all the valid KERNEL-OS combinations.
|
||||||
maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
|
maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
|
||||||
case $maybe_os in
|
case $maybe_os in
|
||||||
nto-qnx* | linux-gnu* | storm-chaos* | os2-emx*)
|
linux-gnu*)
|
||||||
os=-$maybe_os
|
os=-$maybe_os
|
||||||
basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
|
basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
|
||||||
;;
|
;;
|
||||||
|
@ -143,25 +94,15 @@ case $os in
|
||||||
-convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
|
-convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
|
||||||
-c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
|
-c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
|
||||||
-harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
|
-harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
|
||||||
-apple | -axis)
|
-apple)
|
||||||
os=
|
os=
|
||||||
basic_machine=$1
|
basic_machine=$1
|
||||||
;;
|
;;
|
||||||
-sim | -cisco | -oki | -wec | -winbond)
|
|
||||||
os=
|
|
||||||
basic_machine=$1
|
|
||||||
;;
|
|
||||||
-scout)
|
|
||||||
;;
|
|
||||||
-wrs)
|
|
||||||
os=-vxworks
|
|
||||||
basic_machine=$1
|
|
||||||
;;
|
|
||||||
-hiux*)
|
-hiux*)
|
||||||
os=-hiuxwe2
|
os=-hiuxwe2
|
||||||
;;
|
;;
|
||||||
-sco5)
|
-sco5)
|
||||||
os=-sco3.2v5
|
os=sco3.2v5
|
||||||
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
|
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
|
||||||
;;
|
;;
|
||||||
-sco4)
|
-sco4)
|
||||||
|
@ -180,9 +121,6 @@ case $os in
|
||||||
os=-sco3.2v2
|
os=-sco3.2v2
|
||||||
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
|
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
|
||||||
;;
|
;;
|
||||||
-udk*)
|
|
||||||
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
|
|
||||||
;;
|
|
||||||
-isc)
|
-isc)
|
||||||
os=-isc2.2
|
os=-isc2.2
|
||||||
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
|
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
|
||||||
|
@ -205,48 +143,25 @@ case $os in
|
||||||
-psos*)
|
-psos*)
|
||||||
os=-psos
|
os=-psos
|
||||||
;;
|
;;
|
||||||
-mint | -mint[0-9]*)
|
|
||||||
basic_machine=m68k-atari
|
|
||||||
os=-mint
|
|
||||||
;;
|
|
||||||
esac
|
esac
|
||||||
|
|
||||||
# Decode aliases for certain CPU-COMPANY combinations.
|
# Decode aliases for certain CPU-COMPANY combinations.
|
||||||
case $basic_machine in
|
case $basic_machine in
|
||||||
# Recognize the basic CPU types without company name.
|
# Recognize the basic CPU types without company name.
|
||||||
# Some are omitted here because they have special meanings below.
|
# Some are omitted here because they have special meanings below.
|
||||||
tahoe | i860 | ia64 | m32r | m68k | m68000 | m88k | ns32k | arc \
|
tahoe | i860 | m68k | m68000 | m88k | ns32k | arm \
|
||||||
| arm | arme[lb] | arm[bl]e | armv[2345] | armv[345][lb] | strongarm | xscale \
|
| arme[lb] | pyramid \
|
||||||
| pyramid | mn10200 | mn10300 | tron | a29k \
|
| tron | a29k | 580 | i960 | h8300 | hppa1.0 | hppa1.1 \
|
||||||
| 580 | i960 | h8300 \
|
| alpha | we32k | ns16k | clipper | i370 | sh \
|
||||||
| x86 | ppcbe | mipsbe | mipsle | shbe | shle \
|
| powerpc | powerpcle | 1750a | dsp16xx | mips64 | mipsel \
|
||||||
| hppa | hppa1.0 | hppa1.1 | hppa2.0 | hppa2.0w | hppa2.0n \
|
| pdp11 | mips64el | mips64orion | mips64orionel \
|
||||||
| hppa64 \
|
| sparc | sparclet | sparclite | sparc64)
|
||||||
| alpha | alphaev[4-8] | alphaev56 | alphapca5[67] \
|
|
||||||
| alphaev6[78] \
|
|
||||||
| we32k | ns16k | clipper | i370 | sh | sh[34] \
|
|
||||||
| powerpc | powerpcle \
|
|
||||||
| 1750a | dsp16xx | pdp10 | pdp11 \
|
|
||||||
| mips16 | mips64 | mipsel | mips64el \
|
|
||||||
| mips64orion | mips64orionel | mipstx39 | mipstx39el \
|
|
||||||
| mips64vr4300 | mips64vr4300el | mips64vr4100 | mips64vr4100el \
|
|
||||||
| mips64vr5000 | miprs64vr5000el | mcore | s390 | s390x \
|
|
||||||
| sparc | sparclet | sparclite | sparc64 | sparcv9 | v850 | c4x \
|
|
||||||
| thumb | d10v | d30v | fr30 | avr | openrisc)
|
|
||||||
basic_machine=$basic_machine-unknown
|
basic_machine=$basic_machine-unknown
|
||||||
;;
|
;;
|
||||||
m6811 | m68hc11 | m6812 | m68hc12)
|
|
||||||
# Motorola 68HC11/12.
|
|
||||||
basic_machine=$basic_machine-unknown
|
|
||||||
os=-none
|
|
||||||
;;
|
|
||||||
m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | z8k | v70 | h8500 | w65 | pj | pjl)
|
|
||||||
;;
|
|
||||||
|
|
||||||
# We use `pc' rather than `unknown'
|
# We use `pc' rather than `unknown'
|
||||||
# because (1) that's what they normally are, and
|
# because (1) that's what they normally are, and
|
||||||
# (2) the word "unknown" tends to confuse beginning users.
|
# (2) the word "unknown" tends to confuse beginning users.
|
||||||
i[234567]86 | x86_64)
|
i[3456]86)
|
||||||
basic_machine=$basic_machine-pc
|
basic_machine=$basic_machine-pc
|
||||||
;;
|
;;
|
||||||
# Object if more than one company name word.
|
# Object if more than one company name word.
|
||||||
|
@ -255,51 +170,23 @@ case $basic_machine in
|
||||||
exit 1
|
exit 1
|
||||||
;;
|
;;
|
||||||
# Recognize the basic CPU types with company name.
|
# Recognize the basic CPU types with company name.
|
||||||
# FIXME: clean up the formatting here.
|
vax-* | tahoe-* | i[3456]86-* | i860-* | m68k-* | m68000-* | m88k-* \
|
||||||
vax-* | tahoe-* | i[234567]86-* | i860-* | ia64-* | m32r-* | m68k-* | m68000-* \
|
| sparc-* | ns32k-* | fx80-* | arm-* | c[123]* \
|
||||||
| m88k-* | sparc-* | ns32k-* | fx80-* | arc-* | c[123]* \
|
| mips-* | pyramid-* | tron-* | a29k-* | romp-* | rs6000-* | power-* \
|
||||||
| arm-* | armbe-* | armle-* | armv*-* | strongarm-* | xscale-* \
|
| none-* | 580-* | cray2-* | h8300-* | i960-* | xmp-* | ymp-* \
|
||||||
| mips-* | pyramid-* | tron-* | a29k-* | romp-* | rs6000-* \
|
| hppa1.0-* | hppa1.1-* | alpha-* | we32k-* | cydra-* | ns16k-* \
|
||||||
| power-* | none-* | 580-* | cray2-* | h8300-* | h8500-* | i960-* \
|
| pn-* | np1-* | xps100-* | clipper-* | orion-* | sparclite-* \
|
||||||
| xmp-* | ymp-* \
|
| pdp11-* | sh-* | powerpc-* | powerpcle-* | sparc64-* | mips64-* | mipsel-* \
|
||||||
| x86-* | ppcbe-* | mipsbe-* | mipsle-* | shbe-* | shle-* \
|
| mips64el-* | mips64orion-* | mips64orionel-*)
|
||||||
| hppa-* | hppa1.0-* | hppa1.1-* | hppa2.0-* | hppa2.0w-* \
|
|
||||||
| hppa2.0n-* | hppa64-* \
|
|
||||||
| alpha-* | alphaev[4-8]-* | alphaev56-* | alphapca5[67]-* \
|
|
||||||
| alphaev6[78]-* \
|
|
||||||
| we32k-* | cydra-* | ns16k-* | pn-* | np1-* | xps100-* \
|
|
||||||
| clipper-* | orion-* \
|
|
||||||
| sparclite-* | pdp10-* | pdp11-* | sh-* | powerpc-* | powerpcle-* \
|
|
||||||
| sparc64-* | sparcv9-* | sparc86x-* | mips16-* | mips64-* | mipsel-* \
|
|
||||||
| mips64el-* | mips64orion-* | mips64orionel-* \
|
|
||||||
| mips64vr4100-* | mips64vr4100el-* | mips64vr4300-* | mips64vr4300el-* \
|
|
||||||
| mipstx39-* | mipstx39el-* | mcore-* \
|
|
||||||
| f30[01]-* | f700-* | s390-* | s390x-* | sv1-* | t3e-* \
|
|
||||||
| [cjt]90-* \
|
|
||||||
| m88110-* | m680[01234]0-* | m683?2-* | m68360-* | z8k-* | d10v-* \
|
|
||||||
| thumb-* | v850-* | d30v-* | tic30-* | c30-* | fr30-* \
|
|
||||||
| bs2000-* | tic54x-* | c54x-* | x86_64-*)
|
|
||||||
;;
|
;;
|
||||||
# Recognize the various machine names and aliases which stand
|
# Recognize the various machine names and aliases which stand
|
||||||
# for a CPU type and a company and sometimes even an OS.
|
# for a CPU type and a company and sometimes even an OS.
|
||||||
386bsd)
|
|
||||||
basic_machine=i386-unknown
|
|
||||||
os=-bsd
|
|
||||||
;;
|
|
||||||
3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)
|
3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)
|
||||||
basic_machine=m68000-att
|
basic_machine=m68000-att
|
||||||
;;
|
;;
|
||||||
3b*)
|
3b*)
|
||||||
basic_machine=we32k-att
|
basic_machine=we32k-att
|
||||||
;;
|
;;
|
||||||
a29khif)
|
|
||||||
basic_machine=a29k-amd
|
|
||||||
os=-udi
|
|
||||||
;;
|
|
||||||
adobe68k)
|
|
||||||
basic_machine=m68010-adobe
|
|
||||||
os=-scout
|
|
||||||
;;
|
|
||||||
alliant | fx80)
|
alliant | fx80)
|
||||||
basic_machine=fx80-alliant
|
basic_machine=fx80-alliant
|
||||||
;;
|
;;
|
||||||
|
@ -315,24 +202,20 @@ case $basic_machine in
|
||||||
os=-sysv
|
os=-sysv
|
||||||
;;
|
;;
|
||||||
amiga | amiga-*)
|
amiga | amiga-*)
|
||||||
basic_machine=m68k-unknown
|
basic_machine=m68k-cbm
|
||||||
;;
|
;;
|
||||||
amigaos | amigados)
|
amigados)
|
||||||
basic_machine=m68k-unknown
|
basic_machine=m68k-cbm
|
||||||
os=-amigaos
|
os=-amigados
|
||||||
;;
|
;;
|
||||||
amigaunix | amix)
|
amigaunix | amix)
|
||||||
basic_machine=m68k-unknown
|
basic_machine=m68k-cbm
|
||||||
os=-sysv4
|
os=-sysv4
|
||||||
;;
|
;;
|
||||||
apollo68)
|
apollo68)
|
||||||
basic_machine=m68k-apollo
|
basic_machine=m68k-apollo
|
||||||
os=-sysv
|
os=-sysv
|
||||||
;;
|
;;
|
||||||
apollo68bsd)
|
|
||||||
basic_machine=m68k-apollo
|
|
||||||
os=-bsd
|
|
||||||
;;
|
|
||||||
aux)
|
aux)
|
||||||
basic_machine=m68k-apple
|
basic_machine=m68k-apple
|
||||||
os=-aux
|
os=-aux
|
||||||
|
@ -369,16 +252,13 @@ case $basic_machine in
|
||||||
basic_machine=cray2-cray
|
basic_machine=cray2-cray
|
||||||
os=-unicos
|
os=-unicos
|
||||||
;;
|
;;
|
||||||
[cjt]90)
|
[ctj]90-cray)
|
||||||
basic_machine=${basic_machine}-cray
|
basic_machine=c90-cray
|
||||||
os=-unicos
|
os=-unicos
|
||||||
;;
|
;;
|
||||||
crds | unos)
|
crds | unos)
|
||||||
basic_machine=m68k-crds
|
basic_machine=m68k-crds
|
||||||
;;
|
;;
|
||||||
cris | cris-* | etrax*)
|
|
||||||
basic_machine=cris-axis
|
|
||||||
;;
|
|
||||||
da30 | da30-*)
|
da30 | da30-*)
|
||||||
basic_machine=m68k-da30
|
basic_machine=m68k-da30
|
||||||
;;
|
;;
|
||||||
|
@ -412,10 +292,6 @@ case $basic_machine in
|
||||||
encore | umax | mmax)
|
encore | umax | mmax)
|
||||||
basic_machine=ns32k-encore
|
basic_machine=ns32k-encore
|
||||||
;;
|
;;
|
||||||
es1800 | OSE68k | ose68k | ose | OSE)
|
|
||||||
basic_machine=m68k-ericsson
|
|
||||||
os=-ose
|
|
||||||
;;
|
|
||||||
fx2800)
|
fx2800)
|
||||||
basic_machine=i860-alliant
|
basic_machine=i860-alliant
|
||||||
;;
|
;;
|
||||||
|
@ -426,10 +302,6 @@ case $basic_machine in
|
||||||
basic_machine=tron-gmicro
|
basic_machine=tron-gmicro
|
||||||
os=-sysv
|
os=-sysv
|
||||||
;;
|
;;
|
||||||
go32)
|
|
||||||
basic_machine=i386-pc
|
|
||||||
os=-go32
|
|
||||||
;;
|
|
||||||
h3050r* | hiux*)
|
h3050r* | hiux*)
|
||||||
basic_machine=hppa1.1-hitachi
|
basic_machine=hppa1.1-hitachi
|
||||||
os=-hiuxwe2
|
os=-hiuxwe2
|
||||||
|
@ -438,14 +310,6 @@ case $basic_machine in
|
||||||
basic_machine=h8300-hitachi
|
basic_machine=h8300-hitachi
|
||||||
os=-hms
|
os=-hms
|
||||||
;;
|
;;
|
||||||
h8300xray)
|
|
||||||
basic_machine=h8300-hitachi
|
|
||||||
os=-xray
|
|
||||||
;;
|
|
||||||
h8500hms)
|
|
||||||
basic_machine=h8500-hitachi
|
|
||||||
os=-hms
|
|
||||||
;;
|
|
||||||
harris)
|
harris)
|
||||||
basic_machine=m88k-harris
|
basic_machine=m88k-harris
|
||||||
os=-sysv3
|
os=-sysv3
|
||||||
|
@ -461,74 +325,39 @@ case $basic_machine in
|
||||||
basic_machine=m68k-hp
|
basic_machine=m68k-hp
|
||||||
os=-hpux
|
os=-hpux
|
||||||
;;
|
;;
|
||||||
hp3k9[0-9][0-9] | hp9[0-9][0-9])
|
|
||||||
basic_machine=hppa1.0-hp
|
|
||||||
;;
|
|
||||||
hp9k2[0-9][0-9] | hp9k31[0-9])
|
hp9k2[0-9][0-9] | hp9k31[0-9])
|
||||||
basic_machine=m68000-hp
|
basic_machine=m68000-hp
|
||||||
;;
|
;;
|
||||||
hp9k3[2-9][0-9])
|
hp9k3[2-9][0-9])
|
||||||
basic_machine=m68k-hp
|
basic_machine=m68k-hp
|
||||||
;;
|
;;
|
||||||
hp9k6[0-9][0-9] | hp6[0-9][0-9])
|
hp9k7[0-9][0-9] | hp7[0-9][0-9] | hp9k8[0-9]7 | hp8[0-9]7)
|
||||||
basic_machine=hppa1.0-hp
|
|
||||||
;;
|
|
||||||
hp9k7[0-79][0-9] | hp7[0-79][0-9])
|
|
||||||
basic_machine=hppa1.1-hp
|
|
||||||
;;
|
|
||||||
hp9k78[0-9] | hp78[0-9])
|
|
||||||
# FIXME: really hppa2.0-hp
|
|
||||||
basic_machine=hppa1.1-hp
|
|
||||||
;;
|
|
||||||
hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893)
|
|
||||||
# FIXME: really hppa2.0-hp
|
|
||||||
basic_machine=hppa1.1-hp
|
|
||||||
;;
|
|
||||||
hp9k8[0-9][13679] | hp8[0-9][13679])
|
|
||||||
basic_machine=hppa1.1-hp
|
basic_machine=hppa1.1-hp
|
||||||
;;
|
;;
|
||||||
hp9k8[0-9][0-9] | hp8[0-9][0-9])
|
hp9k8[0-9][0-9] | hp8[0-9][0-9])
|
||||||
basic_machine=hppa1.0-hp
|
basic_machine=hppa1.0-hp
|
||||||
;;
|
;;
|
||||||
hppa-next)
|
|
||||||
os=-nextstep3
|
|
||||||
;;
|
|
||||||
hppaosf)
|
|
||||||
basic_machine=hppa1.1-hp
|
|
||||||
os=-osf
|
|
||||||
;;
|
|
||||||
hppro)
|
|
||||||
basic_machine=hppa1.1-hp
|
|
||||||
os=-proelf
|
|
||||||
;;
|
|
||||||
i370-ibm* | ibm*)
|
i370-ibm* | ibm*)
|
||||||
basic_machine=i370-ibm
|
basic_machine=i370-ibm
|
||||||
|
os=-mvs
|
||||||
;;
|
;;
|
||||||
# I'm not sure what "Sysv32" means. Should this be sysv3.2?
|
# I'm not sure what "Sysv32" means. Should this be sysv3.2?
|
||||||
i[34567]86v32)
|
i[3456]86v32)
|
||||||
basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
|
basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
|
||||||
os=-sysv32
|
os=-sysv32
|
||||||
;;
|
;;
|
||||||
i[34567]86v4*)
|
i[3456]86v4*)
|
||||||
basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
|
basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
|
||||||
os=-sysv4
|
os=-sysv4
|
||||||
;;
|
;;
|
||||||
i[34567]86v)
|
i[3456]86v)
|
||||||
basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
|
basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
|
||||||
os=-sysv
|
os=-sysv
|
||||||
;;
|
;;
|
||||||
i[34567]86sol2)
|
i[3456]86sol2)
|
||||||
basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
|
basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
|
||||||
os=-solaris2
|
os=-solaris2
|
||||||
;;
|
;;
|
||||||
i386mach)
|
|
||||||
basic_machine=i386-mach
|
|
||||||
os=-mach
|
|
||||||
;;
|
|
||||||
i386-vsta | vsta)
|
|
||||||
basic_machine=i386-unknown
|
|
||||||
os=-vsta
|
|
||||||
;;
|
|
||||||
iris | iris4d)
|
iris | iris4d)
|
||||||
basic_machine=mips-sgi
|
basic_machine=mips-sgi
|
||||||
case $os in
|
case $os in
|
||||||
|
@ -554,59 +383,19 @@ case $basic_machine in
|
||||||
basic_machine=ns32k-utek
|
basic_machine=ns32k-utek
|
||||||
os=-sysv
|
os=-sysv
|
||||||
;;
|
;;
|
||||||
mingw32)
|
|
||||||
basic_machine=i386-pc
|
|
||||||
os=-mingw32
|
|
||||||
;;
|
|
||||||
miniframe)
|
miniframe)
|
||||||
basic_machine=m68000-convergent
|
basic_machine=m68000-convergent
|
||||||
;;
|
;;
|
||||||
*mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*)
|
|
||||||
basic_machine=m68k-atari
|
|
||||||
os=-mint
|
|
||||||
;;
|
|
||||||
mipsel*-linux*)
|
|
||||||
basic_machine=mipsel-unknown
|
|
||||||
os=-linux-gnu
|
|
||||||
;;
|
|
||||||
mips*-linux*)
|
|
||||||
basic_machine=mips-unknown
|
|
||||||
os=-linux-gnu
|
|
||||||
;;
|
|
||||||
mips3*-*)
|
mips3*-*)
|
||||||
basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`
|
basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`
|
||||||
;;
|
;;
|
||||||
mips3*)
|
mips3*)
|
||||||
basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown
|
basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown
|
||||||
;;
|
;;
|
||||||
mmix*)
|
|
||||||
basic_machine=mmix-knuth
|
|
||||||
os=-mmixware
|
|
||||||
;;
|
|
||||||
monitor)
|
|
||||||
basic_machine=m68k-rom68k
|
|
||||||
os=-coff
|
|
||||||
;;
|
|
||||||
msdos)
|
|
||||||
basic_machine=i386-pc
|
|
||||||
os=-msdos
|
|
||||||
;;
|
|
||||||
mvs)
|
|
||||||
basic_machine=i370-ibm
|
|
||||||
os=-mvs
|
|
||||||
;;
|
|
||||||
ncr3000)
|
ncr3000)
|
||||||
basic_machine=i486-ncr
|
basic_machine=i486-ncr
|
||||||
os=-sysv4
|
os=-sysv4
|
||||||
;;
|
;;
|
||||||
netbsd386)
|
|
||||||
basic_machine=i386-unknown
|
|
||||||
os=-netbsd
|
|
||||||
;;
|
|
||||||
netwinder)
|
|
||||||
basic_machine=armv4l-rebel
|
|
||||||
os=-linux
|
|
||||||
;;
|
|
||||||
news | news700 | news800 | news900)
|
news | news700 | news800 | news900)
|
||||||
basic_machine=m68k-sony
|
basic_machine=m68k-sony
|
||||||
os=-newsos
|
os=-newsos
|
||||||
|
@ -619,10 +408,6 @@ case $basic_machine in
|
||||||
basic_machine=mips-sony
|
basic_machine=mips-sony
|
||||||
os=-newsos
|
os=-newsos
|
||||||
;;
|
;;
|
||||||
necv70)
|
|
||||||
basic_machine=v70-nec
|
|
||||||
os=-sysv
|
|
||||||
;;
|
|
||||||
next | m*-next )
|
next | m*-next )
|
||||||
basic_machine=m68k-next
|
basic_machine=m68k-next
|
||||||
case $os in
|
case $os in
|
||||||
|
@ -648,32 +433,9 @@ case $basic_machine in
|
||||||
basic_machine=i960-intel
|
basic_machine=i960-intel
|
||||||
os=-nindy
|
os=-nindy
|
||||||
;;
|
;;
|
||||||
mon960)
|
|
||||||
basic_machine=i960-intel
|
|
||||||
os=-mon960
|
|
||||||
;;
|
|
||||||
nonstopux)
|
|
||||||
basic_machine=mips-compaq
|
|
||||||
os=-nonstopux
|
|
||||||
;;
|
|
||||||
np1)
|
np1)
|
||||||
basic_machine=np1-gould
|
basic_machine=np1-gould
|
||||||
;;
|
;;
|
||||||
nsr-tandem)
|
|
||||||
basic_machine=nsr-tandem
|
|
||||||
;;
|
|
||||||
op50n-* | op60c-*)
|
|
||||||
basic_machine=hppa1.1-oki
|
|
||||||
os=-proelf
|
|
||||||
;;
|
|
||||||
OSE68000 | ose68000)
|
|
||||||
basic_machine=m68000-ericsson
|
|
||||||
os=-ose
|
|
||||||
;;
|
|
||||||
os68k)
|
|
||||||
basic_machine=m68k-none
|
|
||||||
os=-os68k
|
|
||||||
;;
|
|
||||||
pa-hitachi)
|
pa-hitachi)
|
||||||
basic_machine=hppa1.1-hitachi
|
basic_machine=hppa1.1-hitachi
|
||||||
os=-hiuxwe2
|
os=-hiuxwe2
|
||||||
|
@ -691,28 +453,30 @@ case $basic_machine in
|
||||||
pc532 | pc532-*)
|
pc532 | pc532-*)
|
||||||
basic_machine=ns32k-pc532
|
basic_machine=ns32k-pc532
|
||||||
;;
|
;;
|
||||||
pentium | p5 | k5 | k6 | nexgen)
|
pentium | p5)
|
||||||
basic_machine=i586-pc
|
basic_machine=i586-intel
|
||||||
;;
|
;;
|
||||||
pentiumpro | p6 | 6x86 | athlon)
|
pentiumpro | p6)
|
||||||
basic_machine=i686-pc
|
basic_machine=i686-intel
|
||||||
;;
|
;;
|
||||||
pentiumii | pentium2)
|
pentium-* | p5-*)
|
||||||
basic_machine=i686-pc
|
|
||||||
;;
|
|
||||||
pentium-* | p5-* | k5-* | k6-* | nexgen-*)
|
|
||||||
basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
|
basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
|
||||||
;;
|
;;
|
||||||
pentiumpro-* | p6-* | 6x86-* | athlon-*)
|
pentiumpro-* | p6-*)
|
||||||
basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
|
basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
|
||||||
;;
|
;;
|
||||||
pentiumii-* | pentium2-*)
|
k5)
|
||||||
basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
|
# We don't have specific support for AMD's K5 yet, so just call it a Pentium
|
||||||
|
basic_machine=i586-amd
|
||||||
|
;;
|
||||||
|
nexen)
|
||||||
|
# We don't have specific support for Nexgen yet, so just call it a Pentium
|
||||||
|
basic_machine=i586-nexgen
|
||||||
;;
|
;;
|
||||||
pn)
|
pn)
|
||||||
basic_machine=pn-gould
|
basic_machine=pn-gould
|
||||||
;;
|
;;
|
||||||
power) basic_machine=power-ibm
|
power) basic_machine=rs6000-ibm
|
||||||
;;
|
;;
|
||||||
ppc) basic_machine=powerpc-unknown
|
ppc) basic_machine=powerpc-unknown
|
||||||
;;
|
;;
|
||||||
|
@ -727,24 +491,12 @@ case $basic_machine in
|
||||||
ps2)
|
ps2)
|
||||||
basic_machine=i386-ibm
|
basic_machine=i386-ibm
|
||||||
;;
|
;;
|
||||||
pw32)
|
|
||||||
basic_machine=i586-unknown
|
|
||||||
os=-pw32
|
|
||||||
;;
|
|
||||||
rom68k)
|
|
||||||
basic_machine=m68k-rom68k
|
|
||||||
os=-coff
|
|
||||||
;;
|
|
||||||
rm[46]00)
|
rm[46]00)
|
||||||
basic_machine=mips-siemens
|
basic_machine=mips-siemens
|
||||||
;;
|
;;
|
||||||
rtpc | rtpc-*)
|
rtpc | rtpc-*)
|
||||||
basic_machine=romp-ibm
|
basic_machine=romp-ibm
|
||||||
;;
|
;;
|
||||||
sa29200)
|
|
||||||
basic_machine=a29k-amd
|
|
||||||
os=-udi
|
|
||||||
;;
|
|
||||||
sequent)
|
sequent)
|
||||||
basic_machine=i386-sequent
|
basic_machine=i386-sequent
|
||||||
;;
|
;;
|
||||||
|
@ -752,10 +504,6 @@ case $basic_machine in
|
||||||
basic_machine=sh-hitachi
|
basic_machine=sh-hitachi
|
||||||
os=-hms
|
os=-hms
|
||||||
;;
|
;;
|
||||||
sparclite-wrs)
|
|
||||||
basic_machine=sparclite-wrs
|
|
||||||
os=-vxworks
|
|
||||||
;;
|
|
||||||
sps7)
|
sps7)
|
||||||
basic_machine=m68k-bull
|
basic_machine=m68k-bull
|
||||||
os=-sysv2
|
os=-sysv2
|
||||||
|
@ -763,13 +511,6 @@ case $basic_machine in
|
||||||
spur)
|
spur)
|
||||||
basic_machine=spur-unknown
|
basic_machine=spur-unknown
|
||||||
;;
|
;;
|
||||||
st2000)
|
|
||||||
basic_machine=m68k-tandem
|
|
||||||
;;
|
|
||||||
stratus)
|
|
||||||
basic_machine=i860-stratus
|
|
||||||
os=-sysv4
|
|
||||||
;;
|
|
||||||
sun2)
|
sun2)
|
||||||
basic_machine=m68000-sun
|
basic_machine=m68000-sun
|
||||||
;;
|
;;
|
||||||
|
@ -810,28 +551,10 @@ case $basic_machine in
|
||||||
sun386 | sun386i | roadrunner)
|
sun386 | sun386i | roadrunner)
|
||||||
basic_machine=i386-sun
|
basic_machine=i386-sun
|
||||||
;;
|
;;
|
||||||
sv1)
|
|
||||||
basic_machine=sv1-cray
|
|
||||||
os=-unicos
|
|
||||||
;;
|
|
||||||
symmetry)
|
symmetry)
|
||||||
basic_machine=i386-sequent
|
basic_machine=i386-sequent
|
||||||
os=-dynix
|
os=-dynix
|
||||||
;;
|
;;
|
||||||
t3e)
|
|
||||||
basic_machine=t3e-cray
|
|
||||||
os=-unicos
|
|
||||||
;;
|
|
||||||
tic54x | c54x*)
|
|
||||||
basic_machine=tic54x-unknown
|
|
||||||
os=-coff
|
|
||||||
;;
|
|
||||||
tx39)
|
|
||||||
basic_machine=mipstx39-unknown
|
|
||||||
;;
|
|
||||||
tx39el)
|
|
||||||
basic_machine=mipstx39el-unknown
|
|
||||||
;;
|
|
||||||
tower | tower-32)
|
tower | tower-32)
|
||||||
basic_machine=m68k-ncr
|
basic_machine=m68k-ncr
|
||||||
;;
|
;;
|
||||||
|
@ -843,10 +566,6 @@ case $basic_machine in
|
||||||
basic_machine=a29k-nyu
|
basic_machine=a29k-nyu
|
||||||
os=-sym1
|
os=-sym1
|
||||||
;;
|
;;
|
||||||
v810 | necv810)
|
|
||||||
basic_machine=v810-nec
|
|
||||||
os=-none
|
|
||||||
;;
|
|
||||||
vaxv)
|
vaxv)
|
||||||
basic_machine=vax-dec
|
basic_machine=vax-dec
|
||||||
os=-sysv
|
os=-sysv
|
||||||
|
@ -855,9 +574,6 @@ case $basic_machine in
|
||||||
basic_machine=vax-dec
|
basic_machine=vax-dec
|
||||||
os=-vms
|
os=-vms
|
||||||
;;
|
;;
|
||||||
vpp*|vx|vx-*)
|
|
||||||
basic_machine=f301-fujitsu
|
|
||||||
;;
|
|
||||||
vxworks960)
|
vxworks960)
|
||||||
basic_machine=i960-wrs
|
basic_machine=i960-wrs
|
||||||
os=-vxworks
|
os=-vxworks
|
||||||
|
@ -870,14 +586,6 @@ case $basic_machine in
|
||||||
basic_machine=a29k-wrs
|
basic_machine=a29k-wrs
|
||||||
os=-vxworks
|
os=-vxworks
|
||||||
;;
|
;;
|
||||||
w65*)
|
|
||||||
basic_machine=w65-wdc
|
|
||||||
os=-none
|
|
||||||
;;
|
|
||||||
w89k-*)
|
|
||||||
basic_machine=hppa1.1-winbond
|
|
||||||
os=-proelf
|
|
||||||
;;
|
|
||||||
xmp)
|
xmp)
|
||||||
basic_machine=xmp-cray
|
basic_machine=xmp-cray
|
||||||
os=-unicos
|
os=-unicos
|
||||||
|
@ -885,10 +593,6 @@ case $basic_machine in
|
||||||
xps | xps100)
|
xps | xps100)
|
||||||
basic_machine=xps100-honeywell
|
basic_machine=xps100-honeywell
|
||||||
;;
|
;;
|
||||||
z8k-*-coff)
|
|
||||||
basic_machine=z8k-unknown
|
|
||||||
os=-sim
|
|
||||||
;;
|
|
||||||
none)
|
none)
|
||||||
basic_machine=none-none
|
basic_machine=none-none
|
||||||
os=-none
|
os=-none
|
||||||
|
@ -896,21 +600,8 @@ case $basic_machine in
|
||||||
|
|
||||||
# Here we handle the default manufacturer of certain CPU types. It is in
|
# Here we handle the default manufacturer of certain CPU types. It is in
|
||||||
# some cases the only manufacturer, in others, it is the most popular.
|
# some cases the only manufacturer, in others, it is the most popular.
|
||||||
w89k)
|
|
||||||
basic_machine=hppa1.1-winbond
|
|
||||||
;;
|
|
||||||
op50n)
|
|
||||||
basic_machine=hppa1.1-oki
|
|
||||||
;;
|
|
||||||
op60c)
|
|
||||||
basic_machine=hppa1.1-oki
|
|
||||||
;;
|
|
||||||
mips)
|
mips)
|
||||||
if [ x$os = x-linux-gnu ]; then
|
|
||||||
basic_machine=mips-unknown
|
|
||||||
else
|
|
||||||
basic_machine=mips-mips
|
basic_machine=mips-mips
|
||||||
fi
|
|
||||||
;;
|
;;
|
||||||
romp)
|
romp)
|
||||||
basic_machine=romp-ibm
|
basic_machine=romp-ibm
|
||||||
|
@ -921,20 +612,13 @@ case $basic_machine in
|
||||||
vax)
|
vax)
|
||||||
basic_machine=vax-dec
|
basic_machine=vax-dec
|
||||||
;;
|
;;
|
||||||
pdp10)
|
|
||||||
# there are many clones, so DEC is not a safe bet
|
|
||||||
basic_machine=pdp10-unknown
|
|
||||||
;;
|
|
||||||
pdp11)
|
pdp11)
|
||||||
basic_machine=pdp11-dec
|
basic_machine=pdp11-dec
|
||||||
;;
|
;;
|
||||||
we32k)
|
we32k)
|
||||||
basic_machine=we32k-att
|
basic_machine=we32k-att
|
||||||
;;
|
;;
|
||||||
sh3 | sh4)
|
sparc)
|
||||||
basic_machine=sh-unknown
|
|
||||||
;;
|
|
||||||
sparc | sparcv9)
|
|
||||||
basic_machine=sparc-sun
|
basic_machine=sparc-sun
|
||||||
;;
|
;;
|
||||||
cydra)
|
cydra)
|
||||||
|
@ -946,16 +630,6 @@ case $basic_machine in
|
||||||
orion105)
|
orion105)
|
||||||
basic_machine=clipper-highlevel
|
basic_machine=clipper-highlevel
|
||||||
;;
|
;;
|
||||||
mac | mpw | mac-mpw)
|
|
||||||
basic_machine=m68k-apple
|
|
||||||
;;
|
|
||||||
pmac | pmac-mpw)
|
|
||||||
basic_machine=powerpc-apple
|
|
||||||
;;
|
|
||||||
c4x*)
|
|
||||||
basic_machine=c4x-none
|
|
||||||
os=-coff
|
|
||||||
;;
|
|
||||||
*)
|
*)
|
||||||
echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
|
echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
|
||||||
exit 1
|
exit 1
|
||||||
|
@ -988,12 +662,9 @@ case $os in
|
||||||
-solaris)
|
-solaris)
|
||||||
os=-solaris2
|
os=-solaris2
|
||||||
;;
|
;;
|
||||||
-svr4*)
|
-unixware* | svr4*)
|
||||||
os=-sysv4
|
os=-sysv4
|
||||||
;;
|
;;
|
||||||
-unixware*)
|
|
||||||
os=-sysv4.2uw
|
|
||||||
;;
|
|
||||||
-gnu/linux*)
|
-gnu/linux*)
|
||||||
os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'`
|
os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'`
|
||||||
;;
|
;;
|
||||||
|
@ -1004,40 +675,17 @@ case $os in
|
||||||
-gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
|
-gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
|
||||||
| -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\
|
| -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\
|
||||||
| -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \
|
| -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \
|
||||||
| -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
|
| -amigados* | -msdos* | -newsos* | -unicos* | -aof* | -aos* \
|
||||||
| -aos* \
|
| -nindy* | -vxworks* | -ebmon* | -hms* | -mvs* | -clix* \
|
||||||
| -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
|
| -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
|
||||||
| -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
|
| -hiux* | -386bsd* | -netbsd* | -freebsd* | -riscix* \
|
||||||
| -hiux* | -386bsd* | -netbsd* | -openbsd* | -freebsd* | -riscix* \
|
| -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* \
|
||||||
| -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
|
|
||||||
| -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
|
| -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
|
||||||
| -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
|
| -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
|
||||||
| -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
|
| -cygwin32* | -pe* | -psos* | -moss* | -proelf* \
|
||||||
| -mingw32* | -linux-gnu* | -uxpv* | -beos* | -mpeix* | -udk* \
|
| -linux-gnu*)
|
||||||
| -interix* | -uwin* | -rhapsody* | -darwin* | -opened* \
|
|
||||||
| -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
|
|
||||||
| -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* | -os2*)
|
|
||||||
# Remember, each alternative MUST END IN *, to match a version number.
|
# Remember, each alternative MUST END IN *, to match a version number.
|
||||||
;;
|
;;
|
||||||
-qnx*)
|
|
||||||
case $basic_machine in
|
|
||||||
x86-* | i[34567]86-*)
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
os=-nto$os
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
;;
|
|
||||||
-nto*)
|
|
||||||
os=-nto-qnx
|
|
||||||
;;
|
|
||||||
-sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \
|
|
||||||
| -windows* | -osx | -abug | -netware* | -os9* | -beos* \
|
|
||||||
| -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*)
|
|
||||||
;;
|
|
||||||
-mac*)
|
|
||||||
os=`echo $os | sed -e 's|mac|macos|'`
|
|
||||||
;;
|
|
||||||
-linux*)
|
-linux*)
|
||||||
os=`echo $os | sed -e 's|linux|linux-gnu|'`
|
os=`echo $os | sed -e 's|linux|linux-gnu|'`
|
||||||
;;
|
;;
|
||||||
|
@ -1047,12 +695,6 @@ case $os in
|
||||||
-sunos6*)
|
-sunos6*)
|
||||||
os=`echo $os | sed -e 's|sunos6|solaris3|'`
|
os=`echo $os | sed -e 's|sunos6|solaris3|'`
|
||||||
;;
|
;;
|
||||||
-opened*)
|
|
||||||
os=-openedition
|
|
||||||
;;
|
|
||||||
-wince*)
|
|
||||||
os=-wince
|
|
||||||
;;
|
|
||||||
-osfrose*)
|
-osfrose*)
|
||||||
os=-osfrose
|
os=-osfrose
|
||||||
;;
|
;;
|
||||||
|
@ -1068,18 +710,12 @@ case $os in
|
||||||
-acis*)
|
-acis*)
|
||||||
os=-aos
|
os=-aos
|
||||||
;;
|
;;
|
||||||
-386bsd)
|
|
||||||
os=-bsd
|
|
||||||
;;
|
|
||||||
-ctix* | -uts*)
|
-ctix* | -uts*)
|
||||||
os=-sysv
|
os=-sysv
|
||||||
;;
|
;;
|
||||||
-ns2 )
|
-ns2 )
|
||||||
os=-nextstep2
|
os=-nextstep2
|
||||||
;;
|
;;
|
||||||
-nsk*)
|
|
||||||
os=-nsk
|
|
||||||
;;
|
|
||||||
# Preserve the version number of sinix5.
|
# Preserve the version number of sinix5.
|
||||||
-sinix5.*)
|
-sinix5.*)
|
||||||
os=`echo $os | sed -e 's|sinix|sysv|'`
|
os=`echo $os | sed -e 's|sinix|sysv|'`
|
||||||
|
@ -1105,18 +741,9 @@ case $os in
|
||||||
# This must come after -sysvr4.
|
# This must come after -sysvr4.
|
||||||
-sysv*)
|
-sysv*)
|
||||||
;;
|
;;
|
||||||
-ose*)
|
|
||||||
os=-ose
|
|
||||||
;;
|
|
||||||
-es1800*)
|
|
||||||
os=-ose
|
|
||||||
;;
|
|
||||||
-xenix)
|
-xenix)
|
||||||
os=-xenix
|
os=-xenix
|
||||||
;;
|
;;
|
||||||
-*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
|
|
||||||
os=-mint
|
|
||||||
;;
|
|
||||||
-none)
|
-none)
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
|
@ -1142,15 +769,9 @@ case $basic_machine in
|
||||||
*-acorn)
|
*-acorn)
|
||||||
os=-riscix1.2
|
os=-riscix1.2
|
||||||
;;
|
;;
|
||||||
arm*-rebel)
|
|
||||||
os=-linux
|
|
||||||
;;
|
|
||||||
arm*-semi)
|
arm*-semi)
|
||||||
os=-aout
|
os=-aout
|
||||||
;;
|
;;
|
||||||
pdp10-*)
|
|
||||||
os=-tops20
|
|
||||||
;;
|
|
||||||
pdp11-*)
|
pdp11-*)
|
||||||
os=-none
|
os=-none
|
||||||
;;
|
;;
|
||||||
|
@ -1169,36 +790,15 @@ case $basic_machine in
|
||||||
# default.
|
# default.
|
||||||
# os=-sunos4
|
# os=-sunos4
|
||||||
;;
|
;;
|
||||||
m68*-cisco)
|
|
||||||
os=-aout
|
|
||||||
;;
|
|
||||||
mips*-cisco)
|
|
||||||
os=-elf
|
|
||||||
;;
|
|
||||||
mips*-*)
|
|
||||||
os=-elf
|
|
||||||
;;
|
|
||||||
*-tti) # must be before sparc entry or we get the wrong os.
|
*-tti) # must be before sparc entry or we get the wrong os.
|
||||||
os=-sysv3
|
os=-sysv3
|
||||||
;;
|
;;
|
||||||
sparc-* | *-sun)
|
sparc-* | *-sun)
|
||||||
os=-sunos4.1.1
|
os=-sunos4.1.1
|
||||||
;;
|
;;
|
||||||
*-be)
|
|
||||||
os=-beos
|
|
||||||
;;
|
|
||||||
*-ibm)
|
*-ibm)
|
||||||
os=-aix
|
os=-aix
|
||||||
;;
|
;;
|
||||||
*-wec)
|
|
||||||
os=-proelf
|
|
||||||
;;
|
|
||||||
*-winbond)
|
|
||||||
os=-proelf
|
|
||||||
;;
|
|
||||||
*-oki)
|
|
||||||
os=-proelf
|
|
||||||
;;
|
|
||||||
*-hp)
|
*-hp)
|
||||||
os=-hpux
|
os=-hpux
|
||||||
;;
|
;;
|
||||||
|
@ -1209,7 +809,7 @@ case $basic_machine in
|
||||||
os=-sysv
|
os=-sysv
|
||||||
;;
|
;;
|
||||||
*-cbm)
|
*-cbm)
|
||||||
os=-amigaos
|
os=-amigados
|
||||||
;;
|
;;
|
||||||
*-dg)
|
*-dg)
|
||||||
os=-dgux
|
os=-dgux
|
||||||
|
@ -1259,21 +859,6 @@ case $basic_machine in
|
||||||
*-masscomp)
|
*-masscomp)
|
||||||
os=-rtu
|
os=-rtu
|
||||||
;;
|
;;
|
||||||
f30[01]-fujitsu | f700-fujitsu)
|
|
||||||
os=-uxpv
|
|
||||||
;;
|
|
||||||
*-rom68k)
|
|
||||||
os=-coff
|
|
||||||
;;
|
|
||||||
*-*bug)
|
|
||||||
os=-coff
|
|
||||||
;;
|
|
||||||
*-apple)
|
|
||||||
os=-macos
|
|
||||||
;;
|
|
||||||
*-atari*)
|
|
||||||
os=-mint
|
|
||||||
;;
|
|
||||||
*)
|
*)
|
||||||
os=-none
|
os=-none
|
||||||
;;
|
;;
|
||||||
|
@ -1292,18 +877,15 @@ case $basic_machine in
|
||||||
-sunos*)
|
-sunos*)
|
||||||
vendor=sun
|
vendor=sun
|
||||||
;;
|
;;
|
||||||
|
-lynxos*)
|
||||||
|
vendor=lynx
|
||||||
|
;;
|
||||||
-aix*)
|
-aix*)
|
||||||
vendor=ibm
|
vendor=ibm
|
||||||
;;
|
;;
|
||||||
-beos*)
|
|
||||||
vendor=be
|
|
||||||
;;
|
|
||||||
-hpux*)
|
-hpux*)
|
||||||
vendor=hp
|
vendor=hp
|
||||||
;;
|
;;
|
||||||
-mpeix*)
|
|
||||||
vendor=hp
|
|
||||||
;;
|
|
||||||
-hiux*)
|
-hiux*)
|
||||||
vendor=hitachi
|
vendor=hitachi
|
||||||
;;
|
;;
|
||||||
|
@ -1319,38 +901,21 @@ case $basic_machine in
|
||||||
-genix*)
|
-genix*)
|
||||||
vendor=ns
|
vendor=ns
|
||||||
;;
|
;;
|
||||||
-mvs* | -opened*)
|
-mvs*)
|
||||||
vendor=ibm
|
vendor=ibm
|
||||||
;;
|
;;
|
||||||
-ptx*)
|
-ptx*)
|
||||||
vendor=sequent
|
vendor=sequent
|
||||||
;;
|
;;
|
||||||
-vxsim* | -vxworks*)
|
-vxworks*)
|
||||||
vendor=wrs
|
vendor=wrs
|
||||||
;;
|
;;
|
||||||
-aux*)
|
-aux*)
|
||||||
vendor=apple
|
vendor=apple
|
||||||
;;
|
;;
|
||||||
-hms*)
|
|
||||||
vendor=hitachi
|
|
||||||
;;
|
|
||||||
-mpw* | -macos*)
|
|
||||||
vendor=apple
|
|
||||||
;;
|
|
||||||
-*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
|
|
||||||
vendor=atari
|
|
||||||
;;
|
|
||||||
esac
|
esac
|
||||||
basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"`
|
basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"`
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
echo $basic_machine$os
|
echo $basic_machine$os
|
||||||
exit 0
|
|
||||||
|
|
||||||
# Local variables:
|
|
||||||
# eval: (add-hook 'write-file-hooks 'time-stamp)
|
|
||||||
# time-stamp-start: "timestamp='"
|
|
||||||
# time-stamp-format: "%:y-%02m-%02d"
|
|
||||||
# time-stamp-end: "'"
|
|
||||||
# End:
|
|
||||||
|
|
|
@ -1294,7 +1294,7 @@ fi
|
||||||
;;
|
;;
|
||||||
|
|
||||||
## NetBSD and FreeBSD ( and maybe 386BSD also)
|
## NetBSD and FreeBSD ( and maybe 386BSD also)
|
||||||
*-*-*bsd*|*-*-darwin* )
|
*-*-*bsd* )
|
||||||
dir=bsd
|
dir=bsd
|
||||||
|
|
||||||
echo $ac_n "checking for ELF""... $ac_c" 1>&6
|
echo $ac_n "checking for ELF""... $ac_c" 1>&6
|
||||||
|
@ -1375,8 +1375,8 @@ EOF
|
||||||
|
|
||||||
;;
|
;;
|
||||||
|
|
||||||
## NT - cygwin
|
## NT - cygwin32
|
||||||
*-*-cygwin* )
|
*-*-cygwin32* )
|
||||||
dir=cygwin32
|
dir=cygwin32
|
||||||
;;
|
;;
|
||||||
|
|
||||||
|
|
|
@ -292,7 +292,7 @@ case "$host" in
|
||||||
;;
|
;;
|
||||||
|
|
||||||
## NetBSD and FreeBSD ( and maybe 386BSD also)
|
## NetBSD and FreeBSD ( and maybe 386BSD also)
|
||||||
*-*-*bsd*|*-*-darwin* )
|
*-*-*bsd* )
|
||||||
dir=bsd
|
dir=bsd
|
||||||
SCSH_ELF
|
SCSH_ELF
|
||||||
;;
|
;;
|
||||||
|
@ -322,8 +322,8 @@ case "$host" in
|
||||||
AC_DEFINE(HAVE_NLIST)
|
AC_DEFINE(HAVE_NLIST)
|
||||||
;;
|
;;
|
||||||
|
|
||||||
## NT - cygwin
|
## NT - cygwin32
|
||||||
*-*-cygwin* )
|
*-*-cygwin32* )
|
||||||
dir=cygwin32
|
dir=cygwin32
|
||||||
;;
|
;;
|
||||||
|
|
||||||
|
|
|
@ -1 +0,0 @@
|
||||||
html
|
|
|
@ -19,15 +19,12 @@ man.ind: man.idx
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
-rm *.log
|
-rm *.log
|
||||||
rm -rf html
|
|
||||||
|
|
||||||
INSTALL_DATA= install -c -m 644
|
INSTALL_DATA= install -c -m 644
|
||||||
|
|
||||||
tar:
|
tar:
|
||||||
tar cf - *.tex sty | gzip > man.tar.gz
|
tar cf - *.tex sty | gzip > man.tar.gz
|
||||||
|
|
||||||
html: $(TEX)
|
|
||||||
tex2page man && tex2page man
|
|
||||||
|
|
||||||
install: man.ps
|
install: man.ps
|
||||||
@echo WARNING:
|
@echo WARNING:
|
||||||
|
|
|
@ -76,7 +76,6 @@ characters.
|
||||||
|
|
||||||
|
|
||||||
\subsection{Parsing fields}
|
\subsection{Parsing fields}
|
||||||
\label{sec:field-splitter}
|
|
||||||
|
|
||||||
\defun {field-splitter} {[field num-fields]} \proc
|
\defun {field-splitter} {[field num-fields]} \proc
|
||||||
\defunx {infix-splitter} {[delim num-fields handle-delim]} \proc
|
\defunx {infix-splitter} {[delim num-fields handle-delim]} \proc
|
||||||
|
|
|
@ -0,0 +1,297 @@
|
||||||
|
%&latex -*- latex -*-
|
||||||
|
|
||||||
|
\chapter{Changes from previous releases}
|
||||||
|
\label{sec:changes}
|
||||||
|
|
||||||
|
\newcommand{\itam}[1]{\item {#1} \\}
|
||||||
|
|
||||||
|
\section{Changes from the previous release}
|
||||||
|
|
||||||
|
This section details changes that have been made in scsh since
|
||||||
|
the previous release.
|
||||||
|
|
||||||
|
Scsh is now much more robust.
|
||||||
|
All known bugs have been fixed.
|
||||||
|
There have been many improvements and extensions made.
|
||||||
|
These new features and changes are listed below, in no particular order;
|
||||||
|
the relevant sections of the manual give the full details.
|
||||||
|
|
||||||
|
Scsh now supports complete {\Posix}, including signal handlers.
|
||||||
|
Early autoreaping of child processes is now handled by a \ex{SIGCHLD}
|
||||||
|
signal handler, so children are reaped as early as possible with no
|
||||||
|
user intervention required.
|
||||||
|
|
||||||
|
A functional static heap linker is included in this release.
|
||||||
|
It is ugly, limited in functionality, and extremely slow, but it works.
|
||||||
|
It can be used to build scsh binaries that start up instantly.
|
||||||
|
|
||||||
|
The regular expression system has been sped up.
|
||||||
|
Regular-expression compilation is now provided,
|
||||||
|
and the \ex{awk} macro has been rewritten to pre-compile
|
||||||
|
regexps used in rules outside the loop.
|
||||||
|
It is still, however, slower than it should be.
|
||||||
|
|
||||||
|
Execing programs should be faster in this release, since we now use the
|
||||||
|
\ex{CLOEXEC} status bit to get automatic closing of unrevealed
|
||||||
|
port file descriptors.
|
||||||
|
|
||||||
|
{scm}'s floating point support was inadvertently omitted from the last
|
||||||
|
release. It has been reinstated.
|
||||||
|
|
||||||
|
There is now a new command-line switch, \ex{-sfd \var{num}},
|
||||||
|
which causes scsh to read its script from file descriptor \var{num}.
|
||||||
|
|
||||||
|
|
||||||
|
\section{Changes from the penultimate release}
|
||||||
|
|
||||||
|
This section details changes that have been made in scsh since
|
||||||
|
the penultimate release.
|
||||||
|
|
||||||
|
Scsh is now much more robust.
|
||||||
|
All known bugs have been fixed.
|
||||||
|
There have been many improvements and extensions made.
|
||||||
|
We have also made made some incompatible changes.
|
||||||
|
|
||||||
|
The sections below briefly describe these new features and changes;
|
||||||
|
the relevant sections of the manual give the full details.
|
||||||
|
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
\subsection{New features}
|
||||||
|
This release incorporates several new features into scsh.
|
||||||
|
|
||||||
|
\begin{itemize}
|
||||||
|
\itam{Control of buffered I/O}
|
||||||
|
Scsh now allows you to control the buffering policy used for doing I/O
|
||||||
|
on a Scheme port.
|
||||||
|
|
||||||
|
\itam{Here-strings}
|
||||||
|
Scsh now has a new lexical feature, \verb|#<<|, that provides
|
||||||
|
the ability to enter long, multi-line string constants in scsh programs.
|
||||||
|
Such a string is called a ``here string,'' by analogy to the common
|
||||||
|
shell ``here document'' \ex{<<} redirection.
|
||||||
|
|
||||||
|
\itam{Delimited readers and read-line}
|
||||||
|
Scsh now has a powerful set of delimited readers.
|
||||||
|
These can be used to read input delimited by
|
||||||
|
a newline character (\ex{read-line}),
|
||||||
|
a blank line (\ex{read-paragraph}),
|
||||||
|
or the occurrence of any character in an arbitrary set (\ex{read-delimited}).
|
||||||
|
|
||||||
|
While these procedures can be applied to any Scheme input port,
|
||||||
|
there is native-code support for performing delimited reads on
|
||||||
|
Unix input sources, so doing block input with these procedures should be
|
||||||
|
much faster than the equivalent character-at-a-time Scheme code.
|
||||||
|
|
||||||
|
\itam{New system calls}
|
||||||
|
With the sole exception of signal handlers, scsh now has all of {\Posix}.
|
||||||
|
This release introduces
|
||||||
|
\begin{itemize}
|
||||||
|
\item \ex{select},
|
||||||
|
\item full terminal device control,
|
||||||
|
\item support for pseudo-terminal ``pty'' devices,
|
||||||
|
\item file locking,
|
||||||
|
\item process timing,
|
||||||
|
\item \ex{set-file-times},
|
||||||
|
\item \ex{seek} and \ex{tell}.
|
||||||
|
\end{itemize}
|
||||||
|
|
||||||
|
Note that having \ex{select}, pseudo-terminals, and tty device control means
|
||||||
|
that it is now possible to implement interesting network protocols, such as
|
||||||
|
telnet servers and clients, directly in Scheme.
|
||||||
|
|
||||||
|
\itam{New command-line switches}
|
||||||
|
There is a new set of command-line switches that make it possible
|
||||||
|
to write shell scripts using the {\scm} module system.
|
||||||
|
Scripts can use the new command-line switches to open dependent
|
||||||
|
modules and load dependent source code.
|
||||||
|
Scripts can also be written in the {\scm} module language,
|
||||||
|
which allows you to use it both as a standalone shell script,
|
||||||
|
and as a code module that can be loaded and used by other Scheme programs.
|
||||||
|
|
||||||
|
\itam{Static heap linking}
|
||||||
|
There is a new facility that allows you to compile a heap image
|
||||||
|
to a \ex{.o} file that can be linked with the scsh virtual machine.
|
||||||
|
This produces a standalone executable binary, makes startup time
|
||||||
|
near-instantaneous, and greatly improves memory performance---the
|
||||||
|
initial heap image is placed in the process' text pages,
|
||||||
|
where it is shared by different scsh processes, and does not occupy
|
||||||
|
space in the run-time heap.
|
||||||
|
|
||||||
|
\oops{The static heap linker was not documented and installed in time
|
||||||
|
for this release.}
|
||||||
|
|
||||||
|
|
||||||
|
\end{itemize}
|
||||||
|
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
\subsection{Incompatible improvements}
|
||||||
|
Some features of scsh have been improved in ways that are
|
||||||
|
not backwards-compatible with previous releases.
|
||||||
|
These changes should not affect most code;
|
||||||
|
however, please note the changes and modify your code accordingly.
|
||||||
|
|
||||||
|
\begin{itemize}
|
||||||
|
\itam{New process-object data-type returned by \ex{fork}}
|
||||||
|
Previous releases were prone to fill up the kernel's process table
|
||||||
|
if a program forked large numbers of processes and subsequently failed
|
||||||
|
to use \ex{wait} to reclaim the entries in the kernel's process table.
|
||||||
|
(This is a problem in standard C environments, as well.)
|
||||||
|
|
||||||
|
Scsh 0.4 introduces a new mechanism for automatically managing subprocesses.
|
||||||
|
Processes are no longer represented by an integer process id,
|
||||||
|
which is impossible to garbage-collect, but by an
|
||||||
|
abstract process data type that encapsulates the process id.
|
||||||
|
All processes are represented using the new data structures;
|
||||||
|
see the relevant section of the manual for further details.
|
||||||
|
|
||||||
|
\itam{Better stdio/current-port synchronisation}
|
||||||
|
The \ex{(begin \ldots)} process form now does a \ex{stdio->stdports}
|
||||||
|
call before executing its body.
|
||||||
|
This means that the Scheme code in the body ``sees'' any external
|
||||||
|
redirections.
|
||||||
|
For example, it means that if a \ex{begin} form in the middle of a pipeline
|
||||||
|
performs I/O on the current input and output ports, it will be communicating
|
||||||
|
with its upstream and downstream pipes.
|
||||||
|
\Eg, this code works as intended without the need for explicit synchronisation:
|
||||||
|
\begin{verbatim}
|
||||||
|
(run (| (gunzip)
|
||||||
|
;; Kill line 1 and insert doubled-sided
|
||||||
|
;; code at head of Postscript.
|
||||||
|
(begin (read-line) ; Eat first line.
|
||||||
|
(display "%!PS-Adobe-2.0\\n")
|
||||||
|
(display "statusdict /setduplexmode known ")
|
||||||
|
(display "{statusdict begin true ")
|
||||||
|
(display "setduplexmode end} if\n")
|
||||||
|
(exec-epf (cat)))
|
||||||
|
(lpr))
|
||||||
|
(< paper.ps))\end{verbatim}
|
||||||
|
Arranging for the \ex{begin} process form to synchronise
|
||||||
|
the current I/O ports with stdio means that all process forms now
|
||||||
|
see their epf's redirections.
|
||||||
|
|
||||||
|
\itam{\ex{file-match} more robust}
|
||||||
|
The \ex{file-match} procedure now catches any error condition
|
||||||
|
signalled by a match procedure,
|
||||||
|
and treats it as if the procedure had simply returned {\sharpf},
|
||||||
|
\ie, match failure.
|
||||||
|
This means \ex{file-match} no longer gets blown out of the water by
|
||||||
|
trying to apply a function like \ex{file-directory?} to a dangling symlink,
|
||||||
|
and other related OS errors.
|
||||||
|
|
||||||
|
\itam{Standard input now unbuffered}
|
||||||
|
Scsh's startup code now makes the initial current input port
|
||||||
|
(corresponding to file descriptor 0) unbuffered.
|
||||||
|
This keeps the shell from ``stealing'' input meant for subprocesses.
|
||||||
|
However, it does slow down character-at-a-time input processing.
|
||||||
|
If you are writing a program that is tolerant of buffered input,
|
||||||
|
and wish the efficiency gains, you can reset the buffering policy
|
||||||
|
yourself.
|
||||||
|
|
||||||
|
\itam{``writeable'' now spelled ``writable''}
|
||||||
|
We inconsistently spelled \ex{file-writable?} and \ex{file-not-writable?}
|
||||||
|
in the manual and the implementation.
|
||||||
|
We have now standardised on the common spelling ``writable'' in both.
|
||||||
|
The older bindings still exist in release 0.4, but will go away in future
|
||||||
|
releases.
|
||||||
|
|
||||||
|
\itam{\protect\ex{char-set-member?} replaced}
|
||||||
|
We have de-released the \ex{char-set-member?} procedure.
|
||||||
|
The scsh 0.3 version of this procedure took arguments
|
||||||
|
in the following order:
|
||||||
|
\codex{(char-set-member? \var{char} \var{char-set})}
|
||||||
|
This argument order is in accordance with standard mathematical useage
|
||||||
|
(\ie, $x \in S$), and also consistent with the R4RS
|
||||||
|
\ex{member}, \ex{memq} and \ex{memv} procedures.
|
||||||
|
It is, however, exactly opposite from the argument order
|
||||||
|
used by the \ex{char-set-member?} in MIT Scheme's character-set library.
|
||||||
|
If we left things as they were, we risked problems with code
|
||||||
|
ported over from MIT Scheme.
|
||||||
|
On the other hand, changing to conformance with MIT Scheme meant
|
||||||
|
inconsistency with common mathematical notation and other long-standing
|
||||||
|
Scheme procedures.
|
||||||
|
Either way was bound to introduce confusion.
|
||||||
|
|
||||||
|
We've taken the approach of simply removing the \ex{char-set-member?}
|
||||||
|
procedure altogether, and replacing it with a new procedure:
|
||||||
|
\codex{(char-set-contains? \var{cset} \var{char})}
|
||||||
|
Note that the argument order is consistent with the name.
|
||||||
|
|
||||||
|
\itam{\ex{file-attributes} now \ex{file-info}}
|
||||||
|
In keeping with the general convention in scsh of naming procedures
|
||||||
|
that retrieve information about system resources \ex{\ldots-info}
|
||||||
|
(\eg, \ex{tty-info}, \ex{user-info}, \ex{group-info}),
|
||||||
|
the \ex{file-attributes} procedure is now named \ex{file-info}.
|
||||||
|
|
||||||
|
We continue to export a \ex{file-attributes} binding for the current
|
||||||
|
release, but it will go away in future releases.
|
||||||
|
|
||||||
|
\itam{Renaming of I/O synchronisation procedures}
|
||||||
|
The \ex{(stdio->stdports \var{thunk})} procedure has been
|
||||||
|
renamed \ex{with-stdio-ports*};
|
||||||
|
there is now a corresponding \ex{with-stdio-ports} special form.
|
||||||
|
The \ex{stdio->stdports} procedure is now a nullary procedure
|
||||||
|
that side-effects the current set of current I/O port bindings.
|
||||||
|
|
||||||
|
\itam{New meta-arg line-two syntax}
|
||||||
|
Scsh now uses a simplified grammar for describing command-line
|
||||||
|
arguments read by the ``meta-arg'' switch from line two of a shell script.
|
||||||
|
If you were using this feature in previous releases, the three incompatible
|
||||||
|
changes of which to be aware are:
|
||||||
|
(1) tab is no longer allowed as an argument delimiter,
|
||||||
|
(2) a run of space characters is not equivalent to a single space,
|
||||||
|
(3) empty arguments are written a different way.
|
||||||
|
\end{itemize}
|
||||||
|
|
||||||
|
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
\subsection{Backwards-compatible improvements}
|
||||||
|
|
||||||
|
Some existing features in scsh have been improved in ways that will
|
||||||
|
not effect existing code.
|
||||||
|
|
||||||
|
\begin{itemize}
|
||||||
|
\itam{Improved error reporting}
|
||||||
|
Exception handlers that print out error messages and warnings now
|
||||||
|
print their messages on the error output port,
|
||||||
|
instead of the current output port.
|
||||||
|
Previous releases used the current output port,
|
||||||
|
a problem inherited from Scheme 48.
|
||||||
|
|
||||||
|
Previous scsh releases flushed the Scheme 48 debugging tables when
|
||||||
|
creating the standard scsh heap image.
|
||||||
|
This trimmed the size of the heap image, but made error messages much
|
||||||
|
less comprehensible.
|
||||||
|
We now retain the debugging tables.
|
||||||
|
This bloats the heap image up by about 600kb. And worth it, too.
|
||||||
|
|
||||||
|
(We also have some new techniques for eliminating the run-time memory
|
||||||
|
penalty imposed by these large heap images.
|
||||||
|
Scsh's new static-heap technology allows for this data to be linked
|
||||||
|
into the text pages of the vm's binary, where it will not be touched
|
||||||
|
by the GC or otherwise affect the memory system until it is referenced.)
|
||||||
|
|
||||||
|
Finally, scsh now generates more informative error messages for syscall
|
||||||
|
errors.
|
||||||
|
For example, a file-open error previously told you what the error was
|
||||||
|
(\eg, ``Permission denied,'' or ``No such file or directory''),
|
||||||
|
but not which file you had tried to open.
|
||||||
|
We've improved this.
|
||||||
|
|
||||||
|
\itam{Closing a port twice allowed}
|
||||||
|
Scsh used to generate an error if you attempted to close a port
|
||||||
|
that had already been closed.
|
||||||
|
This is now allowed.
|
||||||
|
The close procedure returns a boolean to indicate whether the port had
|
||||||
|
already been closed or not.
|
||||||
|
|
||||||
|
\itam{Better time precision}
|
||||||
|
The \ex{time+ticks} procedure now returns sub-second precision on OS's
|
||||||
|
that support it.
|
||||||
|
|
||||||
|
\itam{Nicer print-methods for basic data-types}
|
||||||
|
Scsh's standard record types now print more informatively.
|
||||||
|
For example, a process object includes the process id in its
|
||||||
|
printed representation: the process object for process id 2653
|
||||||
|
prints as \verb|#{proc 2653}|.
|
||||||
|
|
||||||
|
\end{itemize}
|
|
@ -1,105 +0,0 @@
|
||||||
% css.t2p
|
|
||||||
% Dorai Sitaram
|
|
||||||
% 19 Jan 2001
|
|
||||||
% A basic style for HTML documents generated
|
|
||||||
% with tex2page.
|
|
||||||
|
|
||||||
\cssblock
|
|
||||||
|
|
||||||
body {
|
|
||||||
color: black;
|
|
||||||
background-color: #e5e5e5;
|
|
||||||
/*background-color: beige;*/
|
|
||||||
margin-top: 2em;
|
|
||||||
margin-left: 8%;
|
|
||||||
margin-right: 8%;
|
|
||||||
}
|
|
||||||
|
|
||||||
h1,h2,h3,h4,h5,h6 {
|
|
||||||
margin-top: .5em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.partheading {
|
|
||||||
font-size: 70%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.chapterheading {
|
|
||||||
font-size: 70%;
|
|
||||||
}
|
|
||||||
|
|
||||||
pre {
|
|
||||||
margin-left: 2em;
|
|
||||||
}
|
|
||||||
|
|
||||||
ol {
|
|
||||||
list-style-type: decimal;
|
|
||||||
}
|
|
||||||
|
|
||||||
ol ol {
|
|
||||||
list-style-type: lower-alpha;
|
|
||||||
}
|
|
||||||
|
|
||||||
ol ol ol {
|
|
||||||
list-style-type: lower-roman;
|
|
||||||
}
|
|
||||||
|
|
||||||
ol ol ol ol {
|
|
||||||
list-style-type: upper-alpha;
|
|
||||||
}
|
|
||||||
|
|
||||||
.scheme {
|
|
||||||
color: brown;
|
|
||||||
}
|
|
||||||
|
|
||||||
.scheme .keyword {
|
|
||||||
color: #990000;
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
|
|
||||||
.scheme .builtin {
|
|
||||||
color: #990000;
|
|
||||||
}
|
|
||||||
|
|
||||||
.scheme .variable {
|
|
||||||
color: navy;
|
|
||||||
}
|
|
||||||
|
|
||||||
.scheme .global {
|
|
||||||
color: purple;
|
|
||||||
}
|
|
||||||
|
|
||||||
.scheme .selfeval {
|
|
||||||
color: green;
|
|
||||||
}
|
|
||||||
|
|
||||||
.scheme .comment {
|
|
||||||
color: teal;
|
|
||||||
}
|
|
||||||
|
|
||||||
.navigation {
|
|
||||||
color: red;
|
|
||||||
text-align: right;
|
|
||||||
font-style: italic;
|
|
||||||
}
|
|
||||||
|
|
||||||
.disable {
|
|
||||||
/* color: #e5e5e5; */
|
|
||||||
color: gray;
|
|
||||||
}
|
|
||||||
|
|
||||||
.smallcaps {
|
|
||||||
font-size: 75%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.smallprint {
|
|
||||||
color: gray;
|
|
||||||
font-size: 75%;
|
|
||||||
text-align: right;
|
|
||||||
}
|
|
||||||
|
|
||||||
.smallprint hr {
|
|
||||||
text-align: left;
|
|
||||||
width: 40%;
|
|
||||||
}
|
|
||||||
|
|
||||||
\endcssblock
|
|
|
@ -23,8 +23,6 @@
|
||||||
\def\maketildeactive{\catcode`\~=13}
|
\def\maketildeactive{\catcode`\~=13}
|
||||||
\def\~{\char`\~}
|
\def\~{\char`\~}
|
||||||
|
|
||||||
\newcommand{\evalsto}{\ensuremath{\Rightarrow}}
|
|
||||||
|
|
||||||
% One-line code examples
|
% One-line code examples
|
||||||
%\newcommand{\codex}[1]% One line, centred. Tight spacing.
|
%\newcommand{\codex}[1]% One line, centred. Tight spacing.
|
||||||
% {$$\abovedisplayskip=.75ex plus 1ex minus .5ex%
|
% {$$\abovedisplayskip=.75ex plus 1ex minus .5ex%
|
||||||
|
|
|
@ -3,17 +3,11 @@
|
||||||
\title{Scsh Reference Manual}
|
\title{Scsh Reference Manual}
|
||||||
\subtitle{For scsh release 0.5.3}
|
\subtitle{For scsh release 0.5.3}
|
||||||
\author{Olin Shivers and Brian D.~Carlstrom}
|
\author{Olin Shivers and Brian D.~Carlstrom}
|
||||||
\date{June 2001}
|
\date{September 1999}
|
||||||
|
|
||||||
\maketitle
|
\maketitle
|
||||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
% Some code-changes for tex2page and latex output. NF
|
|
||||||
\texonly
|
|
||||||
\chapter*{Acknowledgements}
|
\chapter*{Acknowledgements}
|
||||||
\endtexonly
|
|
||||||
\htmlonly
|
|
||||||
\\ \ex{Acknowledgements} \\ \\
|
|
||||||
\endhtmlonly
|
|
||||||
|
|
||||||
Who should I thank?
|
Who should I thank?
|
||||||
My so-called ``colleagues,'' who laugh at me behind my back,
|
My so-called ``colleagues,'' who laugh at me behind my back,
|
||||||
|
|
|
@ -18,30 +18,6 @@ This manual gives a complete description of scsh.
|
||||||
A general discussion of the design principles behind scsh can be found
|
A general discussion of the design principles behind scsh can be found
|
||||||
in a companion paper, ``A Scheme Shell.''
|
in a companion paper, ``A Scheme Shell.''
|
||||||
|
|
||||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
||||||
\section{Copyright \& source-code license}
|
|
||||||
Scsh is open source. The complete sources come with the standard
|
|
||||||
distribution, which can be downloaded off the net.
|
|
||||||
|
|
||||||
For years, scsh's underlying Scheme implementation, Scheme 48, did not have an
|
|
||||||
open-source copyright. However, around 1999/2000, the Scheme 48 authors
|
|
||||||
graciously retrofitted a BSD-style open-source copyright onto the system.
|
|
||||||
Swept up by the fervor, we tacked an ideologically hip license onto scsh
|
|
||||||
source, ourselves (BSD-style, as well). Not that we ever cared before what you
|
|
||||||
did with the system.
|
|
||||||
|
|
||||||
As a result, the whole system is now open source, top-to-bottom.
|
|
||||||
|
|
||||||
We note that the code is a rich source for other Scheme implementations
|
|
||||||
to mine. Not only the \emph{code}, but the \emph{APIs} are available
|
|
||||||
for implementors working on Scheme environments for systems programming.
|
|
||||||
These APIs represent years of work, and should provide a big head-start
|
|
||||||
on any related effort. (Just don't call it ``scsh,'' unless it's
|
|
||||||
\emph{exactly} compliant with the scsh interfaces.)
|
|
||||||
|
|
||||||
Take all the code you like; we'll just write more.
|
|
||||||
|
|
||||||
|
|
||||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
\section{Obtaining scsh}
|
\section{Obtaining scsh}
|
||||||
Scsh is distributed via net publication.
|
Scsh is distributed via net publication.
|
||||||
|
@ -49,9 +25,9 @@ We place new releases at well-known network sites,
|
||||||
and allow them to propagate from there.
|
and allow them to propagate from there.
|
||||||
We currently release scsh to the following Internet sites:
|
We currently release scsh to the following Internet sites:
|
||||||
\begin{inset}\begin{flushleft}
|
\begin{inset}\begin{flushleft}
|
||||||
\ex{\urlh{ftp://ftp-swiss.ai.mit.edu/pub/su/}{ftp://ftp-swiss.ai.mit.edu/pub/su/}} \\
|
\ex{ftp://ftp-swiss.ai.mit.edu/pub/su/} \\
|
||||||
\ex{\urlh{http://www-swiss.ai.mit.edu/scsh/scsh.html}{http://www-swiss.ai.mit.edu/scsh/scsh.html}} \\
|
\ex{http://www-swiss.ai.mit.edu/scsh/scsh.html}
|
||||||
\ex{\urlh{http://www.cs.indiana.edu/scheme-repository/}{http://www.cs.indiana.edu/scheme-repository/}} \\
|
\ex{http://www.cs.indiana.edu/scheme-repository/} \\
|
||||||
\end{flushleft}
|
\end{flushleft}
|
||||||
\end{inset}
|
\end{inset}
|
||||||
These sites are
|
These sites are
|
||||||
|
@ -124,11 +100,14 @@ but the system as-released does not currently provide these features.
|
||||||
|
|
||||||
In the current release, the system has some rough edges.
|
In the current release, the system has some rough edges.
|
||||||
It is quite slow to start up---loading the initial image into the
|
It is quite slow to start up---loading the initial image into the
|
||||||
{\scm} virtual machine induces a noticeable delay.
|
{\scm} virtual machine takes about a cpu second.
|
||||||
This can be fixed with the static heap linker provided with this release.
|
This can be fixed with the static heap linker provided with this release.
|
||||||
|
|
||||||
We welcome parties interested in porting the manual to a more portable
|
This manual is very, very rough.
|
||||||
XML or SGML format; please contact us if you are interested in doing so.
|
At some point, we hope to polish it up, finish it off, and re-typeset it
|
||||||
|
using markup, so we can generate html, info nodes, and {\TeX} output from
|
||||||
|
the single source without having to deal with Texinfo.
|
||||||
|
But it's all there is, for now.
|
||||||
|
|
||||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
\section{Naming conventions}
|
\section{Naming conventions}
|
||||||
|
@ -396,17 +375,11 @@ All told, the \ex{define-record} form above defines the following procedures:
|
||||||
(ship:size \var{ship}) & Retrieve the \var{size} field. \\
|
(ship:size \var{ship}) & Retrieve the \var{size} field. \\
|
||||||
\hline
|
\hline
|
||||||
(set-ship:x \var{ship} \var{new-x}) & Assign the \var{x} field. \\
|
(set-ship:x \var{ship} \var{new-x}) & Assign the \var{x} field. \\
|
||||||
(set-ship:y \var{ship} \var{new-y}) & Assign the \var{y} field. \\
|
(set-ship:y \var{ship} \var{new-y}) & Assign the \var{x} field. \\
|
||||||
(set-ship:size \var{ship} \var{new-size}) & Assign the \var{size} field. \\
|
(set-ship:size \var{ship} \var{new-size}) & Assign the \var{size} field. \\
|
||||||
\hline
|
\hline
|
||||||
(modify-ship:x \var{ship} \var{xfun}) & Modify \var{x} field with \var{xfun}. \\
|
|
||||||
(modify-ship:y \var{ship} \var{yfun}) & Modify \var{y} field with \var{yfun}. \\
|
|
||||||
(modify-ship:size \var{ship} \var{sizefun}) & Modify \var{size} field with \var{sizefun}. \\
|
|
||||||
\hline
|
|
||||||
(ship? \var{object}) & Type predicate. \\
|
(ship? \var{object}) & Type predicate. \\
|
||||||
\hline
|
\hline
|
||||||
(copy-ship \var{ship}) & Shallow-copy of the record. \\
|
|
||||||
\hline
|
|
||||||
\end{tabular}
|
\end{tabular}
|
||||||
\end{center}
|
\end{center}
|
||||||
%
|
%
|
||||||
|
@ -415,8 +388,6 @@ An implementation of \ex{define-record} is available as a macro for Scheme
|
||||||
programmers to define their own record types;
|
programmers to define their own record types;
|
||||||
the syntax is accessed by opening the package \ex{defrec-package}, which
|
the syntax is accessed by opening the package \ex{defrec-package}, which
|
||||||
exports the single syntax form \ex{define-record}.
|
exports the single syntax form \ex{define-record}.
|
||||||
See the source code for the \ex{defrec-package} module
|
|
||||||
for further details of the macro.
|
|
||||||
|
|
||||||
You must open this package to access the form.
|
You must open this package to access the form.
|
||||||
Scsh does not export a record-definition package by default as there are
|
Scsh does not export a record-definition package by default as there are
|
||||||
|
@ -446,9 +417,21 @@ you could not read and internalise such a twisted account without
|
||||||
bleeding from the nose and ears.
|
bleeding from the nose and ears.
|
||||||
|
|
||||||
However, you might keep in mind the following simple fact: of all the
|
However, you might keep in mind the following simple fact: of all the
|
||||||
standards, {\Posix} is the least common denominator.
|
standards, {\Posix}, as far as I have been able to determine,
|
||||||
|
is the least common denominator.
|
||||||
So when this manual repeatedly refers to {\Posix}, the point is ``the
|
So when this manual repeatedly refers to {\Posix}, the point is ``the
|
||||||
thing we are describing should be portable just about anywhere.''
|
thing we are describing should be portable just about anywhere.''
|
||||||
Scsh sticks to {\Posix} when at all possible; its major departure is
|
Scsh sticks to {\Posix} when at all possible; it's major departure is
|
||||||
symbolic links, which aren't in {\Posix} (see---it
|
symbolic links, which aren't in {\Posix} (see---it
|
||||||
really \emph{is} a least common denominator).
|
really \emph{is} a least common denominator).
|
||||||
|
|
||||||
|
However, just because {\Posix} is the l.c.d. standard doesn't mean everyone
|
||||||
|
supports all of it.
|
||||||
|
The guerilla PC {\Unix} implementations that have been springing up on
|
||||||
|
the net (\eg, NetBSD, Linux, FreeBSD, and so forth) are only recently coming
|
||||||
|
into compliance with the standard---although they are getting there.
|
||||||
|
We have been able to implement scsh completely on all of these systems,
|
||||||
|
however---the single exception is NeXTSTEP, whose buggy {\Posix} libraries
|
||||||
|
restricts us to partial support (these lacunae are indicated where relevant
|
||||||
|
in the rest of the manual).\footnote{Feel like porting scsh from {\Posix} to
|
||||||
|
NeXT's BSD API? Send us your fixes; we'll fold them in.}
|
||||||
|
|
|
@ -1,126 +0,0 @@
|
||||||
% man.t2p
|
|
||||||
% Dorai Sitaram
|
|
||||||
% Feb 6, 2000
|
|
||||||
|
|
||||||
% This file contains the tex2page macros needed to process
|
|
||||||
% the scsh LaTeX document scsh-n.n.n/doc/scsh-manual/man.tex.
|
|
||||||
% Copy (or link) this file alongside man.tex and run
|
|
||||||
%
|
|
||||||
% tex2page man
|
|
||||||
|
|
||||||
\input css.t2p
|
|
||||||
\dontuseimgforhtmlmath
|
|
||||||
|
|
||||||
\let\pagebreak\relax
|
|
||||||
|
|
||||||
\let\small\relax
|
|
||||||
|
|
||||||
%\let\PRIMtableofcontents\tableofcontents
|
|
||||||
%\def\tableofcontents{\chapter*{Contents}\PRIMtableofcontents}
|
|
||||||
|
|
||||||
\def\subtitle#1{\def\savesubtitle{#1}}
|
|
||||||
|
|
||||||
\def\maketitle{
|
|
||||||
\subject{\TIIPtitle}
|
|
||||||
{\bf \hr}
|
|
||||||
\rightline{\savesubtitle}
|
|
||||||
\bigskip\bigskip
|
|
||||||
\bigskip\bigskip
|
|
||||||
{\bf\TIIPauthor}
|
|
||||||
{\bf\hr}
|
|
||||||
}
|
|
||||||
|
|
||||||
\let\PRIMdocument\document
|
|
||||||
|
|
||||||
\def\document{\PRIMdocument
|
|
||||||
|
|
||||||
\let\ttchars\relax
|
|
||||||
\let\ttt\tt
|
|
||||||
|
|
||||||
%\def\~{\rawhtml~\endrawhtml}
|
|
||||||
\def\~{\char`\~}
|
|
||||||
\def\cd#1{{\tt\def\\{\char`\\}\defcsactive\${\char`\$}\defcsactive\&{\char`\&}#1}}
|
|
||||||
\def\cddollar{\undefcsactive\$}
|
|
||||||
\def\cdmath{\undefcsactive\$}
|
|
||||||
\def\codeallowbreaks{\relax}
|
|
||||||
\def\defvarx#1#2{\index{#1}\leftline{{\tt #1} \qquad #2}}
|
|
||||||
|
|
||||||
\let\PRIMflushright\flushright
|
|
||||||
|
|
||||||
\def\flushright{\PRIMflushright\TIIPtabularborder=0 }
|
|
||||||
|
|
||||||
\let\PRIMfigure\figure
|
|
||||||
\let\PRIMendfigure\endfigure
|
|
||||||
|
|
||||||
\def\figure{\par\hrule\PRIMfigure}
|
|
||||||
\def\endfigure{\PRIMendfigure\hrule\par}
|
|
||||||
|
|
||||||
\let\PRIMtable\table
|
|
||||||
\let\PRIMendtable\endtable
|
|
||||||
|
|
||||||
\def\table{\par\hrule\PRIMtable}
|
|
||||||
\def\endtable{\PRIMendtable\hrule\par}
|
|
||||||
|
|
||||||
\imgdef\vdots{\bf.\par.\par.}
|
|
||||||
|
|
||||||
\evalh{
|
|
||||||
|
|
||||||
(define all-blanks?
|
|
||||||
(lambda (s)
|
|
||||||
(andmap
|
|
||||||
char-whitespace?
|
|
||||||
(string->list s))))
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
\def\spaceifnotempty{\evalh{
|
|
||||||
|
|
||||||
(let ((x (ungroup (get-token))))
|
|
||||||
(unless (all-blanks? x)
|
|
||||||
(emit #\space)))
|
|
||||||
|
|
||||||
}}
|
|
||||||
|
|
||||||
\def\dfnix#1#2#3#4{\leftline{{\tt(#1\spaceifnotempty{#2}{\it#2})} \quad $\longrightarrow$ \quad {\it #3} \qquad (#4)} \index}
|
|
||||||
|
|
||||||
\def\ex#1{{\tt #1}}
|
|
||||||
\def\l#1{lambda (#1)}
|
|
||||||
\def\lx#1{lambda {#1}}
|
|
||||||
%\def\notenum#1{}
|
|
||||||
%\def\project#1{}
|
|
||||||
\def\var#1{{\it #1\/}}
|
|
||||||
\def\vari#1#2{\mbox{{\it #1\/}\undefcsactive\$$_{#2}$}}
|
|
||||||
|
|
||||||
\renewenvironment{boxedfigure}{\def\srecomment#1{\\#1\\}%
|
|
||||||
\begin{figure}\pagestyle}{\end{figure}}
|
|
||||||
|
|
||||||
\newenvironment{centercode}{\begin{code}}{\end{code}}
|
|
||||||
|
|
||||||
\def\setupcode{\tt%
|
|
||||||
\def\\{\char`\\}%
|
|
||||||
\defcsactive\${\$}%
|
|
||||||
\def\evalto{==> }%
|
|
||||||
\defcsactive\%{\%}\obeywhitespace}
|
|
||||||
|
|
||||||
\newenvironment{code}{\begin{quote}\bgroup\setupcode\GOBBLEOPTARG}
|
|
||||||
{\egroup\end{quote}}
|
|
||||||
|
|
||||||
\newenvironment{codebox}{\begin{tableplain}\bgroup\setupcode\GOBBLEOPTARG}
|
|
||||||
{\egroup\end{tableplain}}
|
|
||||||
|
|
||||||
\renewenvironment{desc}{\begin{quote}}{\end{quote}}
|
|
||||||
|
|
||||||
\renewenvironment{exampletable}{%
|
|
||||||
\def\header#1{\\\leftline{#1}\\}%
|
|
||||||
\def\splitline#1#2{\\\leftline{#1}\\\leftline{#2}}%
|
|
||||||
\begin{tabular}{}}{\end{tabular}}
|
|
||||||
|
|
||||||
\newenvironment{tightcode}{\begin{code}}{\end{code}}
|
|
||||||
\renewenvironment{widecode}{\begin{code}}{\end{code}}
|
|
||||||
|
|
||||||
\renewenvironment{inset}{\begin{quote}}{\end{quote}}
|
|
||||||
\renewenvironment{leftinset}{\begin{quote}}{\end{quote}}
|
|
||||||
\renewenvironment{tightinset}{\begin{quote}}{\end{quote}}
|
|
||||||
\renewenvironment{tightleftinset}{\begin{quote}}{\end{quote}}
|
|
||||||
}
|
|
|
@ -1,19 +1,16 @@
|
||||||
% -*- latex -*-
|
%&latex -*- latex -*-
|
||||||
|
|
||||||
% This is the reference manual for the Scheme Shell.
|
% This is the reference manual for the Scheme Shell.
|
||||||
|
|
||||||
\documentclass[twoside]{report}
|
\documentclass[twoside]{report}
|
||||||
\usepackage{code,boxedminipage,makeidx,palatino,ct,
|
\usepackage{code,boxedminipage,makeidx,palatino,ct,
|
||||||
headings,mantitle,array,matter,mysize10,tex2page}
|
headings,mantitle,array,matter,mysize10}
|
||||||
|
|
||||||
\texonly
|
|
||||||
\let\url\relax
|
|
||||||
\usepackage[dvipdfm,hyperindex,hypertex,
|
\usepackage[dvipdfm,hyperindex,hypertex,
|
||||||
pdftitle={scsh manual, release 0.5.3},
|
pdftitle={scsh manual, release 0.5.3},
|
||||||
pdfauthor={Olin Shivers and Brian D.~Carlstrom}
|
pdfauthor={Olin Shivers and Brian D.~Carlstrom}
|
||||||
colorlinks=true,linkcolor=blue,pagecolor=blue,urlcolor=blue,
|
colorlinks=true,linkcolor=blue,pagecolor=blue,urlcolor=blue,
|
||||||
pdfstartview=FitH,pdfview=FitH]{hyperref}
|
pdfstartview=FitH,pdfview=FitH]{hyperref}
|
||||||
\endtexonly
|
|
||||||
|
|
||||||
% These fonts are good choices for screen-readable pdf, but the man needs
|
% These fonts are good choices for screen-readable pdf, but the man needs
|
||||||
% a pass over the layout, since the this tt font will blow out the width
|
% a pass over the layout, since the this tt font will blow out the width
|
||||||
|
@ -50,6 +47,7 @@
|
||||||
\include{awk}
|
\include{awk}
|
||||||
\include{miscprocs}
|
\include{miscprocs}
|
||||||
\include{running}
|
\include{running}
|
||||||
|
\include{changes}
|
||||||
\include{todo}
|
\include{todo}
|
||||||
|
|
||||||
\backmatter
|
\backmatter
|
||||||
|
|
|
@ -50,8 +50,7 @@
|
||||||
\vskip -0.3\baselineskip
|
\vskip -0.3\baselineskip
|
||||||
\wideline{\leaders\hrule height 4pt\hfill}
|
\wideline{\leaders\hrule height 4pt\hfill}
|
||||||
\wideline{\hfill\subtitlefont\begin{tabular}[t]{@{}r@{}}\@subtitle%
|
\wideline{\hfill\subtitlefont\begin{tabular}[t]{@{}r@{}}\@subtitle%
|
||||||
\\\@date%
|
\end{tabular}\hskip 1in} % subtitle
|
||||||
\end{tabular}} % subtitle
|
|
||||||
%
|
%
|
||||||
% author
|
% author
|
||||||
\vskip 0pt plus 1filll
|
\vskip 0pt plus 1filll
|
||||||
|
|
|
@ -140,7 +140,7 @@ That is, it is equivalent to:
|
||||||
%
|
%
|
||||||
\codex{(begin (apply exec-path `(\var{prog} \vari{arg}1 {\ldots} \vari{arg}n)))}
|
\codex{(begin (apply exec-path `(\var{prog} \vari{arg}1 {\ldots} \vari{arg}n)))}
|
||||||
%
|
%
|
||||||
\ex{Exec-path} is the version of the \ex{\urlh{http://www.FreeBSD.org/cgi/man.cgi?query=exec&apropos=0&sektion=0&manpath=FreeBSD+4.3-RELEASE&format=html}{exec()}} system call that
|
\ex{Exec-path} is the version of the \ex{exec()} system call that
|
||||||
uses scsh's path list to search for an executable.
|
uses scsh's path list to search for an executable.
|
||||||
The program and the arguments must be either strings, symbols, or integers.
|
The program and the arguments must be either strings, symbols, or integers.
|
||||||
Symbols and integers are coerced to strings.
|
Symbols and integers are coerced to strings.
|
||||||
|
@ -438,7 +438,7 @@ Our scsh programmer decides to run \ex{myprog} with stdout and stderr redirected
|
||||||
\emph{via {\Unix} pipes} to the ports \ex{port1} and \ex{port2}, respectively.
|
\emph{via {\Unix} pipes} to the ports \ex{port1} and \ex{port2}, respectively.
|
||||||
He gets into trouble when he subsequently says \ex{(read port2)}.
|
He gets into trouble when he subsequently says \ex{(read port2)}.
|
||||||
The {\Scheme} \ex{read} routine reads the open paren, and then hangs in a
|
The {\Scheme} \ex{read} routine reads the open paren, and then hangs in a
|
||||||
\ex{\urlh{http://www.FreeBSD.org/cgi/man.cgi?query=read&apropos=0&sektion=0&manpath=FreeBSD+4.3-RELEASE&format=html}{read()}} system call trying to read a matching close paren.
|
\ex{read()} system call trying to read a matching close paren.
|
||||||
But before \ex{myprog} sends the close paren down the stderr
|
But before \ex{myprog} sends the close paren down the stderr
|
||||||
pipe, it first tries to write a megabyte of data to the stdout pipe.
|
pipe, it first tries to write a megabyte of data to the stdout pipe.
|
||||||
However, {\Scheme} is not reading that pipe---it's stuck waiting for input on
|
However, {\Scheme} is not reading that pipe---it's stuck waiting for input on
|
||||||
|
|
|
@ -398,7 +398,7 @@ would implement a simple-minded version of the Unix \ex{echo} program:
|
||||||
%
|
%
|
||||||
The idea would be that the command
|
The idea would be that the command
|
||||||
\codex{ekko Hi there.}
|
\codex{ekko Hi there.}
|
||||||
would by expanded by the \ex{\urlh{http://www.FreeBSD.org/cgi/man.cgi?query=exec&apropos=0&sektion=0&manpath=FreeBSD+4.3-RELEASE&format=html}{exec(2)}} kernel call into
|
would by expanded by the \ex{exec(2)} kernel call into
|
||||||
%
|
%
|
||||||
\begin{code}
|
\begin{code}
|
||||||
/usr/local/bin/scsh -e main -s ekko Hi there.\end{code}
|
/usr/local/bin/scsh -e main -s ekko Hi there.\end{code}
|
||||||
|
@ -408,7 +408,7 @@ call the entry point on the command-line list
|
||||||
\codex{(main '("ekko" "Hi" "there."))}
|
\codex{(main '("ekko" "Hi" "there."))}
|
||||||
and exit.
|
and exit.
|
||||||
|
|
||||||
Unfortunately, the {\Unix} \ex{\urlh{http://www.FreeBSD.org/cgi/man.cgi?query=exec&apropos=0&sektion=0&manpath=FreeBSD+4.3-RELEASE&format=html}{exec(2)}} syscall's support for scripts is
|
Unfortunately, the {\Unix} \ex{exec(2)} syscall's support for scripts is
|
||||||
not very general or well-designed.
|
not very general or well-designed.
|
||||||
It will not handle multiple arguments;
|
It will not handle multiple arguments;
|
||||||
the \ex{\#!} line is usually required to contain no more than 32 characters;
|
the \ex{\#!} line is usually required to contain no more than 32 characters;
|
||||||
|
@ -555,7 +555,7 @@ Writing it this way makes it possible to compile the program
|
||||||
(for-each (\l{arg} (display arg) (display " "))
|
(for-each (\l{arg} (display arg) (display " "))
|
||||||
(cdr args)))\end{code}
|
(cdr args)))\end{code}
|
||||||
%
|
%
|
||||||
The \ex{\urlh{http://www.FreeBSD.org/cgi/man.cgi?query=exec&apropos=0&sektion=0&manpath=FreeBSD+4.3-RELEASE&format=html}{exec(2)}} expansion of the \ex{\#!} line together with
|
The \ex{exec(2)} expansion of the \ex{\#!} line together with
|
||||||
the scsh expansion of the ``\verb|\ ekko|'' meta-argument
|
the scsh expansion of the ``\verb|\ ekko|'' meta-argument
|
||||||
(see section~\ref{sec:meta-arg}) gives the following command-line expansion:
|
(see section~\ref{sec:meta-arg}) gives the following command-line expansion:
|
||||||
\begin{code}
|
\begin{code}
|
||||||
|
|
|
@ -1,71 +1,27 @@
|
||||||
% -*- latex -*-
|
% -*- latex -*-
|
||||||
\chapter{Strings and characters}
|
\chapter{Strings and characters}
|
||||||
|
|
||||||
Strings are the basic communication medium for {\Unix} processes, so a
|
Scsh provides a set of procedures for processing strings and characters.
|
||||||
Unix programming environment must have reasonable facilities for manipulating
|
The procedures provided match regular expressions, search strings,
|
||||||
them.
|
parse file-names, and manipulate sets of characters.
|
||||||
Scsh provides a powerful set of procedures for processing strings and
|
|
||||||
characters.
|
|
||||||
Besides the the facilities described in this chapter, scsh also provides
|
|
||||||
\begin{itemize}
|
|
||||||
\itum{Regular expressions (chapter~\ref{chapt:sre})}
|
|
||||||
A complete regular-expression system.
|
|
||||||
|
|
||||||
\itum{Field parsing, delimited record I/O and the awk loop
|
Also see chapters \ref{chapt:sre}, \ref{chapt:rdelim} and \ref{chapt:fr-awk}
|
||||||
(chapter~\ref{chapt:fr-awk})}
|
on regular-expressions, record I/O, field parsing, and the awk loop.
|
||||||
These procedures let you read in chunks of text delimited by selected
|
The procedures documented there allow you to search and pattern-match strings,
|
||||||
characters, and
|
read character-delimited records from ports,
|
||||||
parse each record into fields based on regular expressions
|
use regular expressions to split the records into fields
|
||||||
(for example, splitting a string at every occurrence of colon or
|
(for example, splitting a string at every occurrence of colon or white-space),
|
||||||
white-space).
|
and loop over streams of these records in a convenient way.
|
||||||
The \ex{awk} form allows you to loop over streams of these records
|
|
||||||
in a convenient way.
|
|
||||||
|
|
||||||
\itum{The SRFI-13 string libraries}
|
|
||||||
This pair of libraries contains procedures that create, fold, iterate over,
|
|
||||||
search, compare, assemble, cut, hash, case-map, and otherwise manipulate
|
|
||||||
strings.
|
|
||||||
They are provided by the \ex{string-lib} and \ex{string-lib-internals}
|
|
||||||
packages, and are also available in the default \ex{scsh} package.
|
|
||||||
|
|
||||||
More documentation on these procedures can be found at URLs
|
|
||||||
\begin{tightinset}
|
|
||||||
% The gratuitous mbox makes xdvi render the hyperlinks better.
|
|
||||||
\texonly
|
|
||||||
\mbox{\url{http://srfi.schemers.org/srfi-13/srfi-13.html}}\\
|
|
||||||
\url{http://srfi.schemers.org/srfi-13/srfi-13.txt}
|
|
||||||
\endtexonly
|
|
||||||
% Changed the \mbox into \urlh for tex2page to avoid problems runing tex2page
|
|
||||||
\htmlonly
|
|
||||||
\urlh{http://srfi.schemers.org/srfi-13/srfi-13.html}{http://srfi.schemers.org/srfi-13/srfi-13.html}\\
|
|
||||||
\urlh{http://srfi.schemers.org/srfi-13/srfi-13.txt}{http://srfi.schemers.org/srfi-13/srfi-13.txt}
|
|
||||||
\endhtmlonly
|
|
||||||
\end{tightinset}
|
|
||||||
|
|
||||||
\itum{The SRFI-14 character-set library}
|
|
||||||
This library provides a set-of-characters abstraction, which is frequently
|
|
||||||
useful when searching, parsing, filtering or otherwise operating on
|
|
||||||
strings and character data. The SRFI is provided by the \ex{char-set-lib}
|
|
||||||
package; it's bindings are also available in the default \ex{scsh} package.
|
|
||||||
|
|
||||||
More documentation on this library can be found at URLs
|
|
||||||
\begin{tightinset}
|
|
||||||
% The gratuitous mbox makes xdvi render the hyperlinks better.
|
|
||||||
\texonly
|
|
||||||
\mbox{\url{http://srfi.schemers.org/srfi-14/srfi-14.html}}\\
|
|
||||||
\url{http://srfi.schemers.org/srfi-14/srfi-14.txt}
|
|
||||||
\endtexonly
|
|
||||||
% Changed the \mbox into \urlh for tex2page to avoid problems runing tex2page
|
|
||||||
\htmlonly
|
|
||||||
\urlh{http://srfi.schemers.org/srfi-14/srfi-14.html}{http://srfi.schemers.org/srfi-14/srfi-14.html}\\
|
|
||||||
\urlh{http://srfi.schemers.org/srfi-14/srfi-14.txt}{http://srfi.schemers.org/srfi-14/srfi-14.txt}
|
|
||||||
\endhtmlonly
|
|
||||||
\end{tightinset}
|
|
||||||
|
|
||||||
\end{itemize}
|
|
||||||
|
|
||||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
\section{Manipulating file names}
|
\section{String manipulation}
|
||||||
|
\label{sec:stringmanip}
|
||||||
|
|
||||||
|
Strings are the basic communication medium for {\Unix} processes, so a
|
||||||
|
shell language must have reasonable facilities for manipulating them.
|
||||||
|
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
\subsection{Manipulating file-names}
|
||||||
\label{sec:filenames}
|
\label{sec:filenames}
|
||||||
|
|
||||||
These procedures do not access the file-system at all; they merely operate
|
These procedures do not access the file-system at all; they merely operate
|
||||||
|
@ -74,7 +30,7 @@ design. Perhaps a more sophisticated system would be better, something
|
||||||
like the pathname abstractions of {\CommonLisp} or MIT Scheme. However,
|
like the pathname abstractions of {\CommonLisp} or MIT Scheme. However,
|
||||||
being {\Unix}-specific, we can be a little less general.
|
being {\Unix}-specific, we can be a little less general.
|
||||||
|
|
||||||
\subsection{Terminology}
|
\subsubsection{Terminology}
|
||||||
These procedures carefully adhere to the {\Posix} standard for file-name
|
These procedures carefully adhere to the {\Posix} standard for file-name
|
||||||
resolution, which occasionally entails some slightly odd things.
|
resolution, which occasionally entails some slightly odd things.
|
||||||
This section will describe these rules, and give some basic terminology.
|
This section will describe these rules, and give some basic terminology.
|
||||||
|
@ -139,7 +95,7 @@ interpreted in file-name form, \ie, as root.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
\subsection{Procedures}
|
\subsubsection{Procedures}
|
||||||
|
|
||||||
\defun {file-name-directory?} {fname} \boolean
|
\defun {file-name-directory?} {fname} \boolean
|
||||||
\defunx {file-name-non-directory?} {fname} \boolean
|
\defunx {file-name-non-directory?} {fname} \boolean
|
||||||
|
@ -399,7 +355,38 @@ is also frequently useful for expanding file-names.
|
||||||
|
|
||||||
|
|
||||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
\section{Other string manipulation facilities}
|
\subsection{Other string manipulation facilities}
|
||||||
|
|
||||||
|
\defun {index} {string char [start]} {{\fixnum} or false}
|
||||||
|
\defunx {rindex} {string char [start]} {{\fixnum} or false}
|
||||||
|
\begin{desc}
|
||||||
|
These procedures search through \var{string} looking for an occurrence
|
||||||
|
of character \var{char}. \ex{index} searches left-to-right; \ex{rindex}
|
||||||
|
searches right-to-left.
|
||||||
|
|
||||||
|
\ex{index} returns the smallest index $i$ of \var{string} greater
|
||||||
|
than or equal to \var{start} such that $\var{string}[i] = \var{char}$.
|
||||||
|
The default for \var{start} is zero. If there is no such match,
|
||||||
|
\ex{index} returns false.
|
||||||
|
|
||||||
|
\ex{rindex} returns the largest index $i$ of \var{string} less than
|
||||||
|
\var{start} such that $\var{string}[i] = \var{char}$.
|
||||||
|
The default for \var{start} is \ex{(string-length \var{string})}.
|
||||||
|
If there is no such match, \ex{rindex} returns false.
|
||||||
|
\end{desc}
|
||||||
|
|
||||||
|
I should probably snarf all the MIT Scheme string functions, and stick them
|
||||||
|
in a package. {\Unix} programs need to mung character strings a lot.
|
||||||
|
|
||||||
|
MIT string match commands:
|
||||||
|
\begin{tightcode}
|
||||||
|
[sub]string-match-{forward,backward}[-ci]
|
||||||
|
[sub]string-{prefix,suffix}[-ci]?
|
||||||
|
[sub]string-find-{next,previous}-char[-ci]
|
||||||
|
[sub]string-find-{next,previous}-char-in-set
|
||||||
|
[sub]string-replace[!]
|
||||||
|
\ldots\etc\end{tightcode}
|
||||||
|
These are not currently provided.
|
||||||
|
|
||||||
\begin{defundesc} {substitute-env-vars} {fname} \str
|
\begin{defundesc} {substitute-env-vars} {fname} \str
|
||||||
Replace occurrences of environment variables with their values.
|
Replace occurrences of environment variables with their values.
|
||||||
|
@ -425,72 +412,315 @@ is also frequently useful for expanding file-names.
|
||||||
\end{desc}
|
\end{desc}
|
||||||
|
|
||||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
\section{Character predicates}
|
\section{Character sets}
|
||||||
|
\label{sec:char-sets}
|
||||||
|
|
||||||
\defun {char-letter?}\character\boolean
|
Scsh provides a \ex{char-set} type for expressing sets of characters.
|
||||||
\defunx{char-lower-case?}\character\boolean
|
These sets are used by some of the delimited-input procedures
|
||||||
\defunx{char-upper-case?}\character\boolean
|
(section~\ref{sec:field-reader}).
|
||||||
\defunx{char-title-case?}\character\boolean
|
Scsh's character set package was adapted and extended from
|
||||||
\defunx{char-digit?}\character\boolean
|
Project Mac's MIT Scheme package.
|
||||||
\defunx{char-letter+digit?}\character\boolean
|
Note that the character type used in the current implementation corresponds
|
||||||
\defunx{char-graphic?}\character\boolean
|
to the ASCII character set---but you would be wise not to build this
|
||||||
\defunx{char-printing?}\character\boolean
|
assumption into your code if you can help it.\footnote{
|
||||||
\defunx{char-whitespace?}\character\boolean
|
Actually, it's slightly uglier than that, albeit somewhat more
|
||||||
\defunx{char-blank?}\character\boolean
|
useful. The current character type corresponds to an eight-bit
|
||||||
\defunx{char-iso-control?}\character\boolean
|
superset of ASCII. The \ex{ascii->char} and \ex{char->ascii}
|
||||||
\defunx{char-punctuation?}\character\boolean
|
functions will preserve this eighth bit. However, none of the
|
||||||
\defunx{char-hex-digit?}\character\boolean
|
the high 128 characters appear in any of the standard character
|
||||||
\defunx{char-ascii?}\character\boolean
|
sets defined in section~\ref{sec:std-csets}, except for
|
||||||
|
\ex{char-set:full}. If someone would email the authors a listing
|
||||||
|
of the full Latin-1 definition, we'll be happy to upgrade these
|
||||||
|
sets' definitions to make them Latin-1 compliant.}
|
||||||
|
|
||||||
|
\defun{char-set?}{x}\boolean
|
||||||
\begin{desc}
|
\begin{desc}
|
||||||
Each of these predicates tests for membership in one of the standard
|
Is the object \var{x} a character set?
|
||||||
character sets provided by the SRFI-14 character-set library.
|
\end{desc}
|
||||||
Additionally, the following redundant bindings are provided for {R5RS}
|
|
||||||
compatibility:
|
\defun{char-set=}{\vari{cs}1 \vari{cs}2\ldots}\boolean
|
||||||
\begin{inset}
|
\begin{desc}
|
||||||
\begin{tabular}{ll}
|
Are the character sets equal?
|
||||||
{R5RS} name & scsh definition \\ \hline
|
\end{desc}
|
||||||
\ex{char-alphabetic?} & \ex{char-letter+digit?} \\
|
|
||||||
\ex{char-numeric?} & \ex{char-digit?} \\
|
\defun{char-set<=}{\vari{cs}1 \vari{cs}2\ldots}\boolean
|
||||||
\ex{char-alphanumeric?} & \ex{char-letter+digit?}
|
\begin{desc}
|
||||||
\end{tabular}
|
Returns true if every character set \vari{cs}{i} is
|
||||||
\end{inset}
|
a subset of character set \vari{cs}{i+1}.
|
||||||
|
\end{desc}
|
||||||
|
|
||||||
|
\defun{char-set-fold}{kons knil cs}\object
|
||||||
|
\begin{desc}
|
||||||
|
This is the fundamental iterator for character sets.
|
||||||
|
Applies the function \var{kons} across the character set \var{cs} using
|
||||||
|
initial state value \var{knil}.
|
||||||
|
That is, if \var{cs} is the empty set, the procedure returns \var{knil}.
|
||||||
|
Otherwise, some element \var{c} of \var{cs} is chosen; let \var{cs'} be
|
||||||
|
the remaining, unchosen characters.
|
||||||
|
The procedure returns
|
||||||
|
\begin{tightcode}
|
||||||
|
(char-set-fold \var{kons} (\var{kons} \var{c} \var{knil}) \var{cs'})\end{tightcode}
|
||||||
|
For example, we could define \ex{char-set-members} (see below)
|
||||||
|
as
|
||||||
|
\begin{tightcode}
|
||||||
|
(lambda (cs) (char-set-fold cons '() cs))\end{tightcode}
|
||||||
|
|
||||||
|
\remark{This procedure was formerly named \texttt{\indx{reduce-char-set}}.
|
||||||
|
The old binding is still provided, but is deprecated and will
|
||||||
|
probably vanish in a future release.}
|
||||||
|
\end{desc}
|
||||||
|
|
||||||
|
\defun{char-set-for-each}{p cs}{\undefined}
|
||||||
|
\begin{desc}
|
||||||
|
Apply procedure \var{p} to each character in the character set \var{cs}.
|
||||||
|
Note that the order in which \var{p} is applied to the characters in the
|
||||||
|
set is not specified, and may even change from application to application.
|
||||||
|
\end{desc}
|
||||||
|
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
\subsection{Creating character sets}
|
||||||
|
|
||||||
|
\defun{char-set}{\vari{char}1\ldots}{char-set}
|
||||||
|
\begin{desc}
|
||||||
|
Return a character set containing the given characters.
|
||||||
|
\end{desc}
|
||||||
|
|
||||||
|
\defun{chars->char-set}{chars}{char-set}
|
||||||
|
\begin{desc}
|
||||||
|
Return a character set containing the characters in the list \var{chars}.
|
||||||
|
\end{desc}
|
||||||
|
|
||||||
|
\defun{string->char-set}{s}{char-set}
|
||||||
|
\begin{desc}
|
||||||
|
Return a character set containing the characters in the string \var{s}.
|
||||||
|
\end{desc}
|
||||||
|
|
||||||
|
\defun{predicate->char-set}{pred}{char-set}
|
||||||
|
\begin{desc}
|
||||||
|
Returns a character set containing every character \var{c} such that
|
||||||
|
\ex{(\var{pred} \var{c})} returns true.
|
||||||
|
\end{desc}
|
||||||
|
|
||||||
|
\defun{ascii-range->char-set}{lower upper}{char-set}
|
||||||
|
\begin{desc}
|
||||||
|
Returns a character set containing every character whose {\Ascii}
|
||||||
|
code lies in the half-open range $[\var{lower},\var{upper})$.
|
||||||
|
\end{desc}
|
||||||
|
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
\subsection{Querying character sets}
|
||||||
|
\defun {char-set-members}{char-set}{character-list}
|
||||||
|
\begin{desc}
|
||||||
|
This procedure returns a list of the members of \var{char-set}.
|
||||||
|
\end{desc}
|
||||||
|
|
||||||
|
\defunx{char-set-contains?}{char-set char}\boolean
|
||||||
|
\begin{desc}
|
||||||
|
This procedure tests \var{char} for membership in set \var{char-set}.
|
||||||
|
\remark{Previous releases of scsh called this procedure \ex{char-set-member?},
|
||||||
|
reversing the order of the arguments.
|
||||||
|
This made sense, but was unfortunately the reverse order in which the
|
||||||
|
arguments appear in MIT Scheme.
|
||||||
|
A reasonable argument order was not backwards-compatible with MIT Scheme;
|
||||||
|
on the other hand, the MIT Scheme argument order was counter-intuitive
|
||||||
|
and at odds with common mathematical notation and the \ex{member} family
|
||||||
|
of R4RS procedures.
|
||||||
|
|
||||||
|
We sought to escape the dilemma by shifting to a new name.}
|
||||||
|
\end{desc}
|
||||||
|
|
||||||
|
\defun{char-set-size}{cs}\integer
|
||||||
|
\begin{desc}
|
||||||
|
Returns the number of elements in character set \var{cs}.
|
||||||
|
\end{desc}
|
||||||
|
|
||||||
|
\defun{char-set-every?}{pred cs}\boolean
|
||||||
|
\defunx{char-set-any?}{pred cs}\object
|
||||||
|
\begin{desc}
|
||||||
|
The \ex{char-set-every?} procedure returns true if predicate \var{pred}
|
||||||
|
returns true of every character in the character set \var{cs}.
|
||||||
|
|
||||||
|
Likewise, \ex{char-set-any?} applies \var{pred} to every character in
|
||||||
|
character set \var{cs}, and returns the first true value it finds.
|
||||||
|
If no character produces a true value, it returns false.
|
||||||
|
|
||||||
|
The order in which these procedures sequence through the elements of
|
||||||
|
\var{cs} is not specified.
|
||||||
\end{desc}
|
\end{desc}
|
||||||
|
|
||||||
|
|
||||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
\section{Deprecated character-set procedures}
|
\subsection{Character-set algebra}
|
||||||
\label{sec:char-sets}
|
\defun {char-set-invert}{char-set}{char-set}
|
||||||
|
\defunx{char-set-union}{\vari{char-set}1\ldots}{char-set}
|
||||||
|
\defunx{char-set-intersection}{\vari{char-set}1 \vari{char-set}2\ldots}{char-set}
|
||||||
|
\defunx{char-set-difference}{\vari{char-set}1 \vari{char-set}2\ldots}{char-set}
|
||||||
|
\begin{desc}
|
||||||
|
These procedures implement set complement, union, intersection, and difference
|
||||||
|
for character sets.
|
||||||
|
The union, intersection, and difference operations are n-ary, associating
|
||||||
|
to the left; the difference function requires at least one argument, while
|
||||||
|
union and intersection may be applied to zero arguments.
|
||||||
|
\end{desc}
|
||||||
|
|
||||||
The SRFI-13 character-set library grew out of an earlier library developed
|
\defun {char-set-adjoin}{cs \vari{char}1\ldots}{char-set}
|
||||||
for scsh.
|
\defunx{char-set-delete}{cs \vari{char}1\ldots}{char-set}
|
||||||
However, the SRFI standardisation process introduced incompatibilities with
|
\begin{desc}
|
||||||
the original scsh bindings.
|
Add/delete the \vari{char}i characters to/from character set \var{cs}.
|
||||||
The current version of scsh provides the library
|
\end{desc}
|
||||||
\ex{obsolete-char-set-lib}, which contains the old bindings found in
|
|
||||||
previous releases of scsh.
|
|
||||||
The following table lists the members of this library, along with
|
|
||||||
the equivalent SRFI-13 binding. This obsolete library is deprecated and
|
|
||||||
\emph{not} open by default in the standard \ex{scsh} environment;
|
|
||||||
new code should use the SRFI-13 bindings.
|
|
||||||
\begin{inset}
|
|
||||||
\begin{tabular}{ll}
|
|
||||||
Old \ex{obsolete-char-set-lib} & SRFI-13 \ex{char-set-lib} \\ \hline
|
|
||||||
|
|
||||||
\ex{char-set-members} & \ex{char-set->list} \\
|
|
||||||
\ex{chars->char-set} & \ex{list->char-set} \\
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
\ex{ascii-range->char-set} & \ex{ucs-range->char-set} (not exact) \\
|
\subsection{Standard character sets}
|
||||||
\ex{predicate->char-set} & \ex{char-set-filter} (not exact) \\
|
\label{sec:std-csets}
|
||||||
\ex{char-set-every}? & \ex{char-set-every} \\
|
Several character sets are predefined for convenience:
|
||||||
\ex{char-set-any}? & \ex{char-set-any} \\
|
|
||||||
\\
|
\begin{center}
|
||||||
\ex{char-set-invert} & \ex{char-set-complement} \\
|
\newcommand{\entry}[1]{\ex{#1}\index{#1}}
|
||||||
\ex{char-set-invert}! & \ex{char-set-complement!} \\
|
\begin{tabular}{|ll|}
|
||||||
\\
|
\hline
|
||||||
\ex{char-set:alphabetic} & \ex{char-set:letter} \\
|
\entry{char-set:lower-case} & Lower-case alphabetic chars \\
|
||||||
\ex{char-set:numeric} & \ex{char-set:digit} \\
|
\entry{char-set:upper-case} & Upper-case alphabetic chars \\
|
||||||
\ex{char-set:alphanumeric} & \ex{char-set:letter+digit} \\
|
\entry{char-set:alphabetic} & Alphabetic chars \\
|
||||||
\ex{char-set:control} & \ex{char-set:iso-control}
|
\entry{char-set:numeric} & Decimal digits: 0--9 \\
|
||||||
|
\entry{char-set:alphanumeric} & Alphabetic or numeric \\
|
||||||
|
\entry{char-set:graphic} & Printing characters except space \\
|
||||||
|
\entry{char-set:printing} & Printing characters including space \\
|
||||||
|
\entry{char-set:whitespace} & Whitespace characters \\
|
||||||
|
\entry{char-set:control} & Control characters \\
|
||||||
|
\entry{char-set:punctuation} & Punctuation characters \\
|
||||||
|
\entry{char-set:hex-digit} & A hexadecimal digit: 0--9, A--F, a--f \\
|
||||||
|
\entry{char-set:blank} & Blank characters \\
|
||||||
|
\entry{char-set:ascii} & A character in the ASCII set. \\
|
||||||
|
\entry{char-set:empty} & Empty set \\
|
||||||
|
\entry{char-set:full} & All characters \\
|
||||||
|
\hline
|
||||||
\end{tabular}
|
\end{tabular}
|
||||||
\end{inset}
|
\end{center}
|
||||||
Note also that the \ex{->char-set} procedure no longer handles a predicate
|
The first eleven of these correspond to the character classes defined in
|
||||||
argument.
|
Posix.
|
||||||
|
Note that there may be characters in \ex{char-set:alphabetic} that are
|
||||||
|
neither upper or lower case---this might occur in implementations that
|
||||||
|
use a character type richer than ASCII, such as Unicode.
|
||||||
|
A ``graphic character'' is one that would put ink on your page.
|
||||||
|
While the exact composition of these sets may vary depending upon the
|
||||||
|
character type provided by the Scheme system upon which scsh is running,
|
||||||
|
here are the definitions for some of the sets in an ASCII character set:
|
||||||
|
\begin{center}
|
||||||
|
\newcommand{\entry}[1]{\ex{#1}\index{#1}}
|
||||||
|
\begin{tabular}{|ll|}
|
||||||
|
\hline
|
||||||
|
char-set:alphabetic & A--Z and a--z \\
|
||||||
|
char-set:lower-case & a--z \\
|
||||||
|
char-set:upper-case & A--Z \\
|
||||||
|
char-set:graphic & Alphanumeric + punctuation \\
|
||||||
|
char-set:whitespace & Space, newline, tab, page,
|
||||||
|
vertical tab, carriage return \\
|
||||||
|
char-set:blank & Space and tab \\
|
||||||
|
char-set:control & ASCII 0--31 and 127 \\
|
||||||
|
char-set:punctuation & \verb|!"#$%&'()*+,-./:;<=>|\verb#?@[\]^_`{|}~# \\
|
||||||
|
\hline
|
||||||
|
\end{tabular}
|
||||||
|
\end{center}
|
||||||
|
|
||||||
|
|
||||||
|
\defun {char-alphabetic?}\character\boolean
|
||||||
|
\defunx{char-lower-case?}\character\boolean
|
||||||
|
\defunx{char-upper-case?}\character\boolean
|
||||||
|
\defunx{char-numeric? }\character\boolean
|
||||||
|
\defunx{char-alphanumeric?}\character\boolean
|
||||||
|
\defunx{char-graphic?}\character\boolean
|
||||||
|
\defunx{char-printing?}\character\boolean
|
||||||
|
\defunx{char-whitespace?}\character\boolean
|
||||||
|
\defunx{char-blank?}\character\boolean
|
||||||
|
\defunx{char-control?}\character\boolean
|
||||||
|
\defunx{char-punctuation?}\character\boolean
|
||||||
|
\defunx{char-hex-digit?}\character\boolean
|
||||||
|
\defunx{char-ascii?}\character\boolean
|
||||||
|
\begin{desc}
|
||||||
|
These predicates are defined in terms of the above character sets.
|
||||||
|
\end{desc}
|
||||||
|
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
\subsection{Linear-update character-set operations}
|
||||||
|
These procedures have a hybrid pure-functional/side-effecting semantics:
|
||||||
|
they are allowed, but not required, to side-effect one of their parameters
|
||||||
|
in order to construct their result.
|
||||||
|
An implementation may legally implement these procedures as pure,
|
||||||
|
side-effect-free functions, or it may implement them using side effects,
|
||||||
|
depending upon the details of what is the most efficient or simple to
|
||||||
|
implement in terms of the underlying representation.
|
||||||
|
|
||||||
|
What this means is that clients of these procedures \emph{may not} rely
|
||||||
|
upon these procedures working by side effect.
|
||||||
|
For example, this is not guaranteed to work:
|
||||||
|
\begin{verbatim}
|
||||||
|
(let ((cs (char-set #\a #\b #\c)))
|
||||||
|
(char-set-adjoin! cs #\d)
|
||||||
|
cs) ; Could be either {a,b,c} or {a,b,c,d}.
|
||||||
|
\end{verbatim}
|
||||||
|
However, this is well-defined:
|
||||||
|
\begin{verbatim}
|
||||||
|
(let ((cs (char-set #\a #\b #\c)))
|
||||||
|
(char-set-adjoin! cs #\d)) ; {a,b,c,d}
|
||||||
|
\end{verbatim}
|
||||||
|
So clients of these procedures write in a functional style, but must
|
||||||
|
additionally be sure that, when the procedure is called, there are no
|
||||||
|
other live pointers to the potentially-modified character set (hence the term
|
||||||
|
``linear update'').
|
||||||
|
|
||||||
|
There are two benefits to this convention:
|
||||||
|
\begin{itemize}
|
||||||
|
\item Implementations are free to provide the most efficient possible
|
||||||
|
implementation, either functional or side-effecting.
|
||||||
|
\item Programmers may nonetheless continue to assume that character sets
|
||||||
|
are purely functional data structures: they may be reliably shared
|
||||||
|
without needing to be copied, uniquified, and so forth.
|
||||||
|
\end{itemize}
|
||||||
|
|
||||||
|
In practice, these procedures are most useful for efficiently constructing
|
||||||
|
character sets in a side-effecting manner, in some limited local context,
|
||||||
|
before passing the character set outside the local construction scope to be
|
||||||
|
used in a functional manner.
|
||||||
|
|
||||||
|
Scsh provides no assistance in checking the linearity of the potentially
|
||||||
|
side-effected parameters passed to these functions --- there's no linear
|
||||||
|
type checker or run-time mechanism for detecting violations.
|
||||||
|
|
||||||
|
\defun{char-set-copy}{cs}{char-set}
|
||||||
|
\begin{desc}
|
||||||
|
Returns a copy of the character set \var{cs}.
|
||||||
|
``Copy'' means that if either the input parameter or the
|
||||||
|
result value of this procedure is passed to one of the linear-update
|
||||||
|
procedures described below, the other character set is guaranteed
|
||||||
|
not to be altered.
|
||||||
|
(A system that provides pure-functional implementations of the rest of
|
||||||
|
the linear-operator suite could implement this procedure as the
|
||||||
|
identity function.)
|
||||||
|
\end{desc}
|
||||||
|
|
||||||
|
\defun{char-set-adjoin!}{cs \vari{char}1\ldots}{char-set}
|
||||||
|
\begin{desc}
|
||||||
|
Add the \vari{char}i characters to character set \var{cs}, and
|
||||||
|
return the result.
|
||||||
|
This procedure is allowed, but not required, to side-effect \var{cs}.
|
||||||
|
\end{desc}
|
||||||
|
|
||||||
|
\defun{char-set-delete!}{cs \vari{char}1\ldots}{char-set}
|
||||||
|
\begin{desc}
|
||||||
|
Remove the \vari{char}i characters to character set \var{cs}, and
|
||||||
|
return the result.
|
||||||
|
This procedure is allowed, but not required, to side-effect \var{cs}.
|
||||||
|
\end{desc}
|
||||||
|
|
||||||
|
\defun {char-set-invert!}{char-set}{char-set}
|
||||||
|
\defunx{char-set-union!}{\vari{char-set}1 \vari{char-set}2\ldots}{char-set}
|
||||||
|
\defunx{char-set-intersection!}{\vari{char-set}1 \vari{char-set}2\ldots}{char-set}
|
||||||
|
\defunx{char-set-difference!}{\vari{char-set}1 \vari{char-set}2\ldots}{char-set}
|
||||||
|
\begin{desc}
|
||||||
|
These procedures implement set complement, union, intersection, and difference
|
||||||
|
for character sets.
|
||||||
|
They are allowed, but not required, to side-effect their first parameter.
|
||||||
|
The union, intersection, and difference operations are n-ary, associating
|
||||||
|
to the left.
|
||||||
|
\end{desc}
|
||||||
|
|
|
@ -49,7 +49,7 @@ Programs can use \ex{with-errno-handler*} to establish
|
||||||
handlers for these exceptions.
|
handlers for these exceptions.
|
||||||
|
|
||||||
If a {\Unix} error arises while \var{thunk} is executing,
|
If a {\Unix} error arises while \var{thunk} is executing,
|
||||||
\var{handler} is called on two arguments like this:
|
\var{handler} is called on two arguments:
|
||||||
\codex{(\var{handler} \var{errno} \var{packet})}
|
\codex{(\var{handler} \var{errno} \var{packet})}
|
||||||
\var{packet} is a list of the form
|
\var{packet} is a list of the form
|
||||||
$$\var{packet} = \ex{(\var{errno-msg} \var{syscall} . \var{data})},$$
|
$$\var{packet} = \ex{(\var{errno-msg} \var{syscall} . \var{data})},$$
|
||||||
|
@ -375,7 +375,7 @@ descriptor to a port with \ex{fdes->outport} or \ex{fdes->inport}, the port
|
||||||
has its revealed field incremented.
|
has its revealed field incremented.
|
||||||
|
|
||||||
Not all file descriptors are created by requests to make ports. Some are
|
Not all file descriptors are created by requests to make ports. Some are
|
||||||
inherited on process invocation via \ex{\urlh{http://www.FreeBSD.org/cgi/man.cgi?query=exec&apropos=0&sektion=0&manpath=FreeBSD+4.3-RELEASE&format=html}{exec(2)}}, and are simply part of the
|
inherited on process invocation via \ex{exec(2)}, and are simply part of the
|
||||||
global environment. Subprocesses may depend upon them, so if a port is later
|
global environment. Subprocesses may depend upon them, so if a port is later
|
||||||
allocated for these file descriptors, is should be considered as a revealed
|
allocated for these file descriptors, is should be considered as a revealed
|
||||||
port. For example, when the {\Scheme} shell's process starts up, it opens ports
|
port. For example, when the {\Scheme} shell's process starts up, it opens ports
|
||||||
|
@ -388,7 +388,7 @@ port.
|
||||||
|
|
||||||
Unrevealed file ports have the nice property that they can be closed when all
|
Unrevealed file ports have the nice property that they can be closed when all
|
||||||
pointers to the port are dropped. This can happen during gc, or at an
|
pointers to the port are dropped. This can happen during gc, or at an
|
||||||
\ex{\urlh{http://www.FreeBSD.org/cgi/man.cgi?query=exec&apropos=0&sektion=0&manpath=FreeBSD+4.3-RELEASE&format=html}{exec()}}---since all memory is dropped at an \ex{\urlh{http://www.FreeBSD.org/cgi/man.cgi?query=exec&apropos=0&sektion=0&manpath=FreeBSD+4.3-RELEASE&format=html}{exec()}}. No one knows the
|
\ex{exec()}---since all memory is dropped at an \ex{exec()}. No one knows the
|
||||||
file descriptor associated with the port, so the exec'd process certainly
|
file descriptor associated with the port, so the exec'd process certainly
|
||||||
can't refer to it.
|
can't refer to it.
|
||||||
|
|
||||||
|
@ -399,11 +399,11 @@ the garbage collector. This is critical, since shell programming
|
||||||
absolutely requires access to the {\Unix} file descriptors, as their
|
absolutely requires access to the {\Unix} file descriptors, as their
|
||||||
numerical values are a critical part of the process interface.
|
numerical values are a critical part of the process interface.
|
||||||
|
|
||||||
A port's underlying file descriptor can be shifted around with \ex{\urlh{http://www.FreeBSD.org/cgi/man.cgi?query=dup&apropos=0&sektion=0&manpath=FreeBSD+4.3-RELEASE&format=html}{dup(2)}}
|
A port's underlying file descriptor can be shifted around with \ex{dup(2)}
|
||||||
when convenient. That is, the actual file descriptor on top of which a port is
|
when convenient. That is, the actual file descriptor on top of which a port is
|
||||||
constructed can be shifted around underneath the port by the scsh kernel when
|
constructed can be shifted around underneath the port by the scsh kernel when
|
||||||
necessary. This is important, because when the user is setting up file
|
necessary. This is important, because when the user is setting up file
|
||||||
descriptors prior to a \ex{\urlh{http://www.FreeBSD.org/cgi/man.cgi?query=exec&apropos=0&sektion=0&manpath=FreeBSD+4.3-RELEASE&format=html}{exec(2)}}, he may explicitly use a file descriptor
|
descriptors prior to a \ex{exec(2)}, he may explicitly use a file descriptor
|
||||||
that has already been allocated to some port. In this case, the scsh kernel
|
that has already been allocated to some port. In this case, the scsh kernel
|
||||||
just shifts the port's file descriptor to some new location with \ex{dup},
|
just shifts the port's file descriptor to some new location with \ex{dup},
|
||||||
freeing up its old descriptor. This prevents errors from happening in the
|
freeing up its old descriptor. This prevents errors from happening in the
|
||||||
|
@ -431,8 +431,8 @@ alive and well so that it can subsequently be dup'd into descriptor 0 for
|
||||||
\ex{prog}'s stdin.
|
\ex{prog}'s stdin.
|
||||||
|
|
||||||
The port-shifting machinery makes the following guarantee: a port is only
|
The port-shifting machinery makes the following guarantee: a port is only
|
||||||
moved when the underlying file descriptor is closed, either by a \ex{\urlh{http://www.FreeBSD.org/cgi/man.cgi?query=close&apropos=0&sektion=0&manpath=FreeBSD+4.3-RELEASE&format=html}{close()}}
|
moved when the underlying file descriptor is closed, either by a \ex{close()}
|
||||||
or a \ex{\urlh{http://www.FreeBSD.org/cgi/man.cgi?query=dup2&apropos=0&sektion=0&manpath=FreeBSD+4.3-RELEASE&format=html}{dup2()}} operation. Otherwise a port/file-descriptor association is
|
or a \ex{dup2()} operation. Otherwise a port/file-descriptor association is
|
||||||
stable.
|
stable.
|
||||||
|
|
||||||
Under normal circumstances, all this machinery just works behind the scenes to
|
Under normal circumstances, all this machinery just works behind the scenes to
|
||||||
|
@ -524,17 +524,17 @@ Decrement the port's revealed count.
|
||||||
\defunx{dup->outport} {fd/port [newfd]} {port}
|
\defunx{dup->outport} {fd/port [newfd]} {port}
|
||||||
\defunx{dup->fdes} {fd/port [newfd]} {fd}
|
\defunx{dup->fdes} {fd/port [newfd]} {fd}
|
||||||
\begin{desc}
|
\begin{desc}
|
||||||
These procedures provide the functionality of C's \ex{\urlh{http://www.FreeBSD.org/cgi/man.cgi?query=dup&apropos=0&sektion=0&manpath=FreeBSD+4.3-RELEASE&format=html}{dup()}} and \ex{\urlh{http://www.FreeBSD.org/cgi/man.cgi?query=dup2&apropos=0&sektion=0&manpath=FreeBSD+4.3-RELEASE&format=html}{dup2()}}.
|
These procedures provide the functionality of C's \ex{dup()} and \ex{dup2()}.
|
||||||
The different routines return different types of values:
|
The different routines return different types of values:
|
||||||
\ex{dup->inport}, \ex{dup->outport}, and \ex{dup->fdes} return
|
\ex{dup->inport}, \ex{dup->outport}, and \ex{dup->fdes} return
|
||||||
input ports, output ports, and integer file descriptors, respectively.
|
input ports, output ports, and integer file descriptors, respectively.
|
||||||
\ex{dup}'s return value depends on on the type of
|
\ex{dup}'s return value depends on on the type of
|
||||||
\var{fd/port}---it maps fd$\rightarrow$fd and port$\rightarrow$port.
|
\var{fd/port}---it maps fd$\rightarrow$fd and port$\rightarrow$port.
|
||||||
|
|
||||||
These procedures use the {\Unix} \ex{\urlh{http://www.FreeBSD.org/cgi/man.cgi?query=dup&apropos=0&sektion=0&manpath=FreeBSD+4.3-RELEASE&format=html}{dup()}} syscall to replicate
|
These procedures use the {\Unix} \ex{dup()} syscall to replicate
|
||||||
the file descriptor or file port \var{fd/port}.
|
the file descriptor or file port \var{fd/port}.
|
||||||
If a \var{newfd} file descriptor is given, it is used as the target of
|
If a \var{newfd} file descriptor is given, it is used as the target of
|
||||||
the dup operation, \ie, the operation is a \ex{\urlh{http://www.FreeBSD.org/cgi/man.cgi?query=dup2&apropos=0&sektion=0&manpath=FreeBSD+4.3-RELEASE&format=html}{dup2()}}.
|
the dup operation, \ie, the operation is a \ex{dup2()}.
|
||||||
In this case, procedures that return a port (such as \ex{dup->inport})
|
In this case, procedures that return a port (such as \ex{dup->inport})
|
||||||
will return one with the revealed count set to one.
|
will return one with the revealed count set to one.
|
||||||
For example, \ex{(dup (current-input-port) 5)} produces
|
For example, \ex{(dup (current-input-port) 5)} produces
|
||||||
|
@ -953,16 +953,21 @@ It is not without reason that the FreeBSD man pages refer to {\Posix}
|
||||||
file locking as ``completely stupid.''
|
file locking as ``completely stupid.''
|
||||||
|
|
||||||
Scsh moves Scheme ports from file descriptor to file descriptor with
|
Scsh moves Scheme ports from file descriptor to file descriptor with
|
||||||
\ex{\urlh{http://www.FreeBSD.org/cgi/man.cgi?query=dup&apropos=0&sektion=0&manpath=FreeBSD+4.3-RELEASE&format=html}{dup()}} and \ex{\urlh{http://www.FreeBSD.org/cgi/man.cgi?query=close&apropos=0&sektion=0&manpath=FreeBSD+4.3-RELEASE&format=html}{close()}} as required by the runtime,
|
\ex{dup()} and \ex{close()} as required by the runtime,
|
||||||
so it is impossible to keep file locks open across one of these shifts.
|
so it is impossible to keep file locks open across one of these shifts.
|
||||||
Hence we can only offer {\Posix} advisory file locking directly on raw
|
Hence we can only offer {\Posix} advisory file locking directly on raw
|
||||||
integer file descriptors;
|
integer file descriptors;
|
||||||
regrettably, there are no facilities for locking Scheme ports.
|
regrettably, there are no facilities for locking Scheme ports.
|
||||||
|
|
||||||
Note that once a Scheme port is revealed in scsh, the runtime will not
|
Note that once a Scheme port is revealed in scsh, the runtime will not
|
||||||
shift the port around with \ex{\urlh{http://www.FreeBSD.org/cgi/man.cgi?query=dup&apropos=0&sektion=0&manpath=FreeBSD+4.3-RELEASE&format=html}{dup()}} and \ex{\urlh{http://www.FreeBSD.org/cgi/man.cgi?query=close&apropos=0&sektion=0&manpath=FreeBSD+4.3-RELEASE&format=html}{close()}}.
|
shift the port around with \ex{dup()} and \ex{close()}.
|
||||||
This means the file-locking procedures can then be applied to the port's
|
This means the file-locking procedures can then be applied to the port's
|
||||||
associated file descriptor.
|
associated file descriptor.
|
||||||
|
|
||||||
|
NeXTSTEP users should also note that even minimalist {\Posix} file locking
|
||||||
|
is not supported for NFS-mounted files in NeXTSTEP; NeXT claims they will
|
||||||
|
fix this in NS release 4.
|
||||||
|
We'd appreciate hearing from users when and if this happens.
|
||||||
}
|
}
|
||||||
|
|
||||||
{\Posix} allows the user to lock a region of a file with either
|
{\Posix} allows the user to lock a region of a file with either
|
||||||
|
@ -1117,7 +1122,7 @@ while \ex{delete-filesys-object} simply returns.
|
||||||
If you override an existing object, then \var{old-fname}
|
If you override an existing object, then \var{old-fname}
|
||||||
and \var{new-fname} must type-match---either both directories,
|
and \var{new-fname} must type-match---either both directories,
|
||||||
or both non-directories.
|
or both non-directories.
|
||||||
This is required by the semantics of {\Unix} \ex{\urlh{http://www.FreeBSD.org/cgi/man.cgi?query=rename&apropos=0&sektion=0&manpath=FreeBSD+4.3-RELEASE&format=html}{rename()}}.
|
This is required by the semantics of {\Unix} \ex{rename()}.
|
||||||
|
|
||||||
\remark{
|
\remark{
|
||||||
There is an unfortunate atomicity problem with the \ex{rename-file}
|
There is an unfortunate atomicity problem with the \ex{rename-file}
|
||||||
|
@ -1125,7 +1130,7 @@ while \ex{delete-filesys-object} simply returns.
|
||||||
specify no-override, but create file \ex{new-fname} sometime between
|
specify no-override, but create file \ex{new-fname} sometime between
|
||||||
\ex{rename-file}'s existence check and the actual rename operation,
|
\ex{rename-file}'s existence check and the actual rename operation,
|
||||||
your file will be clobbered with \ex{old-fname}. There is no way to fix
|
your file will be clobbered with \ex{old-fname}. There is no way to fix
|
||||||
this problem, given the semantics of {\Unix} \ex{\urlh{http://www.FreeBSD.org/cgi/man.cgi?query=rename&apropos=0&sektion=0&manpath=FreeBSD+4.3-RELEASE&format=html}{rename()}};
|
this problem, given the semantics of {\Unix} \ex{rename()};
|
||||||
at least it is highly unlikely to occur in practice.
|
at least it is highly unlikely to occur in practice.
|
||||||
}
|
}
|
||||||
\end{defundescx}
|
\end{defundescx}
|
||||||
|
@ -1165,7 +1170,7 @@ while \ex{delete-filesys-object} simply returns.
|
||||||
These procedures are not {\Posix}.
|
These procedures are not {\Posix}.
|
||||||
Interestingly enough, \ex{sync\=file\=system} doesn't actually
|
Interestingly enough, \ex{sync\=file\=system} doesn't actually
|
||||||
do what it is claimed to do. We just threw it in for humor value.
|
do what it is claimed to do. We just threw it in for humor value.
|
||||||
See the \ex{\urlh{http://www.FreeBSD.org/cgi/man.cgi?query=sync&apropos=0&sektion=0&manpath=FreeBSD+4.3-RELEASE&format=html}{sync(2)}} man page for {\Unix} enlightenment.
|
See the \ex{sync(2)} man page for {\Unix} enlightenment.
|
||||||
\end{desc}
|
\end{desc}
|
||||||
|
|
||||||
\begin{defundesc} {truncate-file} {fname/fd/port len} \undefined
|
\begin{defundesc} {truncate-file} {fname/fd/port len} \undefined
|
||||||
|
@ -1290,7 +1295,7 @@ For example,
|
||||||
calls do not take a \var{chase?} flag.
|
calls do not take a \var{chase?} flag.
|
||||||
|
|
||||||
Note that these procedures use the process' \emph{effective} user
|
Note that these procedures use the process' \emph{effective} user
|
||||||
and group ids for permission checking. {\Posix} defines an \ex{\urlh{http://www.FreeBSD.org/cgi/man.cgi?query=access&apropos=0&sektion=0&manpath=FreeBSD+4.3-RELEASE&format=html}{access()}}
|
and group ids for permission checking. {\Posix} defines an \ex{access()}
|
||||||
function that uses the process' real uid and gids. This is handy
|
function that uses the process' real uid and gids. This is handy
|
||||||
for setuid programs that would like to find out if the actual user
|
for setuid programs that would like to find out if the actual user
|
||||||
has specific rights; scsh ought to provide this functionality (but doesn't
|
has specific rights; scsh ought to provide this functionality (but doesn't
|
||||||
|
@ -1310,7 +1315,7 @@ For example,
|
||||||
These should be disentangled.
|
These should be disentangled.
|
||||||
|
|
||||||
Some of these problems could be avoided if {\Posix} had a real-uid
|
Some of these problems could be avoided if {\Posix} had a real-uid
|
||||||
variant of the \ex{\urlh{http://www.FreeBSD.org/cgi/man.cgi?query=access&apropos=0&sektion=0&manpath=FreeBSD+4.3-RELEASE&format=html}{access()}} call we could use, but the atomicity
|
variant of the \ex{access()} call we could use, but the atomicity
|
||||||
issue is still a problem. In the final analysis, the only way to
|
issue is still a problem. In the final analysis, the only way to
|
||||||
find out if you have the right to perform an operation on a file
|
find out if you have the right to perform an operation on a file
|
||||||
is to try and open it for the desired operation. These permission-checking
|
is to try and open it for the desired operation. These permission-checking
|
||||||
|
@ -1387,8 +1392,8 @@ Returns:
|
||||||
|
|
||||||
Note that the rules of backslash for {\Scheme} strings and glob patterns
|
Note that the rules of backslash for {\Scheme} strings and glob patterns
|
||||||
work together to require four backslashes in a row to specify a
|
work together to require four backslashes in a row to specify a
|
||||||
single literal backslash. Fortunately, it is very rare that a backslash
|
single literal backslash. Fortunately, this should be a rare
|
||||||
occurs in a Unix file name.
|
occurrence.
|
||||||
|
|
||||||
A glob subpattern will not match against dot files unless the first
|
A glob subpattern will not match against dot files unless the first
|
||||||
character of the subpattern is a literal ``\ex{.}''.
|
character of the subpattern is a literal ``\ex{.}''.
|
||||||
|
@ -1467,7 +1472,7 @@ All wild-card characters in \var{str} are quoted with a backslash.
|
||||||
|
|
||||||
\ex{file-match} provides a more powerful file-matching service, at the
|
\ex{file-match} provides a more powerful file-matching service, at the
|
||||||
expense of a less convenient notation. It is intermediate in
|
expense of a less convenient notation. It is intermediate in
|
||||||
power between most shell matching machinery and recursive \ex{\urlh{http://www.FreeBSD.org/cgi/man.cgi?query=find&apropos=0&sektion=0&manpath=FreeBSD+4.3-RELEASE&format=html}{find(1)}}.
|
power between most shell matching machinery and recursive \ex{find(1)}.
|
||||||
|
|
||||||
Each pattern is a regexp. The procedure searches from \var{root},
|
Each pattern is a regexp. The procedure searches from \var{root},
|
||||||
matching the first-level files against pattern \vari{pat}1, the
|
matching the first-level files against pattern \vari{pat}1, the
|
||||||
|
@ -1716,7 +1721,7 @@ a slash character---it is used directly. So a program with a name like
|
||||||
\ex{"bin/prog"} always executes the program \ex{bin/prog} in the current working
|
\ex{"bin/prog"} always executes the program \ex{bin/prog} in the current working
|
||||||
directory. See \verb|$path| and \verb|exec-path-list|, below.
|
directory. See \verb|$path| and \verb|exec-path-list|, below.
|
||||||
|
|
||||||
Note that there is no analog to the C function \ex{\urlh{http://www.FreeBSD.org/cgi/man.cgi?query=execv&apropos=0&sektion=0&manpath=FreeBSD+4.3-RELEASE&format=html}{execv()}}.
|
Note that there is no analog to the C function \ex{execv()}.
|
||||||
To get the effect just do
|
To get the effect just do
|
||||||
\codex{(apply exec prog arglist)}
|
\codex{(apply exec prog arglist)}
|
||||||
|
|
||||||
|
@ -1724,7 +1729,7 @@ All of these procedures flush buffered output and close unrevealed ports
|
||||||
before executing the new binary.
|
before executing the new binary.
|
||||||
To avoid flushing buffered output, see \verb|%exec| below.
|
To avoid flushing buffered output, see \verb|%exec| below.
|
||||||
|
|
||||||
Note that the C \ex{\urlh{http://www.FreeBSD.org/cgi/man.cgi?query=exec&apropos=0&sektion=0&manpath=FreeBSD+4.3-RELEASE&format=html}{exec()}} procedure allows the zeroth element of the
|
Note that the C \ex{exec()} procedure allows the zeroth element of the
|
||||||
argument vector to be different from the file being executed, \eg
|
argument vector to be different from the file being executed, \eg
|
||||||
%
|
%
|
||||||
\begin{inset}
|
\begin{inset}
|
||||||
|
@ -1802,7 +1807,7 @@ Suspend the current process with a SIGSTOP signal.
|
||||||
\defun {fork} {[thunk]} {proc or \sharpf}
|
\defun {fork} {[thunk]} {proc or \sharpf}
|
||||||
\defunx {\%fork} {[thunk]} {proc or \sharpf}
|
\defunx {\%fork} {[thunk]} {proc or \sharpf}
|
||||||
\begin{desc}
|
\begin{desc}
|
||||||
\ex{fork} with no arguments is like C \ex{\urlh{http://www.FreeBSD.org/cgi/man.cgi?query=fork&apropos=0&sektion=0&manpath=FreeBSD+4.3-RELEASE&format=html}{fork()}}.
|
\ex{fork} with no arguments is like C \ex{fork()}.
|
||||||
In the parent process, it returns the child's \emph{process object}
|
In the parent process, it returns the child's \emph{process object}
|
||||||
(see below for more information on process objects).
|
(see below for more information on process objects).
|
||||||
In the child process, it returns {\sharpf}.
|
In the child process, it returns {\sharpf}.
|
||||||
|
@ -2242,7 +2247,7 @@ I can't remember how \ex{set-priority} and \ex{priority} work, so no
|
||||||
\begin{desc}
|
\begin{desc}
|
||||||
These routines get and set the effective and real user and group ids.
|
These routines get and set the effective and real user and group ids.
|
||||||
The \ex{set-uid} and \ex{set-gid} routines correspond to the {\Posix}
|
The \ex{set-uid} and \ex{set-gid} routines correspond to the {\Posix}
|
||||||
\ex{\urlh{http://www.FreeBSD.org/cgi/man.cgi?query=setuid&apropos=0&sektion=0&manpath=FreeBSD+4.3-RELEASE&format=html}{setuid()}} and \ex{\urlh{http://www.FreeBSD.org/cgi/man.cgi?query=setgid&apropos=0&sektion=0&manpath=FreeBSD+4.3-RELEASE&format=html}{setgid()}} procedures.
|
\ex{setuid()} and \ex{setgid()} procedures.
|
||||||
\end{desc}
|
\end{desc}
|
||||||
|
|
||||||
|
|
||||||
|
@ -2618,6 +2623,9 @@ all of the complexity is optional,
|
||||||
and defaulting all the optional arguments reduces the system
|
and defaulting all the optional arguments reduces the system
|
||||||
to a simple interface.
|
to a simple interface.
|
||||||
|
|
||||||
|
\remark{This time package does not currently work with NeXTSTEP, as NeXTSTEP
|
||||||
|
does not provide a {\Posix}-compliant time library that will even link.}
|
||||||
|
|
||||||
\subsection{Terminology}
|
\subsection{Terminology}
|
||||||
``UTC'' and ``UCT'' stand for ``universal coordinated time,'' which is the
|
``UTC'' and ``UCT'' stand for ``universal coordinated time,'' which is the
|
||||||
official name for what is colloquially referred to as ``Greenwich Mean
|
official name for what is colloquially referred to as ``Greenwich Mean
|
||||||
|
@ -2787,7 +2795,7 @@ String & A {\Posix} time zone string understood by the OS
|
||||||
``\ex{UTC+\emph{hh}:\emph{mm}:\emph{ss}}'';
|
``\ex{UTC+\emph{hh}:\emph{mm}:\emph{ss}}'';
|
||||||
the trailing \ex{:\emph{mm}:\emph{ss}} portion is deleted if it is zeroes.
|
the trailing \ex{:\emph{mm}:\emph{ss}} portion is deleted if it is zeroes.
|
||||||
|
|
||||||
\oops{The Posix facility for converting dates to times, \ex{\urlh{http://www.FreeBSD.org/cgi/man.cgi?query=mktime&apropos=0&sektion=0&manpath=FreeBSD+4.3-RELEASE&format=html}{mktime()}},
|
\oops{The Posix facility for converting dates to times, \ex{mktime()},
|
||||||
has a broken design: it indicates an error by returning -1, which
|
has a broken design: it indicates an error by returning -1, which
|
||||||
is also a legal return value (for date 23:59:59 UCT, 12/31/1969).
|
is also a legal return value (for date 23:59:59 UCT, 12/31/1969).
|
||||||
Scsh resolves the ambiguity in a paranoid fashion: it always
|
Scsh resolves the ambiguity in a paranoid fashion: it always
|
||||||
|
@ -2984,8 +2992,7 @@ If \var{val} is {\sharpf}, then any entry for \var{var} is deleted.
|
||||||
an alist, \eg,
|
an alist, \eg,
|
||||||
\begin{code}
|
\begin{code}
|
||||||
(("TERM" . "vt100")
|
(("TERM" . "vt100")
|
||||||
("SHELL" . "/usr/local/bin/scsh")
|
("SHELL" . "/bin/csh")
|
||||||
("PATH" . "/sbin:/usr/sbin:/bin:/usr/bin")
|
|
||||||
("EDITOR" . "emacs")
|
("EDITOR" . "emacs")
|
||||||
\ldots)\end{code}
|
\ldots)\end{code}
|
||||||
\end{desc}
|
\end{desc}
|
||||||
|
@ -2998,21 +3005,6 @@ If \var{val} is {\sharpf}, then any entry for \var{var} is deleted.
|
||||||
environment (\ie, converted to a null-terminated C vector of
|
environment (\ie, converted to a null-terminated C vector of
|
||||||
\ex{"\var{var}=\var{val}"} strings which is assigned to the global
|
\ex{"\var{var}=\var{val}"} strings which is assigned to the global
|
||||||
\ex{char **environ}).
|
\ex{char **environ}).
|
||||||
|
|
||||||
\begin{code}
|
|
||||||
;;; Note $PATH entry is converted
|
|
||||||
;;; to /sbin:/usr/sbin:/bin:/usr/bin.
|
|
||||||
(alist->env '(("TERM" . "vt100")
|
|
||||||
("PATH" "/sbin" "/usr/sbin" "/bin")
|
|
||||||
("SHELL" . "/usr/local/bin/scsh")))
|
|
||||||
\end{code}
|
|
||||||
|
|
||||||
Note that \ex{env->alist} and \ex{alist->env} are not exact
|
|
||||||
inverses---\ex{alist->env} will convert a list value into a single
|
|
||||||
colon-separated string, but \ex{env->alist} will not parse colon-separated
|
|
||||||
values into lists. (See the \ex{\$PATH} element in the examples given for
|
|
||||||
each procedure.)
|
|
||||||
|
|
||||||
\end{desc}
|
\end{desc}
|
||||||
|
|
||||||
The following three functions help the programmer manipulate alist
|
The following three functions help the programmer manipulate alist
|
||||||
|
@ -3090,30 +3082,18 @@ Example: These four pieces of code all run the mailer with special
|
||||||
|
|
||||||
\subsection{Path lists and colon lists}
|
\subsection{Path lists and colon lists}
|
||||||
|
|
||||||
When environment variables such as \ex{\$PATH} need to encode a list of
|
Environment variables such as \ex{\$PATH} encode a list of strings
|
||||||
strings (such as a list of directories to be searched),
|
by separating the list elements with colon delimiters.
|
||||||
the common Unix convention is to separate the list elements with
|
Once parsed into actual lists, these ordered lists can be manipulated
|
||||||
colon delimiters.\footnote{\ldots and hope the individual list elements
|
with the following two functions.
|
||||||
don't contain colons themselves.}
|
|
||||||
To convert between the colon-separated string encoding and the
|
To convert between the colon-separated string encoding and the
|
||||||
list-of-strings representation, see the \ex{infix-splitter} function
|
list-of-strings representation, see the \ex{field-reader} and
|
||||||
(section~\ref{sec:field-splitter}) and the string library's
|
\ex{join-strings} functions in section~\ref{sec:field-reader}.
|
||||||
\ex{string-join} function.
|
\remark{An earlier release of scsh provided the \ex{split-colon-list}
|
||||||
For example,
|
and \ex{string-list->colon-list} functions. These have been
|
||||||
\begin{code}
|
removed from scsh, and are replaced by the more general
|
||||||
(define split (infix-splitter (rx ":")))
|
parsers and unparsers of the field-reader module.}
|
||||||
(split "/sbin:/bin::/usr/bin") {\evalsto}
|
|
||||||
'("/sbin" "/bin" "" "/usr/bin")
|
|
||||||
(string-join ":" '("/sbin" "/bin" "" "/usr/bin")) {\evalsto}
|
|
||||||
"/sbin:/bin::/usr/bin"\end{code}
|
|
||||||
The following two functions are useful for manipulating these ordered lists,
|
|
||||||
once they have been parsed from their colon-separated form.
|
|
||||||
|
|
||||||
%\remark{An earlier release of scsh provided the \ex{split-colon-list}
|
|
||||||
% and \ex{string-list->colon-list} functions. These have been
|
|
||||||
% removed from scsh, and are replaced by the more general
|
|
||||||
% parsers and unparsers of the field-reader module.}
|
|
||||||
%
|
|
||||||
%\defun {split-colon-list} {string} {{\str} list}
|
%\defun {split-colon-list} {string} {{\str} list}
|
||||||
%\defunx {string-list->colon-list} {string-list} \str
|
%\defunx {string-list->colon-list} {string-list} \str
|
||||||
%\begin{desc}
|
%\begin{desc}
|
||||||
|
@ -3166,18 +3146,15 @@ Scsh never uses \cd{$USER} at all.
|
||||||
It computes \ex{(user-login-name)} from the system call \ex{(user-uid)}.
|
It computes \ex{(user-login-name)} from the system call \ex{(user-uid)}.
|
||||||
|
|
||||||
\defvar {home-directory} \str
|
\defvar {home-directory} \str
|
||||||
\defvarx {exec-path-list} {{\str} list fluid}
|
\defvarx {exec-path-list} {{\str} list}
|
||||||
\begin{desc}
|
\begin{desc}
|
||||||
Scsh accesses \cd{$HOME} at start-up time, and stores the value in the
|
Scsh accesses \cd{$HOME} at start-up time, and stores the value in the
|
||||||
global variable \ex{home-directory}. It uses this value for \ex{\~}
|
global variable \ex{home-directory}. It uses this value for \ex{\~}
|
||||||
lookups and for returning to home on \ex{(chdir)}.
|
lookups and for returning to home on \ex{(chdir)}.
|
||||||
|
|
||||||
Scsh accesses \cd{$PATH} at start-up time, colon-splits the path list, and
|
Scsh accesses \cd{$PATH} at start-up time, colon-splits the path list, and
|
||||||
stores the value in the fluid \ex{exec-path-list}. This list is
|
stores the value in the global variable \ex{exec-path-list}. This list is
|
||||||
used for \ex{exec-path} and \ex{exec-path/env} searches.
|
used for \ex{exec-path} and \ex{exec-path/env} searches.
|
||||||
|
|
||||||
To access, rebind or side-effect fluid cells, you must open
|
|
||||||
the \ex{fluids} package.
|
|
||||||
\end{desc}
|
\end{desc}
|
||||||
|
|
||||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
|
@ -1,9 +0,0 @@
|
||||||
% tex2page.sty
|
|
||||||
% Dorai Sitaram
|
|
||||||
|
|
||||||
% Loading this file in a LaTeX document
|
|
||||||
% gives it all the macros of tex2page.tex,
|
|
||||||
% but via a more LaTeX-convenient filename.
|
|
||||||
|
|
||||||
\input{tex2page}
|
|
||||||
|
|
|
@ -7,10 +7,8 @@ made to scsh.
|
||||||
We invite interested hackers to do any of them, and send us the code;
|
We invite interested hackers to do any of them, and send us the code;
|
||||||
we'll put you on the team.
|
we'll put you on the team.
|
||||||
Visit the Scheme Underground Web page for more information on good hacks at
|
Visit the Scheme Underground Web page for more information on good hacks at
|
||||||
\begin{inset} \begin{flushleft}
|
\begin{tightinset}\verb|http://www.ai.mit.edu/projects/su/|
|
||||||
\ex{\urlh{http://www.ai.mit.edu/projects/su/}{http://www.ai.mit.edu/projects/su/}}
|
\end{tightinset}
|
||||||
\end{flushleft}
|
|
||||||
\end{inset}
|
|
||||||
Scsh is a tool that lets you write fun programs that do real things in
|
Scsh is a tool that lets you write fun programs that do real things in
|
||||||
an elegant language; go wild.
|
an elegant language; go wild.
|
||||||
|
|
||||||
|
@ -19,8 +17,19 @@ an elegant language; go wild.
|
||||||
\item An X gui interface. (Needs threads.)
|
\item An X gui interface. (Needs threads.)
|
||||||
\item A better C function/data-structure interface. This is not easy.
|
\item A better C function/data-structure interface. This is not easy.
|
||||||
\item More network protocols. Telnet and ftp would be the most important.
|
\item More network protocols. Telnet and ftp would be the most important.
|
||||||
|
\item An ILU interface.
|
||||||
|
\item An RPC system, with ``tail-recursion.''
|
||||||
|
\item Interfaces to relational db's.
|
||||||
|
This would be quite useful for Web servers.
|
||||||
|
An s-expression embedding of SQL would be a key design component
|
||||||
|
of such a system, along the lines of scsh's process notation or
|
||||||
|
\ex{awk} notation.
|
||||||
\item Port Edwin, and emacs text editor written in MIT Scheme, to scsh.
|
\item Port Edwin, and emacs text editor written in MIT Scheme, to scsh.
|
||||||
Combine it with scsh's OS interfaces to make a visual shell.
|
Combine it with scsh's OS interfaces to make a visual shell.
|
||||||
|
\item An \ex{expect} knock-off.
|
||||||
|
\item A \ex{make} replacement, using scsh's process notation in the build
|
||||||
|
rules.
|
||||||
|
|
||||||
\item Manual hacking.
|
\item Manual hacking.
|
||||||
\begin{itemize}
|
\begin{itemize}
|
||||||
\item The {\LaTeX} hackery needs yet another serious pass. Most importantly,
|
\item The {\LaTeX} hackery needs yet another serious pass. Most importantly,
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
\documentclass[twoside]{report}
|
\documentclass[twoside]{report}
|
||||||
\usepackage{code,boxedminipage,draftfooters,makeidx,palatino,ct,
|
\usepackage{code,boxedminipage,draftfooters,makeidx,palatino,ct,
|
||||||
headings,mantitle,array,matter,a4,tex2page}
|
headings,mantitle,array,matter,a4}
|
||||||
|
|
||||||
% Style issues
|
% Style issues
|
||||||
\parskip = 3pt plus 3pt
|
\parskip = 3pt plus 3pt
|
||||||
|
|
14
scsh.man
14
scsh.man
|
@ -1,4 +1,4 @@
|
||||||
.TH LSCSH 1
|
.TH LS48 1
|
||||||
.\" File scsh.man: Manual page template for scsh.
|
.\" File scsh.man: Manual page template for scsh.
|
||||||
.\" Replace LSCSH with the name of your default image and LLIB with the
|
.\" Replace LSCSH with the name of your default image and LLIB with the
|
||||||
.\" directory containing scshvm and default image.
|
.\" directory containing scshvm and default image.
|
||||||
|
@ -22,7 +22,8 @@ The
|
||||||
.B LSCSH
|
.B LSCSH
|
||||||
command loop reads Scheme expressions,
|
command loop reads Scheme expressions,
|
||||||
evaluates them, and prints their results.
|
evaluates them, and prints their results.
|
||||||
The Scheme 48 system is an R5RS system.
|
The Scheme 48 system is an R4RS system, and also provides features from
|
||||||
|
the draft R5RS standard.
|
||||||
It also executes commands, which are identified by an initial comma character.
|
It also executes commands, which are identified by an initial comma character.
|
||||||
Type the command
|
Type the command
|
||||||
.I ,help
|
.I ,help
|
||||||
|
@ -41,7 +42,7 @@ argument can be one of
|
||||||
Either of these switches terminates argument parsing; following arguments
|
Either of these switches terminates argument parsing; following arguments
|
||||||
are available from scsh as the string list produced by
|
are available from scsh as the string list produced by
|
||||||
.nf
|
.nf
|
||||||
(command-line)
|
(command-line-arguments)
|
||||||
.fi
|
.fi
|
||||||
The
|
The
|
||||||
.B \-s
|
.B \-s
|
||||||
|
@ -62,12 +63,9 @@ The
|
||||||
.B \-\-
|
.B \-\-
|
||||||
switch is used to pass arguments to an interactive scsh.
|
switch is used to pass arguments to an interactive scsh.
|
||||||
It simply terminates argument parsing, causing following
|
It simply terminates argument parsing, causing following
|
||||||
arguments to be made available by
|
arguments to be bound to
|
||||||
.nf
|
.nf
|
||||||
(command-line)
|
(command-line-arguments)
|
||||||
|
|
||||||
There are other command-line switches. For detailed documentation,
|
|
||||||
see the manual, which comes with the distribution.
|
|
||||||
|
|
||||||
.SH FILES
|
.SH FILES
|
||||||
.TP
|
.TP
|
||||||
|
|
|
@ -1,4 +0,0 @@
|
||||||
/* Exports from signals1.c */
|
|
||||||
|
|
||||||
const int sig2int[];
|
|
||||||
const int max_sig;
|
|
|
@ -1,2 +1,6 @@
|
||||||
|
/* Cygwin seems to have TZNAME but they forgot to define it */
|
||||||
|
#define HAVE_TZNAME
|
||||||
|
#define tzname _tzname
|
||||||
|
|
||||||
/* Cygwin's adds _'s but making configure.in know about dlltool seemed evil */
|
/* Cygwin's adds _'s but making configure.in know about dlltool seemed evil */
|
||||||
#define DLSYM_ADDS_USCORE
|
#define DLSYM_ADDS_USCORE
|
||||||
|
|
|
@ -40,7 +40,7 @@
|
||||||
(let ((uid (user-effective-uid)))
|
(let ((uid (user-effective-uid)))
|
||||||
(with-errno-handler ((err data)
|
(with-errno-handler ((err data)
|
||||||
((errno/acces) 'search-denied)
|
((errno/acces) 'search-denied)
|
||||||
((errno/notdir) 'no-directory)
|
((errno/notdir) 'not-directory)
|
||||||
|
|
||||||
;; If the file doesn't exist, we usually return
|
;; If the file doesn't exist, we usually return
|
||||||
;; 'nonexistent, but we special-case writability
|
;; 'nonexistent, but we special-case writability
|
||||||
|
|
|
@ -69,7 +69,7 @@
|
||||||
|
|
||||||
(define (->delim-matcher x)
|
(define (->delim-matcher x)
|
||||||
(if (procedure? x) x ; matcher proc
|
(if (procedure? x) x ; matcher proc
|
||||||
(let ((re (cond ((string? x) (posix-string->regexp x))
|
(let ((re (cond ((string? x) (re-string x))
|
||||||
((char-set? x) (re-char-set x))
|
((char-set? x) (re-char-set x))
|
||||||
((char? x) (re-string (string x)))
|
((char? x) (re-string (string x)))
|
||||||
((regexp? x) x)
|
((regexp? x) x)
|
||||||
|
|
|
@ -122,9 +122,10 @@
|
||||||
(cons re-any (str-cons chars res))
|
(cons re-any (str-cons chars res))
|
||||||
i))
|
i))
|
||||||
|
|
||||||
((#\[) (receive (re i) (parse-glob-bracket pat i)
|
((#\[) (receive (cset i) (parse-glob-bracket pat i)
|
||||||
(lp '()
|
(lp '()
|
||||||
(cons re (str-cons chars res))
|
(cons (re-char-set cset)
|
||||||
|
(str-cons chars res))
|
||||||
i)))
|
i)))
|
||||||
|
|
||||||
(else (lp (cons c chars) res i))))))))))
|
(else (lp (cons c chars) res i))))))))))
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
;;; These defs are things for characters *not* in SRFIs 13 & 14.
|
;;; These defs are things for characters *not* in SRFIs 13 & 14.
|
||||||
;;; It includes some R5RS defs that are not correct in S48 in a Latin-1 world.
|
;;; It includes some R5RS defs that are not correct in S48 in a Latin-1 world.
|
||||||
|
|
||||||
(define-interface char-predicates-interface
|
(define-interface char-set-predicates-interface
|
||||||
(export
|
(export
|
||||||
((char-lower-case? ; R5RS
|
((char-lower-case? ; R5RS
|
||||||
char-upper-case? ; R5RS
|
char-upper-case? ; R5RS
|
||||||
|
@ -24,7 +24,7 @@
|
||||||
char-ascii?) (proc (:char) :boolean))))
|
char-ascii?) (proc (:char) :boolean))))
|
||||||
|
|
||||||
|
|
||||||
(define-structure char-predicates-lib char-predicates-interface
|
(define-structure char-set-predicates-lib char-set-predicates-interface
|
||||||
(open error-package ; ERROR
|
(open error-package ; ERROR
|
||||||
scsh-utilities ; DEPRECATED-PROC
|
scsh-utilities ; DEPRECATED-PROC
|
||||||
char-set-lib
|
char-set-lib
|
||||||
|
|
|
@ -6,9 +6,8 @@
|
||||||
chars->char-set ; list->char-set
|
chars->char-set ; list->char-set
|
||||||
ascii-range->char-set ; ucs-range->char-set (not exact)
|
ascii-range->char-set ; ucs-range->char-set (not exact)
|
||||||
predicate->char-set ; char-set-filter (not exact)
|
predicate->char-set ; char-set-filter (not exact)
|
||||||
;->char-set ; no longer handles a predicate
|
->char-set ; no longer handles a predicate
|
||||||
char-set-every? ; char-set-every
|
char-set-every? ; char-set-every
|
||||||
char-set-any? ; char-set-any
|
|
||||||
|
|
||||||
char-set-invert ; char-set-complement
|
char-set-invert ; char-set-complement
|
||||||
char-set-invert! ; char-set-complement!
|
char-set-invert! ; char-set-complement!
|
||||||
|
@ -39,16 +38,13 @@
|
||||||
"Change code to use CHAR-SET-FILTER."))
|
"Change code to use CHAR-SET-FILTER."))
|
||||||
(define char-set-every?
|
(define char-set-every?
|
||||||
(deprecated-proc char-set-every 'char-set-every?
|
(deprecated-proc char-set-every 'char-set-every?
|
||||||
"Use CHAR-SET-EVERY instead."))
|
"Use CHAR-SET-EVERYyn instead."))
|
||||||
(define char-set-any?
|
|
||||||
(deprecated-proc char-set-every 'char-set-any?
|
|
||||||
"Use CHAR-SET-ANY instead."))
|
|
||||||
(define char-set-invert
|
(define char-set-invert
|
||||||
(deprecated-proc char-set-complement 'char-set-invert
|
(deprecated-proc char-set-complement 'char-set-invert
|
||||||
"Use CHAR-SET-COMPLEMENT instead."))
|
"Use CHAR-SET-COMPLEMENTyn instead."))
|
||||||
(define char-set-invert!
|
(define char-set-invert!
|
||||||
(deprecated-proc char-set-complement! 'char-set-invert!
|
(deprecated-proc char-set-complement! 'char-set-invert!
|
||||||
"Use CHAR-SET-COMPLEMENT! instead."))
|
"Use CHAR-SET-COMPLEMENT!yn instead."))
|
||||||
|
|
||||||
(define char-set:alphabetic char-set:letter)
|
(define char-set:alphabetic char-set:letter)
|
||||||
(define char-set:numeric char-set:digit)
|
(define char-set:numeric char-set:digit)
|
||||||
|
|
|
@ -62,7 +62,7 @@
|
||||||
|
|
||||||
(char-set-size (proc (:value) :exact-integer))
|
(char-set-size (proc (:value) :exact-integer))
|
||||||
(char-set-count (proc ((proc (:char) :boolean) :value) :exact-integer))
|
(char-set-count (proc ((proc (:char) :boolean) :value) :exact-integer))
|
||||||
(char-set-contains? (proc (:value :value) :boolean))
|
(char-set-contains? (proc (:char :value) :boolean))
|
||||||
|
|
||||||
(char-set-every (proc ((proc (:char) :boolean) :value) :boolean))
|
(char-set-every (proc ((proc (:char) :boolean) :value) :boolean))
|
||||||
(char-set-any (proc ((proc (:char) :boolean) :value) :value))
|
(char-set-any (proc ((proc (:char) :boolean) :value) :value))
|
||||||
|
|
|
@ -1130,7 +1130,7 @@
|
||||||
;;; string-index-right string char/char-set/pred [start end]
|
;;; string-index-right string char/char-set/pred [start end]
|
||||||
;;; string-skip string char/char-set/pred [start end]
|
;;; string-skip string char/char-set/pred [start end]
|
||||||
;;; string-skip-right string char/char-set/pred [start end]
|
;;; string-skip-right string char/char-set/pred [start end]
|
||||||
;;; string-count string char/char-set/pred [start end]
|
;;; string-count char/char-set/pred string [start end]
|
||||||
;;; There's a lot of replicated code here for efficiency.
|
;;; There's a lot of replicated code here for efficiency.
|
||||||
;;; For example, the char/char-set/pred discrimination has
|
;;; For example, the char/char-set/pred discrimination has
|
||||||
;;; been lifted above the inner loop of each proc.
|
;;; been lifted above the inner loop of each proc.
|
||||||
|
@ -1220,7 +1220,7 @@
|
||||||
string-skip-right criterion)))))
|
string-skip-right criterion)))))
|
||||||
|
|
||||||
|
|
||||||
(define (string-count s criterion . maybe-start+end)
|
(define (string-count criterion s . maybe-start+end)
|
||||||
(let-string-start+end (start end) string-count s maybe-start+end
|
(let-string-start+end (start end) string-count s maybe-start+end
|
||||||
(cond ((char? criterion)
|
(cond ((char? criterion)
|
||||||
(do ((i start (+ i 1))
|
(do ((i start (+ i 1))
|
||||||
|
|
|
@ -1,315 +0,0 @@
|
||||||
;;; string-lib
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
||||||
;;; string-map string-map!
|
|
||||||
;;; string-fold string-fold-right
|
|
||||||
;;; string-unfold string-tabulate
|
|
||||||
;;; string-for-each string-iter
|
|
||||||
;;; string-every string-any
|
|
||||||
;;; string-compare string-compare-ci
|
|
||||||
;;; substring-compare substring-compare-ci
|
|
||||||
;;; string= string< string> string<= string>= string<>
|
|
||||||
;;; string-ci= string-ci< string-ci> string-ci<= string-ci>= string-ci<>
|
|
||||||
;;; substring= substring<> substring-ci= substring-ci<>
|
|
||||||
;;; substring< substring> substring-ci< substring-ci>
|
|
||||||
;;; substring<= substring>= substring-ci<= substring-ci>=
|
|
||||||
;;; string-upper-case? string-lower-case?
|
|
||||||
;;; capitalize-string capitalize-words string-downcase string-upcase
|
|
||||||
;;; capitalize-string! capitalize-words! string-downcase! string-upcase!
|
|
||||||
;;; string-take string-drop
|
|
||||||
;;; string-pad string-pad-right
|
|
||||||
;;; string-trim string-trim-right string-trim-both
|
|
||||||
;;; string-filter string-delete
|
|
||||||
;;; string-index string-index-right string-skip string-skip-right
|
|
||||||
;;; string-prefix-count string-prefix-count-ci
|
|
||||||
;;; string-suffix-count string-suffix-count-ci
|
|
||||||
;;; substring-prefix-count substring-prefix-count-ci
|
|
||||||
;;; substring-suffix-count substring-suffix-count-ci
|
|
||||||
;;; string-prefix? string-prefix-ci?
|
|
||||||
;;; string-suffix? string-suffix-ci?
|
|
||||||
;;; substring-prefix? substring-prefix-ci?
|
|
||||||
;;; substring-suffix? substring-suffix-ci?
|
|
||||||
;;; substring? substring-ci?
|
|
||||||
;;; string-fill! string-copy! string-copy substring
|
|
||||||
;;; string-reverse string-reverse! reverse-list->string
|
|
||||||
;;; string->list
|
|
||||||
;;; string-concat string-concat/shared string-append/shared
|
|
||||||
;;; xsubstring string-xcopy!
|
|
||||||
;;; string-null?
|
|
||||||
;;; join-strings
|
|
||||||
;;;
|
|
||||||
;;; string? make-string string string-length string-ref string-set!
|
|
||||||
;;; string-append list->string
|
|
||||||
|
|
||||||
(define-interface string-lib-interface
|
|
||||||
(export
|
|
||||||
;; string-map proc s [start end] -> s
|
|
||||||
(string-map (proc ((proc (:char) :char)
|
|
||||||
:string
|
|
||||||
&opt :exact-integer :exact-integer)
|
|
||||||
:string))
|
|
||||||
|
|
||||||
;; string-map! proc s [start end] -> unspecific
|
|
||||||
(string-map! (proc ((proc (:char) :values)
|
|
||||||
:string
|
|
||||||
&opt :exact-integer :exact-integer)
|
|
||||||
:unspecific))
|
|
||||||
|
|
||||||
;; string-fold kons knil s [start end] -> value
|
|
||||||
;; string-fold-right kons knil s [start end] -> value
|
|
||||||
((string-fold string-fold-right)
|
|
||||||
(proc ((proc (:char :value) :value)
|
|
||||||
:value :string
|
|
||||||
&opt :exact-integer :exact-integer)
|
|
||||||
:value))
|
|
||||||
|
|
||||||
;; string-unfold p f g seed -> string
|
|
||||||
(string-unfold (proc ((proc (:value) :boolean)
|
|
||||||
(proc (:value) :char)
|
|
||||||
(proc (:value) :value)
|
|
||||||
:value)
|
|
||||||
:string))
|
|
||||||
|
|
||||||
; Enough is enough.
|
|
||||||
; ;; string-unfoldn p f g seed ... -> string
|
|
||||||
; (string-unfoldn (proc ((procedure :values :boolean)
|
|
||||||
; (procedure :values :char)
|
|
||||||
; (procedure :values :values)
|
|
||||||
; &rest :value)
|
|
||||||
; :string))
|
|
||||||
|
|
||||||
;; string-tabulate proc len -> string
|
|
||||||
(string-tabulate (proc ((proc (:exact-integer) :char) :exact-integer)
|
|
||||||
:string))
|
|
||||||
|
|
||||||
;; string-for-each proc s [start end] -> unspecific
|
|
||||||
;; string-iter proc s [start end] -> unspecific
|
|
||||||
((string-for-each string-iter)
|
|
||||||
(proc ((proc (:char) :values) :string &opt :exact-integer :exact-integer)
|
|
||||||
:unspecific))
|
|
||||||
|
|
||||||
;; string-every pred s [start end]
|
|
||||||
;; string-any pred s [start end]
|
|
||||||
(string-every
|
|
||||||
(proc ((proc (:char) :boolean) :string &opt :exact-integer :exact-integer)
|
|
||||||
:boolean))
|
|
||||||
(string-any
|
|
||||||
(proc ((proc (:char) :boolean) :string &opt :exact-integer :exact-integer)
|
|
||||||
:value))
|
|
||||||
|
|
||||||
;; string-compare string1 string2 lt-proc eq-proc gt-proc
|
|
||||||
;; string-compare-ci string1 string2 lt-proc eq-proc gt-proc
|
|
||||||
((string-compare string-compare-ci)
|
|
||||||
(proc (:string :string (proc (:exact-integer) :values)
|
|
||||||
(proc (:exact-integer) :values)
|
|
||||||
(proc (:exact-integer) :values))
|
|
||||||
:values))
|
|
||||||
|
|
||||||
;; substring-compare string1 start1 end1 string2 start2 end2 lt eq gt
|
|
||||||
;; substring-compare-ci string1 start1 end1 string2 start2 end2 lt eq gt
|
|
||||||
((substring-compare substring-compare-ci)
|
|
||||||
(proc (:string :exact-integer :exact-integer
|
|
||||||
:string :exact-integer :exact-integer
|
|
||||||
(proc (:exact-integer) :values)
|
|
||||||
(proc (:exact-integer) :values)
|
|
||||||
(proc (:exact-integer) :values))
|
|
||||||
:values))
|
|
||||||
|
|
||||||
;; string< string1 string2
|
|
||||||
((string= string< string> string<= string>= string<>
|
|
||||||
string-ci= string-ci< string-ci> string-ci<= string-ci>= string-ci<>)
|
|
||||||
(proc (&rest :string) :value))
|
|
||||||
|
|
||||||
;; substring< string1 start1 end1 string2 start2 end2
|
|
||||||
((substring= substring<> substring-ci= substring-ci<>
|
|
||||||
substring< substring> substring-ci< substring-ci>
|
|
||||||
substring<= substring>= substring-ci<= substring-ci>=)
|
|
||||||
(proc (:string :exact-integer :exact-integer
|
|
||||||
:string :exact-integer :exact-integer)
|
|
||||||
:value))
|
|
||||||
|
|
||||||
;; string-upper-case? string [start end]
|
|
||||||
;; string-lower-case? string [start end]
|
|
||||||
((string-upper-case? string-lower-case?)
|
|
||||||
(proc (:string &opt :exact-integer :exact-integer) :boolean))
|
|
||||||
|
|
||||||
;; capitalize-string string [start end]
|
|
||||||
;; capitalize-words string [start end]
|
|
||||||
;; string-downcase string [start end]
|
|
||||||
;; string-upcase string [start end]
|
|
||||||
;; capitalize-string! string [start end]
|
|
||||||
;; capitalize-words! string [start end]
|
|
||||||
;; string-downcase! string [start end]
|
|
||||||
;; string-upcase! string [start end]
|
|
||||||
((capitalize-string capitalize-words string-downcase string-upcase)
|
|
||||||
(proc (:string &opt :exact-integer :exact-integer) :string))
|
|
||||||
((capitalize-string! capitalize-words! string-downcase! string-upcase!)
|
|
||||||
(proc (:string &opt :exact-integer :exact-integer) :unspecific))
|
|
||||||
|
|
||||||
;; string-take string nchars
|
|
||||||
;; string-drop string nchars
|
|
||||||
((string-take string-drop) (proc (:string :exact-integer) :string))
|
|
||||||
|
|
||||||
;; string-pad string k [char start end]
|
|
||||||
;; string-pad-right string k [char start end]
|
|
||||||
((string-pad string-pad-right)
|
|
||||||
(proc (:string :exact-integer &opt :char :exact-integer :exact-integer)
|
|
||||||
:string))
|
|
||||||
|
|
||||||
;; string-trim string [char/char-set/pred start end]
|
|
||||||
;; string-trim-right string [char/char-set/pred start end]
|
|
||||||
;; string-trim-both string [char/char-set/pred start end]
|
|
||||||
((string-trim string-trim-right string-trim-both)
|
|
||||||
(proc (:string &opt :value :exact-integer :exact-integer)
|
|
||||||
:string))
|
|
||||||
|
|
||||||
;; string-filter char/char-set/pred string [start end]
|
|
||||||
;; string-delete char/char-set/pred string [start end]
|
|
||||||
((string-filter string-delete)
|
|
||||||
(proc (:value :string &opt :exact-integer :exact-integer) :string))
|
|
||||||
|
|
||||||
;; string-index string char/char-set/pred [start end]
|
|
||||||
;; string-index-right string char/char-set/pred [end start]
|
|
||||||
;; string-skip string char/char-set/pred [start end]
|
|
||||||
;; string-skip-right string char/char-set/pred [end start]
|
|
||||||
((string-index string-index-right string-skip string-skip-right)
|
|
||||||
(proc (:string :value &opt :exact-integer :exact-integer)
|
|
||||||
:value))
|
|
||||||
|
|
||||||
;; string-prefix-count string1 string2
|
|
||||||
;; string-suffix-count string1 string2
|
|
||||||
;; string-prefix-count-ci string1 string2
|
|
||||||
;; string-suffix-count-ci string1 string2
|
|
||||||
((string-prefix-count string-prefix-count-ci
|
|
||||||
string-suffix-count string-suffix-count-ci)
|
|
||||||
(proc (:string :string) :exact-integer))
|
|
||||||
|
|
||||||
;; substring-prefix-count string1 start1 end1 string2 start2 end2
|
|
||||||
;; substring-suffix-count string1 start1 end1 string2 start2 end2
|
|
||||||
;; substring-prefix-count-ci string1 start1 end1 string2 start2 end2
|
|
||||||
;; substring-suffix-count-ci string1 start1 end1 string2 start2 end2
|
|
||||||
((substring-prefix-count substring-prefix-count-ci
|
|
||||||
substring-suffix-count substring-suffix-count-ci)
|
|
||||||
(proc (:string :exact-integer :exact-integer
|
|
||||||
:string :exact-integer :exact-integer)
|
|
||||||
:exact-integer))
|
|
||||||
|
|
||||||
|
|
||||||
;; string-prefix? string1 string2
|
|
||||||
;; string-suffix? string1 string2
|
|
||||||
;; string-prefix-ci? string1 string2
|
|
||||||
;; string-suffix-ci? string1 string2
|
|
||||||
((string-prefix? string-prefix-ci?
|
|
||||||
string-suffix? string-suffix-ci?)
|
|
||||||
(proc (:string :string) :boolean))
|
|
||||||
|
|
||||||
;; substring-prefix? string1 start1 end1 string2 start2 end2
|
|
||||||
;; substring-suffix? string1 start1 end1 string2 start2 end2
|
|
||||||
;; substring-prefix-ci? string1 start1 end1 string2 start2 end2
|
|
||||||
;; substring-suffix-ci? string1 start1 end1 string2 start2 end2
|
|
||||||
((substring-prefix? substring-prefix-ci?
|
|
||||||
substring-suffix? substring-suffix-ci?)
|
|
||||||
(proc (:string :exact-integer :exact-integer
|
|
||||||
:string :exact-integer :exact-integer)
|
|
||||||
:boolean))
|
|
||||||
|
|
||||||
;; substring? pattern string [start end]
|
|
||||||
;; substring-ci? pattern string [start end]
|
|
||||||
((substring? substring-ci?)
|
|
||||||
(proc (:string :string &opt :exact-integer :exact-integer)
|
|
||||||
:value))
|
|
||||||
|
|
||||||
;; string-fill! string char [start end]
|
|
||||||
(string-fill! (proc (:string :char &opt :exact-integer :exact-integer)
|
|
||||||
:unspecific))
|
|
||||||
|
|
||||||
;; string-copy! to tstart from [fstart fend]
|
|
||||||
(string-copy! (proc (:string :exact-integer :string
|
|
||||||
&opt :exact-integer :exact-integer)
|
|
||||||
:unspecific))
|
|
||||||
|
|
||||||
;; string-copy s [start end] -> string
|
|
||||||
;; substring s start [end] -> string
|
|
||||||
(string-copy (proc (:string &opt :exact-integer :exact-integer) :string))
|
|
||||||
(substring (proc (:string :exact-integer &opt :exact-integer) :string))
|
|
||||||
|
|
||||||
;; string-reverse s [start end]
|
|
||||||
;; string-reverse! s [start end]
|
|
||||||
(string-reverse (proc (:string &opt :exact-integer :exact-integer) :string))
|
|
||||||
(string-reverse! (proc (:string &opt :exact-integer :exact-integer) :unspecific))
|
|
||||||
|
|
||||||
;; reverse-list->string char-list
|
|
||||||
;; string->list s [start end]
|
|
||||||
;; string-concat string-list
|
|
||||||
;; string-concat/shared string-list
|
|
||||||
;; string-append/shared s ...
|
|
||||||
(reverse-list->string (proc (:value) :string))
|
|
||||||
(string->list (proc (:string &opt :exact-integer :exact-integer) :value))
|
|
||||||
((string-concat string-concat/shared) (proc (:value) :string))
|
|
||||||
(string-append/shared (proc (&rest :string) :string))
|
|
||||||
|
|
||||||
;; xsubstring s from [to start end]
|
|
||||||
;; string-xcopy! target tstart s from [to start end]
|
|
||||||
(xsubstring (proc (:string :exact-integer &opt
|
|
||||||
:exact-integer :exact-integer :exact-integer)
|
|
||||||
:string))
|
|
||||||
(string-xcopy! (proc (:string :exact-integer :string :exact-integer &opt
|
|
||||||
:exact-integer :exact-integer :exact-integer)
|
|
||||||
:unspecific))
|
|
||||||
|
|
||||||
;; string-null? s
|
|
||||||
(string-null? (proc (:string) :boolean))
|
|
||||||
|
|
||||||
(join-strings (proc (:value &opt :string :symbol) :string))
|
|
||||||
|
|
||||||
;; Here are the R4RS procs
|
|
||||||
(string? (proc (:value) :boolean))
|
|
||||||
(make-string (proc (:exact-integer &opt :char) :string))
|
|
||||||
(string (proc (&rest :char) :string))
|
|
||||||
(string-length (proc (:string) :exact-integer))
|
|
||||||
(string-ref (proc (:string :exact-integer) :char))
|
|
||||||
(string-set! (proc (:string :exact-integer :char) :unspecific))
|
|
||||||
|
|
||||||
; Not provided by string-lib.
|
|
||||||
;((string=? string-ci=? string<? string-ci<?
|
|
||||||
; string>? string-ci>? string<=? string-ci<=?
|
|
||||||
; string>=? string-ci>=?) (proc (:string :string) :boolean))
|
|
||||||
|
|
||||||
;; These are the R4RS types for SUBSTRING, STRING-COPY, STRING-FILL!,
|
|
||||||
;; and STRING->LIST. The string-lib types are different -- extended.
|
|
||||||
;(substring (proc (:string :exact-integer :exact-integer) :string))
|
|
||||||
;(string-copy (proc (:string) :string))
|
|
||||||
;(string-fill! (proc (:string :char) :unspecific))
|
|
||||||
;(string->list (proc (:string) :value))
|
|
||||||
|
|
||||||
(string-append (proc (&rest :string) :string))
|
|
||||||
(list->string (proc (:value) :string))
|
|
||||||
))
|
|
||||||
|
|
||||||
|
|
||||||
;;; make-kmp-restart-vector
|
|
||||||
;;; parse-final-start+end
|
|
||||||
;;; parse-start+end
|
|
||||||
;;; check-substring-spec
|
|
||||||
|
|
||||||
(define-interface string-lib-internals-interface
|
|
||||||
(export
|
|
||||||
(parse-final-start+end (proc ((procedure :values :values) :string :value)
|
|
||||||
(some-values :exact-integer :exact-integer)))
|
|
||||||
(parse-start+end (proc ((procedure :values :values) :string :value)
|
|
||||||
(some-values :exact-integer :exact-integer :value)))
|
|
||||||
(check-substring-spec (proc ((procedure :values :values) :string :exact-integer :exact-integer)
|
|
||||||
:unspecific))
|
|
||||||
(make-kmp-restart-vector (proc (:string (proc (:char :char) :boolean))
|
|
||||||
:vector))))
|
|
||||||
|
|
||||||
|
|
||||||
(define-structures ((string-lib string-lib-interface)
|
|
||||||
(string-lib-internals string-lib-internals-interface))
|
|
||||||
(access scheme) ; Get at R5RS SUBSTRING
|
|
||||||
(open receiving ; RECEIVE
|
|
||||||
char-set-package; Various
|
|
||||||
error-package ; ERROR
|
|
||||||
let-opt ; LET-OPTIONALS :OPTIONAL
|
|
||||||
structure-refs ; STRUCTURE-REF
|
|
||||||
scheme)
|
|
||||||
(files string-lib))
|
|
|
@ -0,0 +1,578 @@
|
||||||
|
Todo:
|
||||||
|
parse-start+end parse-final-start+end need "string" in the name
|
||||||
|
Also, export macro binder.
|
||||||
|
What's up w/quotient? (quotient -1 3) = 0.
|
||||||
|
regexp-foldl
|
||||||
|
type regexp interface
|
||||||
|
land*
|
||||||
|
Let-optional:
|
||||||
|
A let-optional that parses a prefix of the args.
|
||||||
|
Arg checking forms that get used if it parses, but are not
|
||||||
|
applied to the default.
|
||||||
|
|
||||||
|
The Scheme Underground string library includes a rich set of operations
|
||||||
|
for manipulating strings. These are frequently useful for scripting and
|
||||||
|
other text-manipulation applications.
|
||||||
|
|
||||||
|
The library's design was influenced by the string libraries found in MIT
|
||||||
|
Scheme, Gambit, RScheme, MzScheme, slib, Common Lisp, Bigloo, guile, APL and
|
||||||
|
the SML standard basis. Some of the code bears a distant family relation to
|
||||||
|
the MIT Scheme implementation, and being derived from that code, is covered by
|
||||||
|
the MIT Scheme copyright (which is a fairly generic "free" copyright -- see
|
||||||
|
the source file for details). The fast KMP string-search code used in
|
||||||
|
SUBSTRING? was loosely adapted from old slib code by Stephen Bevan.
|
||||||
|
|
||||||
|
The library has the following design principles:
|
||||||
|
- *All* procedures involving character comparison are available in
|
||||||
|
both case-sensitive and case-insensitive forms.
|
||||||
|
|
||||||
|
- *All* functionality is available in substring and full-string forms.
|
||||||
|
|
||||||
|
- The procedures are spec'd so as to permit efficient implementation in a
|
||||||
|
Scheme that provided shared-text substrings (e.g., guile). This means that
|
||||||
|
you should not rely on many of the substring-selecting procedures to return
|
||||||
|
freshly-allocated strings. Careful attention is paid to the issue of which
|
||||||
|
procedures allocate fresh storage, and which are permitted to return results
|
||||||
|
that share storage with the arguments.
|
||||||
|
|
||||||
|
- Common Lisp theft:
|
||||||
|
+ inequality functions return mismatch index.
|
||||||
|
I generalised this so that this "protocol" is extended even to
|
||||||
|
the equality functions. This means that clients can be handed any generic
|
||||||
|
string-comparison function and rely on the meaning of the true value.
|
||||||
|
|
||||||
|
+ Common Lisp capitalisation definition
|
||||||
|
|
||||||
|
The library addresses some problems with the R5RS string procedures:
|
||||||
|
- Question marks after string-comparison functions (string=?, etc.)
|
||||||
|
This is inconsistent with numeric comparison functions, and ugly, too.
|
||||||
|
- String-comparison functions do not provide useful true value.
|
||||||
|
- STRING-COPY should have optional start/end args;
|
||||||
|
SUBSTRING shouldn't specify if it copies or returns shared bits.
|
||||||
|
- STRING-FILL! and STRING->LIST should take optional start/end args.
|
||||||
|
- No <> function provided.
|
||||||
|
|
||||||
|
In the following procedure specifications:
|
||||||
|
- Any S parameter is a string;
|
||||||
|
|
||||||
|
- START and END parameters are half-open string indices specifying
|
||||||
|
a substring within a string parameter; when optional, they default
|
||||||
|
to 0 and the length of the string, respectively. When specified, it
|
||||||
|
must be the case that 0 <= START <= END <= (string-length S), for
|
||||||
|
the corresponding parameter S. They typically restrict a procedure's
|
||||||
|
action to the indicated substring.
|
||||||
|
|
||||||
|
- A CHAR/CHAR-SET/PRED parameter is a value used to select/search
|
||||||
|
for a character in a string. If it is a character, it is used in
|
||||||
|
an equality test; if it is a character set, it is used as a
|
||||||
|
membership test; if it is a procedure, it is applied to the
|
||||||
|
characters as a test predicate.
|
||||||
|
|
||||||
|
This library contains a large number of procedures, but they follow
|
||||||
|
a consistent naming scheme. The names are composed of smaller lexemes
|
||||||
|
in a regular way that exposes the structure and relationships between the
|
||||||
|
procedures. This should help the programmer to recall or reconstitute the name
|
||||||
|
of the particular procedure that he needs when writing his own code. In
|
||||||
|
particular
|
||||||
|
- Procedures whose names end in "-ci" are case-insensitive variants.
|
||||||
|
- Procedures whose names end in "!" are side-effecting variants.
|
||||||
|
These procedures generally return an unspecified value.
|
||||||
|
- The order of common parameters is fairly consistent across the
|
||||||
|
different procedures.
|
||||||
|
|
||||||
|
For more text-manipulation functionality, see also the regular expression,
|
||||||
|
file-name, character set, and character->character partial map packages.
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
* R4RS/R5RS procedures
|
||||||
|
|
||||||
|
The R4RS and R5RS reports define 22 string procedures. The string-lib
|
||||||
|
package includes 8 of these exactly as defined, 4 in an extended,
|
||||||
|
backwards-compatible way, and drops the remaining 10 (whose functionality
|
||||||
|
is available via other bindings).
|
||||||
|
|
||||||
|
The 8 procedures provided exactly as documented in the reports are
|
||||||
|
string?
|
||||||
|
make-string
|
||||||
|
string
|
||||||
|
string-length
|
||||||
|
string-ref
|
||||||
|
string-set!
|
||||||
|
string-append
|
||||||
|
list->string
|
||||||
|
|
||||||
|
The ten functions not included are the R4RS string-comparison functions:
|
||||||
|
string=? string-ci=?
|
||||||
|
string<? string-ci<?
|
||||||
|
string>? string-ci>?
|
||||||
|
string<=? string-ci<=?
|
||||||
|
string>=? string-ci>=?
|
||||||
|
The string-lib package provides alternate bindings.
|
||||||
|
|
||||||
|
Additionally, the four extended procedures are
|
||||||
|
|
||||||
|
string-fill! s char [start end] -> unspecific
|
||||||
|
string->list s [start end] -> char-list
|
||||||
|
substring s start [end] -> string
|
||||||
|
string-copy s [start end] -> string
|
||||||
|
|
||||||
|
These procedures are documented in the following section. In brief, they are
|
||||||
|
extended to take optional start/end parameters specifying substring ranges;
|
||||||
|
Additionally, SUBSTRING is allowed to return a value that shares storage with
|
||||||
|
its argument.
|
||||||
|
|
||||||
|
|
||||||
|
* Procedures
|
||||||
|
|
||||||
|
These procedures are contained in the Scheme 48 package "string-lib",
|
||||||
|
which is open in the default user package. They are not found in the
|
||||||
|
"scsh" package; script writers and other programmers that use the Scheme
|
||||||
|
48 module system must open string-lib explicitly.
|
||||||
|
|
||||||
|
string-map proc s [start end] -> string
|
||||||
|
string-map! proc s [start end] -> unspecified
|
||||||
|
PROC is a char->char procedure; it is mapped over S.
|
||||||
|
Note: no sequence order is specified.
|
||||||
|
|
||||||
|
string-fold kons knil s [start end] -> value
|
||||||
|
string-fold-right kons knil s [start end] -> value
|
||||||
|
These are the fundamental iterators for strings.
|
||||||
|
The left-fold operator maps the KONS procedure across the
|
||||||
|
string from left to right
|
||||||
|
(... (kons s[2] (kons s[1] (kons s[0] knil))))
|
||||||
|
In other words, string-fold obeys the recursion
|
||||||
|
(string-fold kons knil s start end) =
|
||||||
|
(string-fold kons (kons s[start] knil) start+1 end)
|
||||||
|
|
||||||
|
The right-fold operator maps the KONS procedure across the
|
||||||
|
string from right to left
|
||||||
|
(kons s[0] (... (kons s[end-3] (kons s[end-2] (kons s[end-1] knil)))))
|
||||||
|
obeying the recursion
|
||||||
|
(string-fold-right kons knil s start end) =
|
||||||
|
(string-fold-right kons (kons s[end-1] knil) start end-1)
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
To convert a string to a list of chars:
|
||||||
|
(string-fold-right cons '() s)
|
||||||
|
|
||||||
|
To count the number of lower-case characters in a string:
|
||||||
|
(string-fold (lambda (c count)
|
||||||
|
(if (char-set-contains? char-set:lower c)
|
||||||
|
(+ count 1)
|
||||||
|
count))
|
||||||
|
0
|
||||||
|
s)
|
||||||
|
|
||||||
|
string-unfold p f g seed -> string
|
||||||
|
This is the fundamental constructor for strings.
|
||||||
|
- G is used to generate a series of "seed" values from the initial seed:
|
||||||
|
SEED, (G SEED), (G^2 SEED), (G^3 SEED), ...
|
||||||
|
- P tells us when to stop -- when it returns true when applied to one
|
||||||
|
of these seed values.
|
||||||
|
- F maps each seed value to the corresponding character
|
||||||
|
in the result string.
|
||||||
|
|
||||||
|
More precisely, the following (simple, inefficient) definition holds:
|
||||||
|
(define (string-unfold p f g seed)
|
||||||
|
(if (p seed) ""
|
||||||
|
(string-append (string (f seed))
|
||||||
|
(string-unfold p f g (g seed)))))
|
||||||
|
|
||||||
|
STRING-UNFOLD is a fairly powerful constructor -- you can use it to
|
||||||
|
reverse a string, copy a string, convert a list to a string, read
|
||||||
|
a port into a string, and so forth. Examples:
|
||||||
|
(port->string p) = (string-unfold eof-object? values
|
||||||
|
(lambda (x) (read-char p))
|
||||||
|
(read-char p))
|
||||||
|
|
||||||
|
(list->string lis) = (string-unfold null? car cdr lis)
|
||||||
|
|
||||||
|
(tabulate-string f size) = (string-unfold (lambda (i) (= i size)) f add1 0)
|
||||||
|
|
||||||
|
To map F over a list LIS, producing a string:
|
||||||
|
(string-unfold null? (compose f car) cdr lis)
|
||||||
|
|
||||||
|
string-tabulate proc len -> string
|
||||||
|
PROC is an integer->char procedure. Construct a string of size LEN
|
||||||
|
by applying PROC to each index to produce the corresponding string
|
||||||
|
element. The order in which PROC is applied to the indices is not
|
||||||
|
specified.
|
||||||
|
|
||||||
|
string-for-each proc s [start end] -> unspecified
|
||||||
|
string-iter proc s [start end] -> unspecified
|
||||||
|
Apply PROC to each character in S.
|
||||||
|
STRING-FOR-EACH has no specified iteration order.
|
||||||
|
STRING-ITER is required to iterate from START to END
|
||||||
|
in increasing order.
|
||||||
|
|
||||||
|
string-every? pred s [start end] -> boolean
|
||||||
|
string-any? pred s [start end] -> value
|
||||||
|
Note: no sequence order specified.
|
||||||
|
Checks to see if predicate PRED is true of every / any character in S.
|
||||||
|
STRING-ANY? is witness-generating -- it applies PRED to the elements
|
||||||
|
of S, returning the first true value it finds, otherwise false.
|
||||||
|
|
||||||
|
string-compare s1 s2 lt-proc eq-proc gt-proc -> values
|
||||||
|
string-compare-ci s1 s2 lt-proc eq-proc gt-proc -> values
|
||||||
|
Apply LT-PROC, EQ-PROC, GT-PROC to the mismatch index, depending
|
||||||
|
upon whether S1 is less than, equal to, or greater than S2.
|
||||||
|
The "mismatch index" is the largest index i such that for
|
||||||
|
every 0 <= j < i, s1[j] = s2[j] -- that is, I is the first
|
||||||
|
position that doesn't match. If S1 = S2, the mismatch index
|
||||||
|
is simply the length of the strings; we observe the protocol
|
||||||
|
in this redundant case for uniformity.
|
||||||
|
|
||||||
|
substring-compare s1 start1 end1 s2 start2 end2 lt-proc eq-proc gt-proc -> values
|
||||||
|
substring-compare-ci s1 start1 end1 s2 start2 end2 lt-proc eq-proc gt-proc -> values
|
||||||
|
The continuation procedures are applied to S1's mismatch index (as defined
|
||||||
|
above). In the case of EQ-PROC, this is always END1.
|
||||||
|
|
||||||
|
string= s1 s2 -> #f or integer
|
||||||
|
string<> s1 s2 -> #f or integer
|
||||||
|
string< s1 s2 -> #f or integer
|
||||||
|
string> s1 s2 -> #f or integer
|
||||||
|
string<= s1 s2 -> #f or integer
|
||||||
|
string>= s1 s2 -> #f or integer
|
||||||
|
If the comparison operation is true, the function returns the
|
||||||
|
mismatch index (as defined for the previous comparator functions).
|
||||||
|
|
||||||
|
string-ci= s1 s2 -> #f or integer
|
||||||
|
string-ci<> s1 s2 -> #f or integer
|
||||||
|
string-ci< s1 s2 -> #f or integer
|
||||||
|
string-ci> s1 s2 -> #f or integer
|
||||||
|
string-ci<= s1 s2 -> #f or integer
|
||||||
|
string-ci>= s1 s2 -> #f or integer
|
||||||
|
Case-insensitive variants.
|
||||||
|
|
||||||
|
substring= s1 start1 end1 s2 start2 end2 -> #f or integer
|
||||||
|
substring<> s1 start1 end1 s2 start2 end2 -> #f or integer
|
||||||
|
substring< s1 start1 end1 s2 start2 end2 -> #f or integer
|
||||||
|
substring> s1 start1 end1 s2 start2 end2 -> #f or integer
|
||||||
|
substring<= s1 start1 end1 s2 start2 end2 -> #f or integer
|
||||||
|
substring>= s1 start1 end1 s2 start2 end2 -> #f or integer
|
||||||
|
|
||||||
|
substring-ci= s1 start1 end1 s2 start2 end2 -> #f or integer
|
||||||
|
substring-ci<> s1 start1 end1 s2 start2 end2 -> #f or integer
|
||||||
|
substring-ci< s1 start1 end1 s2 start2 end2 -> #f or integer
|
||||||
|
substring-ci> s1 start1 end1 s2 start2 end2 -> #f or integer
|
||||||
|
substring-ci<= s1 start1 end1 s2 start2 end2 -> #f or integer
|
||||||
|
substring-ci>= s1 start1 end1 s2 start2 end2 -> #f or integer
|
||||||
|
These variants restrict the comparison to the indicated
|
||||||
|
substrings of S1 and S2.
|
||||||
|
|
||||||
|
string-upper-case? s [start end] -> boolean
|
||||||
|
string-lower-case? s [start end] -> boolean
|
||||||
|
STRING-UPPER-CASE? returns true iff the string contains
|
||||||
|
no lower-case characters. STRING-LOWER-CASE returns true
|
||||||
|
iff the string contains no upper-case characters.
|
||||||
|
(string-upper-case? "") => #t
|
||||||
|
(string-lower-case? "") => #t
|
||||||
|
(string-upper-case? "FOOb") => #f
|
||||||
|
(string-upper-case? "U.S.A.") => #t
|
||||||
|
|
||||||
|
capitalize-string s [start end] -> string
|
||||||
|
capitalize-string! s [start end] -> unspecified
|
||||||
|
Capitalize the string: upcase the first alphanumeric character,
|
||||||
|
and downcase the rest of the string. CAPITALIZE-STRING returns
|
||||||
|
a freshly allocated string.
|
||||||
|
|
||||||
|
(capitalize-string "--capitalize tHIS sentence.") =>
|
||||||
|
"--Capitalize this sentence."
|
||||||
|
|
||||||
|
(capitalize-string "see Spot run. see Nix run.") =>
|
||||||
|
"See spot run. see nix run."
|
||||||
|
|
||||||
|
(capitalize-string "3com makes routers.") =>
|
||||||
|
"3com makes routers."
|
||||||
|
|
||||||
|
capitalize-words s [start end] -> string
|
||||||
|
capitalize-words! s [start end] -> unspecified
|
||||||
|
A "word" is a maximal contiguous sequence of alphanumeric characters.
|
||||||
|
Upcase the first character of every word; downcase the rest of the word.
|
||||||
|
CAPITALIZE-WORDS returns a freshly allocated string.
|
||||||
|
|
||||||
|
(capitalize-words "HELLO, 3THErE, my nAME IS olin") =>
|
||||||
|
"Hello, 3there, My Name Is Olin"
|
||||||
|
|
||||||
|
More sophisticated capitalisation procedures can be synthesized
|
||||||
|
using CAPITALIZE-STRING and pattern matchers. In this context,
|
||||||
|
the REGEXP-SUBSTITUTE/GLOBAL procedure may be useful for picking
|
||||||
|
out the units to be capitalised and applying CAPITALIZE-STRING to
|
||||||
|
their components.
|
||||||
|
|
||||||
|
string-upcase s [start end] -> string
|
||||||
|
string-upcase! s [start end] -> unspecified
|
||||||
|
string-downcase s [start end] -> string
|
||||||
|
string-downcase! s [start end] -> unspecified
|
||||||
|
Raise or lower the case of the alphabetic characters in the string.
|
||||||
|
STRING-UPCASE and STRING-DOWNCASE return freshly allocated strings.
|
||||||
|
|
||||||
|
string-take s nchars -> string
|
||||||
|
string-drop s nchars -> string
|
||||||
|
string-take-right s nchars -> string
|
||||||
|
string-drop-right s nchars -> string
|
||||||
|
STRING-TAKE returns the first NCHARS of STRING;
|
||||||
|
STRING-DROP returns all but the first NCHARS of STRING.
|
||||||
|
STRING-TAKE-RIGHT returns the last NCHARS of STRING;
|
||||||
|
STRING-DROP-RIGHT returns all but the last NCHARS of STRING.
|
||||||
|
These generalise MIT Scheme's HEAD & TAIL functions.
|
||||||
|
If these procedures produce the entire string, they may return either
|
||||||
|
S or a copy of S; in some implementations, proper substrings may share
|
||||||
|
memory with S.
|
||||||
|
|
||||||
|
string-pad s k [char start end] -> string
|
||||||
|
string-pad-right s k [char start end] -> string
|
||||||
|
Build a string of length K comprised of S padded on the left (right)
|
||||||
|
by as many occurences of the character CHAR as needed. If S has more
|
||||||
|
than K chars, it is truncated on the left (right) to length k. CHAR
|
||||||
|
defaults to #\space.
|
||||||
|
|
||||||
|
If K is exactly the length of S, these functions may return
|
||||||
|
either S or a copy of S.
|
||||||
|
|
||||||
|
string-trim s [char/char-set/pred start end] -> string
|
||||||
|
string-trim-right s [char/char-set/pred start end] -> string
|
||||||
|
string-trim-both s [char/char-set/pred start end] -> string
|
||||||
|
Trim S by skipping over all characters on the left / on the right /
|
||||||
|
on both sides that satisfy the second parameter CHAR/CHAR-SET/PRED:
|
||||||
|
- If it is a character CHAR, characters equal to CHAR are trimmed.
|
||||||
|
- If it is a char set CHAR-SET, characters contained in CHAR-SET
|
||||||
|
are trimmed.
|
||||||
|
- If it is a predicate PRED, it is a test predicate that is applied
|
||||||
|
to the characters in S; a character causing it to return true
|
||||||
|
is skipped.
|
||||||
|
CHAR/CHAR/SET-PRED defaults to CHAR-SET:WHITESPACE.
|
||||||
|
|
||||||
|
If no trimming occurs, these functions may return either S or a copy of S;
|
||||||
|
in some implementations, proper substrings may share memory with S.
|
||||||
|
|
||||||
|
(string-trim-both " The outlook wasn't brilliant, \n\r")
|
||||||
|
=> "The outlook wasn't brilliant,"
|
||||||
|
|
||||||
|
string-filter s char/char-set/pred [start end] -> string
|
||||||
|
string-delete s char/char-set/pred [start end] -> string
|
||||||
|
Filter the string S, retaining only those characters that
|
||||||
|
satisfy / do not satisfy the CHAR/CHAR-SET/PRED argument. If
|
||||||
|
this argument is a procedure, it is applied to the character
|
||||||
|
as a predicate; if it is a char-set, the character is tested
|
||||||
|
for membership; if it is a character, it is used in an equality test.
|
||||||
|
|
||||||
|
If the string is unaltered by the filtering operation, these
|
||||||
|
functions may return either S or a copy of S.
|
||||||
|
|
||||||
|
string-index s char/char-set/pred [start end] -> integer or #f
|
||||||
|
string-index-right s char/char-set/pred [end start] -> integer or #f
|
||||||
|
string-skip s char/char-set/pred [start end] -> integer or #f
|
||||||
|
string-skip-right s char/char-set/pred [end start] -> integer or #f
|
||||||
|
Note the inverted start/end ordering of index-right and skip-right's
|
||||||
|
parameters.
|
||||||
|
|
||||||
|
Index (index-right) searches through the string from the left (right),
|
||||||
|
returning the index of the first occurence of a character which
|
||||||
|
- equals CHAR/CHAR-SET/PRED (if it is a character);
|
||||||
|
- is in CHAR/CHAR-SET/PRED (if it is a char-set);
|
||||||
|
- satisfies the predicate CHAR/CHAR-SET/PRED (if it is a procedure).
|
||||||
|
If no match is found, the functions return false.
|
||||||
|
|
||||||
|
The skip functions are similar, but use the complement of the criteria:
|
||||||
|
they search for the first char that *doesn't* satisfy the test. E.g.,
|
||||||
|
to skip over initial whitespace, say
|
||||||
|
(cond ((string-skip s char-set:whitespace) =>
|
||||||
|
(lambda (i)
|
||||||
|
;; (string-ref s i) is not whitespace.
|
||||||
|
...)))
|
||||||
|
|
||||||
|
string-prefix-count s1 s2 -> integer
|
||||||
|
string-suffix-count s1 s2 -> integer
|
||||||
|
string-prefix-count-ci s1 s2 -> integer
|
||||||
|
string-suffix-count-ci s1 s2 -> integer
|
||||||
|
Return the length of the longest common prefix/suffix of the two strings.
|
||||||
|
This is equivalent to the "mismatch index" for the strings.
|
||||||
|
|
||||||
|
substring-prefix-count s1 start1 end1 s2 start2 end2 -> integer
|
||||||
|
substring-suffix-count s1 start1 end1 s2 start2 end2 -> integer
|
||||||
|
substring-prefix-count-ci s1 start1 end1 s2 start2 end2 -> integer
|
||||||
|
substring-suffix-count-ci s1 start1 end1 s2 start2 end2 -> integer
|
||||||
|
Substring variants.
|
||||||
|
|
||||||
|
string-prefix? s1 s2 -> boolean
|
||||||
|
string-suffix? s1 s2 -> boolean
|
||||||
|
string-prefix-ci? s1 s2 -> boolean
|
||||||
|
string-suffix-ci? s1 s2 -> boolean
|
||||||
|
Is S1 a prefix/suffix of S2?
|
||||||
|
|
||||||
|
substring-prefix? s1 start1 end1 s2 start2 end2 -> boolean
|
||||||
|
substring-suffix? s1 start1 end1 s2 start2 end2 -> boolean
|
||||||
|
substring-prefix-ci? s1 start1 end1 s2 start2 end2 -> boolean
|
||||||
|
substring-suffix-ci? s1 start1 end1 s2 start2 end2 -> boolean
|
||||||
|
Substring variants.
|
||||||
|
|
||||||
|
substring? s1 s2 [start end] -> integer or false
|
||||||
|
substring-ci? s1 s2 [start end] -> integer or false
|
||||||
|
Return the index in S2 where S1 occurs as a substring, or false.
|
||||||
|
The returned index is in the range [start,end).
|
||||||
|
The current implementation uses the Knuth-Morris-Pratt algorithm.
|
||||||
|
|
||||||
|
string-fill! s char [start end] -> unspecified
|
||||||
|
Store CHAR into the elements of S.
|
||||||
|
This is the R4RS procedure extended to have optional START/END parameters.
|
||||||
|
|
||||||
|
string-copy! target tstart s [start end] -> unspecified
|
||||||
|
Copy the sequence of characters from index range [START,END) in
|
||||||
|
string S to string TARGET, beginning at index TSTART. The characters
|
||||||
|
are copied left-to-right or right-to-left as needed -- the copy is
|
||||||
|
guaranteed to work, even if TARGET and S are the same string.
|
||||||
|
|
||||||
|
substring s start [end] -> string
|
||||||
|
string-copy s [start end] -> string
|
||||||
|
These R4RS procedures are extended to have optional START/END parameters.
|
||||||
|
Use STRING-COPY when you want to indicate explicitly in your code that you
|
||||||
|
wish to allocate new storage; use SUBSTRING when you don't care if you
|
||||||
|
get a fresh copy or share storage with the original string.
|
||||||
|
E.g.:
|
||||||
|
(string-copy "Beta substitution") => "Beta substitution"
|
||||||
|
(string-copy "Beta substitution" 1 10)
|
||||||
|
=> "eta subst"
|
||||||
|
(string-copy "Beta substitution" 5) => "substitution"
|
||||||
|
|
||||||
|
SUBSTRING may return a value with shares memory with S.
|
||||||
|
|
||||||
|
string-reverse s [start end] -> string
|
||||||
|
string-reverse! s [start end] -> unspecific
|
||||||
|
Reverse the string.
|
||||||
|
|
||||||
|
reverse-list->string char-list -> string
|
||||||
|
An efficient implementation of (compose string->list reverse):
|
||||||
|
(reverse-list->string '(#\a #\B #\c)) -> "cBa"
|
||||||
|
This is a common idiom in the epilog of string-processing loops
|
||||||
|
that accumulate an answer in a reverse-order list.
|
||||||
|
|
||||||
|
string-concat string-list -> string
|
||||||
|
Append the elements of STRING-LIST together into a single list.
|
||||||
|
Guaranteed to return a freshly allocated list. Appears sufficiently
|
||||||
|
often as to warrant being named.
|
||||||
|
|
||||||
|
string-concat/shared string-list -> string
|
||||||
|
string-append/shared s ... -> string
|
||||||
|
These two procedures are variants of STRING-CONCAT and STRING-APPEND
|
||||||
|
that are permitted to return results that share storage with their
|
||||||
|
parameters. In particular, if STRING-APPEND/SHARED is applied to just
|
||||||
|
one argument, it may return exactly that argument, whereas STRING-APPEND
|
||||||
|
is required to allocate a fresh string.
|
||||||
|
|
||||||
|
string->list s [start end] -> char-list
|
||||||
|
The R5RS STRING->LIST procedure is extended to take optional START/END
|
||||||
|
arguments.
|
||||||
|
|
||||||
|
string-null? s -> bool
|
||||||
|
Is S the empty string?
|
||||||
|
|
||||||
|
xsubstring s from [to start end] -> string
|
||||||
|
This is the "extended substring" procedure that implements replicated
|
||||||
|
copying of a substring of some string.
|
||||||
|
|
||||||
|
S is a string; START and END are optional arguments that demarcate
|
||||||
|
a substring of S, defaulting to 0 and the length of S (e.g., the whole
|
||||||
|
string). Replicate this substring up and down index space, in both the
|
||||||
|
positive and negative directions. For example, if S = "abcdefg", START=3,
|
||||||
|
and END=6, then we have the conceptual bidirectionally-infinite string
|
||||||
|
... d e f d e f d e f d e f d e f d e f d e f ...
|
||||||
|
... -9 -8 -7 -6 -5 -4 -3 -2 -1 0 1 2 3 4 5 6 7 8 9 ...
|
||||||
|
XSUBSTRING returns the substring of this string beginning at index FROM,
|
||||||
|
and ending at TO (which defaults to FROM+(END-START)).
|
||||||
|
|
||||||
|
You can use XSUBSTRING to perform a variety of tasks:
|
||||||
|
- To rotate a string left: (xsubstring "abcdef" 2) => "cdefab"
|
||||||
|
- To rotate a string right: (xsubstring "abcdef" -2) => "efabcd"
|
||||||
|
- To replicate a string: (xsubstring "abc" 0 7) => "abcabca"
|
||||||
|
|
||||||
|
Note that
|
||||||
|
- The FROM/TO indices give a half-open range -- the characters from
|
||||||
|
index FROM up to, but not including, index TO.
|
||||||
|
- The FROM/TO indices are not in terms of the index space for string S.
|
||||||
|
They are in terms of the replicated index space of the substring
|
||||||
|
defined by S, START, and END.
|
||||||
|
|
||||||
|
It is an error if START=END -- although this is allowed by special
|
||||||
|
dispensation when FROM=TO.
|
||||||
|
|
||||||
|
string-xcopy! target tstart s sfrom [sto start end] -> unspecific
|
||||||
|
Exactly the same as XSUBSTRING, but the extracted text is written
|
||||||
|
into the string TARGET starting at index TSTART.
|
||||||
|
This operation is not defined if (EQ? TARGET S) -- you cannot copy
|
||||||
|
a string on top of itself.
|
||||||
|
|
||||||
|
|
||||||
|
* Lower-level procedures
|
||||||
|
|
||||||
|
The following procedures are useful for writing other string-processing
|
||||||
|
functions, and are contained in the string-lib-internals package.
|
||||||
|
|
||||||
|
parse-start+end proc s args -> [start end rest]
|
||||||
|
parse-final-start+end proc s args -> [start end]
|
||||||
|
PARSE-START+END may be used to parse a pair of optional START/END arguments
|
||||||
|
from an argument list, defaulting them to 0 and the length of some string
|
||||||
|
S, respectively. Let the length of string S be SLEN.
|
||||||
|
- If ARGS = (), the function returns (values 0 slen '())
|
||||||
|
- If ARGS = (i), I is checked to ensure it is an integer, and
|
||||||
|
that 0 <= i <= slen. Returns (values i slen (cdr rest)).
|
||||||
|
- If ARGS = (i j ...), I and J are checked to ensure they are
|
||||||
|
integers, and that 0 <= i <= j <= slen. Returns (values i j (cddr rest)).
|
||||||
|
If any of the checks fail, an error condition is raised, and PROC is used
|
||||||
|
as part of the error condition -- it should be the name of the client
|
||||||
|
procedure whose argument list PARSE-START+END is parsing.
|
||||||
|
|
||||||
|
parse-final-start+end is exactly the same, except that the args list
|
||||||
|
passed to it is required to be of length two or less; if it is longer,
|
||||||
|
an error condition is raised. It may be used when the optional START/END
|
||||||
|
parameters are final arguments to the procedure.
|
||||||
|
|
||||||
|
check-substring-spec proc s start end -> unspecific
|
||||||
|
Check values START and END to ensure they specify a valid substring
|
||||||
|
in S. This means that START and END are exact integers, and
|
||||||
|
0 <= START <= END <= (STRING-LENGTH S)
|
||||||
|
If this is not the case, an error condition is raised. PROC is used
|
||||||
|
as part of error condition, and should be the procedure whose START/END
|
||||||
|
parameters we are checking.
|
||||||
|
|
||||||
|
make-kmp-restart-vector s c= -> vector
|
||||||
|
Build the Knuth-Morris-Pratt "restart vector," which is useful
|
||||||
|
for quickly searching character sequences for the occurrence of
|
||||||
|
string S. C= is a character-equality function used to construct
|
||||||
|
the restart vector; it is usefully CHAR=? or CHAR-CI=?.
|
||||||
|
|
||||||
|
The definition of the restart vector RV for string S is:
|
||||||
|
If we have matched chars 0..i-1 of S against some search string SS, and
|
||||||
|
S[i] doesn't match SS[k], then reset i := RV[i], and try again to
|
||||||
|
match SS[k]. If RV[i] = -1, then punt SS[k] completely, and move on to
|
||||||
|
SS[k+1] and S[0].
|
||||||
|
|
||||||
|
In other words, if you have matched the first i chars of S, but
|
||||||
|
the i+1'th char doesn't match, RV[i] tells you what the next-longest
|
||||||
|
prefix of PATTERN is that you have matched.
|
||||||
|
|
||||||
|
The following string-search function shows how a restart vector
|
||||||
|
is used to search. It can be easily adapted to search other character
|
||||||
|
sequences (such as ports).
|
||||||
|
|
||||||
|
(define (find-substring pattern source start end)
|
||||||
|
(let ((plen (string-length pattern))
|
||||||
|
(rv (make-kmp-restart-vector pattern char=?)))
|
||||||
|
|
||||||
|
;; The search loop. SJ & PJ are redundant state.
|
||||||
|
(let lp ((si start) (pi 0)
|
||||||
|
(sj (- end start)) ; (- end si) -- how many chars left.
|
||||||
|
(pj plen)) ; (- plen pi) -- how many chars left.
|
||||||
|
|
||||||
|
(if (= pi plen) (- si plen) ; Win.
|
||||||
|
|
||||||
|
(and (<= pj sj) ; Lose.
|
||||||
|
|
||||||
|
(if (char=? (string-ref source si) ; Search.
|
||||||
|
(string-ref pattern pi))
|
||||||
|
(lp (+ 1 si) (+ 1 pi) (- sj 1) (- pj 1)) ; Advance.
|
||||||
|
|
||||||
|
(let ((pi (vector-ref rv pi))) ; Retreat.
|
||||||
|
(if (= pi -1)
|
||||||
|
(lp (+ si 1) 0 (- sj 1) plen) ; Punt.
|
||||||
|
(lp si pi sj (- plen pi))))))))))
|
|
@ -80,23 +80,9 @@
|
||||||
(set-socket-option sock level/socket socket/reuse-address #t)
|
(set-socket-option sock level/socket socket/reuse-address #t)
|
||||||
(bind-socket sock addr)
|
(bind-socket sock addr)
|
||||||
(listen-socket sock 5)
|
(listen-socket sock 5)
|
||||||
(with-handler
|
|
||||||
(lambda (condition more)
|
|
||||||
(with-handler
|
|
||||||
(lambda (condition ignore) (more))
|
|
||||||
(lambda () (close-socket sock)))
|
|
||||||
(more))
|
|
||||||
(lambda ()
|
|
||||||
(let loop ()
|
(let loop ()
|
||||||
(with-errno-handler
|
(call-with-values (lambda () (accept-connection sock)) proc)
|
||||||
;; ECONNABORTED we just ignore
|
(loop))))
|
||||||
((errno packet)
|
|
||||||
((errno/connaborted) (loop)))
|
|
||||||
(call-with-values
|
|
||||||
(lambda () (accept-connection sock))
|
|
||||||
proc)
|
|
||||||
(loop)))))))
|
|
||||||
|
|
||||||
|
|
||||||
;;;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
|
;;;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
|
||||||
;;; Socket Record Structure
|
;;; Socket Record Structure
|
||||||
|
@ -421,9 +407,8 @@
|
||||||
reader sockfd flags
|
reader sockfd flags
|
||||||
s start end from))
|
s start end from))
|
||||||
(let ((addr (make-addr from)))
|
(let ((addr (make-addr from)))
|
||||||
(let loop ((i start) (remote #f))
|
(let loop ((i start))
|
||||||
(if (>= i end)
|
(if (>= i end) (- i start)
|
||||||
(values (- i start) remote)
|
|
||||||
(receive (err nread)
|
(receive (err nread)
|
||||||
(reader sockfd flags s i end addr)
|
(reader sockfd flags s i end addr)
|
||||||
(cond (err (if (= err errno/intr) (loop i)
|
(cond (err (if (= err errno/intr) (loop i)
|
||||||
|
@ -436,7 +421,7 @@
|
||||||
(let ((result (- i start)))
|
(let ((result (- i start)))
|
||||||
(and (not (zero? result)) result))
|
(and (not (zero? result)) result))
|
||||||
from))
|
from))
|
||||||
(else (loop (+ i nread) from))))))))
|
(else (loop (+ i nread)))))))))
|
||||||
|
|
||||||
(define (receive-message/partial socket len . maybe-flags)
|
(define (receive-message/partial socket len . maybe-flags)
|
||||||
(let ((flags (:optional maybe-flags 0)))
|
(let ((flags (:optional maybe-flags 0)))
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
/* Make sure our exports match up w/the implementation: */
|
/* Make sure our exports match up w/the implementation: */
|
||||||
#include "network1.h"
|
#include "network1.h"
|
||||||
|
|
||||||
#if !defined(__CYGWIN__) && !defined(_AIX)
|
#ifndef __CYGWIN__
|
||||||
extern int h_errno;
|
extern int h_errno;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -43,8 +43,6 @@ int scheme_bind(int sockfd, int family, scheme_value scheme_name)
|
||||||
struct sockaddr_un name;
|
struct sockaddr_un name;
|
||||||
int scheme_length=STRING_LENGTH(scheme_name);
|
int scheme_length=STRING_LENGTH(scheme_name);
|
||||||
|
|
||||||
memset(&name, 0, sizeof(name));
|
|
||||||
|
|
||||||
name.sun_family=AF_UNIX;
|
name.sun_family=AF_UNIX;
|
||||||
if (scheme_length>=(108-1)) /* save space for \0 */
|
if (scheme_length>=(108-1)) /* save space for \0 */
|
||||||
return(-1);
|
return(-1);
|
||||||
|
@ -62,9 +60,6 @@ int scheme_bind(int sockfd, int family, scheme_value scheme_name)
|
||||||
|
|
||||||
u_long addr=GET_LONG(scheme_name,0);
|
u_long addr=GET_LONG(scheme_name,0);
|
||||||
u_short port=htons((u_short)ntohl(GET_LONG(scheme_name,1)));
|
u_short port=htons((u_short)ntohl(GET_LONG(scheme_name,1)));
|
||||||
|
|
||||||
memset(&name, 0, sizeof(name));
|
|
||||||
|
|
||||||
name.sin_family=AF_INET;
|
name.sin_family=AF_INET;
|
||||||
name.sin_addr.s_addr=addr;
|
name.sin_addr.s_addr=addr;
|
||||||
name.sin_port=port;
|
name.sin_port=port;
|
||||||
|
@ -87,8 +82,6 @@ int scheme_connect(int sockfd, int family, scheme_value scheme_name)
|
||||||
struct sockaddr_un name;
|
struct sockaddr_un name;
|
||||||
int scheme_length=STRING_LENGTH(scheme_name);
|
int scheme_length=STRING_LENGTH(scheme_name);
|
||||||
|
|
||||||
memset(&name, 0, sizeof(name));
|
|
||||||
|
|
||||||
name.sun_family=AF_UNIX;
|
name.sun_family=AF_UNIX;
|
||||||
if (scheme_length>=(108-1)) /* save space for \0 */
|
if (scheme_length>=(108-1)) /* save space for \0 */
|
||||||
return(-1);
|
return(-1);
|
||||||
|
@ -107,8 +100,6 @@ int scheme_connect(int sockfd, int family, scheme_value scheme_name)
|
||||||
u_long addr=GET_LONG(scheme_name,0);
|
u_long addr=GET_LONG(scheme_name,0);
|
||||||
u_short port=htons((u_short)ntohl(GET_LONG(scheme_name,1)));
|
u_short port=htons((u_short)ntohl(GET_LONG(scheme_name,1)));
|
||||||
|
|
||||||
memset(&name, 0, sizeof(name));
|
|
||||||
|
|
||||||
name.sin_family=AF_INET;
|
name.sin_family=AF_INET;
|
||||||
name.sin_addr.s_addr=addr;
|
name.sin_addr.s_addr=addr;
|
||||||
name.sin_port=port;
|
name.sin_port=port;
|
||||||
|
@ -279,8 +270,6 @@ int send_substring(int s,
|
||||||
struct sockaddr_un name;
|
struct sockaddr_un name;
|
||||||
int scheme_length=STRING_LENGTH(scheme_name);
|
int scheme_length=STRING_LENGTH(scheme_name);
|
||||||
|
|
||||||
memset(&name, 0, sizeof(name));
|
|
||||||
|
|
||||||
name.sun_family=AF_UNIX;
|
name.sun_family=AF_UNIX;
|
||||||
if (scheme_length>=(108-1)) /* save space for \0 */
|
if (scheme_length>=(108-1)) /* save space for \0 */
|
||||||
return(-1);
|
return(-1);
|
||||||
|
@ -300,9 +289,6 @@ int send_substring(int s,
|
||||||
struct sockaddr_in name;
|
struct sockaddr_in name;
|
||||||
u_long addr=GET_LONG(scheme_name,0);
|
u_long addr=GET_LONG(scheme_name,0);
|
||||||
u_short port=htons((u_short)ntohl(GET_LONG(scheme_name,1)));
|
u_short port=htons((u_short)ntohl(GET_LONG(scheme_name,1)));
|
||||||
|
|
||||||
memset(&name, 0, sizeof(name));
|
|
||||||
|
|
||||||
name.sin_family=AF_INET;
|
name.sin_family=AF_INET;
|
||||||
name.sin_addr.s_addr=addr;
|
name.sin_addr.s_addr=addr;
|
||||||
name.sin_port=port;
|
name.sin_port=port;
|
||||||
|
|
568
scsh/oldfr.scm
568
scsh/oldfr.scm
|
@ -1,568 +0,0 @@
|
||||||
;;; Field and record parsing utilities for scsh.
|
|
||||||
;;; Copyright (c) 1994 by Olin Shivers.
|
|
||||||
|
|
||||||
;;; Notes:
|
|
||||||
;;; - Comment on the dependencies here...
|
|
||||||
;;; - Redefine READ-LINE using READ-DELIMITED.
|
|
||||||
;;; - Awk should deal with case-insensitivity.
|
|
||||||
;;; - Should I change the field-splitters to return lists? It's the
|
|
||||||
;;; right thing, and costs nothing in terms of efficiency.
|
|
||||||
|
|
||||||
;;; Looping primitives:
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
||||||
;;; It is nicer for loops that loop over a bunch of different things
|
|
||||||
;;; if you can encapsulate the idea of iterating over a data structure
|
|
||||||
;;; with a
|
|
||||||
;;; (next-element state) -> elt next-state
|
|
||||||
;;; (more-elements? state) -? #t/#f
|
|
||||||
;;; generator/termination-test pair. You can use the generator with REDUCE
|
|
||||||
;;; to make a list; you can stick it into a loop macro to loop over the
|
|
||||||
;;; elements. For example, if we had an extensible Yale-loop style loop macro,
|
|
||||||
;;; we could have a loop clause like
|
|
||||||
;;;
|
|
||||||
;;; (loop (for field in-infix-delimited-string ":" path)
|
|
||||||
;;; (do (display field) (newline)))
|
|
||||||
;;;
|
|
||||||
;;; and it would be simple to expand this into code using the generator.
|
|
||||||
;;; With procedural inlining, you can get pretty optimal loops over data
|
|
||||||
;;; structures this way.
|
|
||||||
;;;
|
|
||||||
;;; As of now, you are forced to parse fields into a buffer, and loop
|
|
||||||
;;; over that. This is inefficient of time and space. If I ever manage to do
|
|
||||||
;;; an extensible loop macro for Scheme 48, I'll have to come back to this
|
|
||||||
;;; package and rethink how to provide this functionality.
|
|
||||||
|
|
||||||
;;; Forward-progress guarantees and empty string matches.
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
||||||
;;; A loop that pulls text off a string by matching a regexp against
|
|
||||||
;;; that string can conceivably get stuck in an infinite loop if the
|
|
||||||
;;; regexp matches the empty string. For example, the regexps
|
|
||||||
;;; ^, $, .*, foo|[^f]* can all match the empty string.
|
|
||||||
;;;
|
|
||||||
;;; The regexp-loop routines in this code are careful to handle this case.
|
|
||||||
;;; If a regexp matches the empty string, the next search starts, not from
|
|
||||||
;;; the end of the match (which in the empty string case is also the
|
|
||||||
;;; beginning -- there's the rub), but from the next character over.
|
|
||||||
;;; This is the correct behaviour. Regexps match the longest possible
|
|
||||||
;;; string at a given location, so if the regexp matched the empty string
|
|
||||||
;;; at location i, then it is guaranteed they could not have matched
|
|
||||||
;;; a longer pattern starting with character #i. So we can safely begin
|
|
||||||
;;; our search for the next match at char i+1.
|
|
||||||
;;;
|
|
||||||
;;; So every iteration through the loop makes some forward progress,
|
|
||||||
;;; and the loop is guaranteed to terminate.
|
|
||||||
;;;
|
|
||||||
;;; This has the effect you want with field parsing. For example, if you split
|
|
||||||
;;; a string with the empty pattern, you will explode the string into its
|
|
||||||
;;; individual characters:
|
|
||||||
;;; ((suffix-splitter "") "foo") -> #("" "f" "o" "o")
|
|
||||||
;;; However, even though this boundary case is handled correctly, we don't
|
|
||||||
;;; recommend using it. Say what you mean -- just use a field splitter:
|
|
||||||
;;; ((field-splitter ".") "foo") -> #("f" "o" "o")
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
;;; (join-strings string-list [delimiter grammar]) => string
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
||||||
;;; Paste strings together using the delimiter string.
|
|
||||||
;;;
|
|
||||||
;;; (join-strings '("foo" "bar" "baz") ":") => "foo:bar:baz"
|
|
||||||
;;;
|
|
||||||
;;; DELIMITER defaults to a single space " "
|
|
||||||
;;; GRAMMAR is one of the symbols {infix, suffix} and defaults to 'infix.
|
|
||||||
|
|
||||||
;;; (join-strings strings [delim grammar])
|
|
||||||
|
|
||||||
(define (join-strings strings . args)
|
|
||||||
(if (pair? strings)
|
|
||||||
(receive (delim grammar) (parse-optionals args " " 'infix)
|
|
||||||
(check-arg string? delim join-strings)
|
|
||||||
(let ((strings (reverse strings)))
|
|
||||||
(let lp ((strings (cdr strings))
|
|
||||||
(ans (case grammar
|
|
||||||
((infix) (list (car strings)))
|
|
||||||
((suffix) (list (car strings) delim))
|
|
||||||
(else (error "Illegal grammar" grammar)))))
|
|
||||||
(if (pair? strings)
|
|
||||||
(lp (cdr strings)
|
|
||||||
(cons (car strings) (cons delim ans)))
|
|
||||||
|
|
||||||
; All done
|
|
||||||
(apply string-append ans)))))
|
|
||||||
|
|
||||||
"")) ; Special-cased for infix grammar.
|
|
||||||
|
|
||||||
;;; FIELD PARSERS
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
||||||
;;; This section defines routines to split a string into fields.
|
|
||||||
;;; You can parse by specifying a pattern that *separates* fields,
|
|
||||||
;;; a pattern that *terminates* fields, or a pattern that *matches*
|
|
||||||
;;; fields.
|
|
||||||
|
|
||||||
(define (->delim-matcher x)
|
|
||||||
(if (procedure? x) x ; matcher proc
|
|
||||||
(let ((re (cond ((regexp? x) x) ; regexp pattern
|
|
||||||
((string? x) (make-regexp x)) ; regexp string
|
|
||||||
(else (error "Illegal pattern/parser" x)))))
|
|
||||||
|
|
||||||
;; The matcher proc.
|
|
||||||
(lambda (s i)
|
|
||||||
(cond ((regexp-exec re s i) =>
|
|
||||||
(lambda (m) (values (match:start m 0) (match:end m 0))))
|
|
||||||
(else (values #f #f)))))))
|
|
||||||
|
|
||||||
;;; (infix-splitter [re num-fields handle-delim]) -> parser
|
|
||||||
;;; (suffix-splitter [re num-fields handle-delim]) -> parser
|
|
||||||
;;; (sloppy-suffix-splitter [re num-fields handle-delim]) -> parser
|
|
||||||
;;; (field-splitter [re num-fields]) -> parser
|
|
||||||
;;;
|
|
||||||
;;; (parser string [start]) -> string-list
|
|
||||||
|
|
||||||
(define (make-field-parser-generator default-delim-matcher loop-proc)
|
|
||||||
;; This is the parser-generator
|
|
||||||
(lambda args
|
|
||||||
(receive (delim-spec num-fields handle-delim)
|
|
||||||
(parse-optionals args default-delim-matcher #f 'trim)
|
|
||||||
|
|
||||||
;; Process and error-check the args
|
|
||||||
(let ((match-delim (->delim-matcher delim-spec))
|
|
||||||
(cons-field (case handle-delim ; Field is s[i,j).
|
|
||||||
((trim) ; Delimiter is s[j,k).
|
|
||||||
(lambda (s i j k fields)
|
|
||||||
(cons (substring s i j) fields)))
|
|
||||||
((split)
|
|
||||||
(lambda (s i j k fields)
|
|
||||||
(cons (substring s j k)
|
|
||||||
(cons (substring s i j) fields))))
|
|
||||||
((concat)
|
|
||||||
(lambda (s i j k fields)
|
|
||||||
(cons (substring s i k)
|
|
||||||
fields)))
|
|
||||||
(else
|
|
||||||
(error "Illegal handle-delim spec"
|
|
||||||
handle-delim)))))
|
|
||||||
|
|
||||||
(receive (num-fields nfields-exact?)
|
|
||||||
(cond ((not num-fields) (values #f #f))
|
|
||||||
((not (integer? num-fields))
|
|
||||||
(error "Illegal NUM-FIELDS value" num-fields))
|
|
||||||
((<= num-fields 0) (values (- num-fields) #f))
|
|
||||||
(else (values num-fields #t)))
|
|
||||||
|
|
||||||
;; This is the parser.
|
|
||||||
(lambda (s . maybe-start)
|
|
||||||
(reverse (loop-proc s (optional-arg maybe-start 0)
|
|
||||||
match-delim cons-field
|
|
||||||
num-fields nfields-exact?))))))))
|
|
||||||
|
|
||||||
(define default-field-matcher (->delim-matcher "[^ \t\n]+"))
|
|
||||||
|
|
||||||
;;; (field-splitter [field-spec num-fields])
|
|
||||||
|
|
||||||
(define (field-splitter . args)
|
|
||||||
(receive (field-spec num-fields)
|
|
||||||
(parse-optionals args default-field-matcher #f)
|
|
||||||
|
|
||||||
;; Process and error-check the args
|
|
||||||
(let ((match-field (->delim-matcher field-spec)))
|
|
||||||
(receive (num-fields nfields-exact?)
|
|
||||||
(cond ((not num-fields) (values #f #f))
|
|
||||||
((not (integer? num-fields))
|
|
||||||
(error "Illegal NUM-FIELDS value"
|
|
||||||
field-splitter num-fields))
|
|
||||||
((<= num-fields 0) (values (- num-fields) #f))
|
|
||||||
(else (values num-fields #t)))
|
|
||||||
|
|
||||||
;; This is the parser procedure.
|
|
||||||
(lambda (s . maybe-start)
|
|
||||||
(reverse (fieldspec-field-loop s (optional-arg maybe-start 0)
|
|
||||||
match-field num-fields nfields-exact?)))))))
|
|
||||||
|
|
||||||
|
|
||||||
;;; These four procedures implement the guts of each parser
|
|
||||||
;;; (field, infix, suffix, and sloppy-suffix).
|
|
||||||
;;;
|
|
||||||
;;; The CONS-FIELD argument is a procedure that parameterises the
|
|
||||||
;;; HANDLE-DELIM action for the field parser.
|
|
||||||
;;;
|
|
||||||
;;; The MATCH-DELIM argument is used to match a delimiter.
|
|
||||||
;;; (MATCH-DELIM S I) returns two integers [start, end] marking
|
|
||||||
;;; the next delimiter after index I in string S. If no delimiter is
|
|
||||||
;;; found, it returns [#f #f].
|
|
||||||
|
|
||||||
;;; In the main loop of each parser, the loop variable LAST-NULL? tells if the
|
|
||||||
;;; previous delimiter-match matched the empty string. If it did, we start our
|
|
||||||
;;; next delimiter search one character to the right of the match, so we won't
|
|
||||||
;;; loop forever. This means that an empty delimiter regexp "" simply splits
|
|
||||||
;;; the string at each character, which is the correct thing to do.
|
|
||||||
;;;
|
|
||||||
;;; These routines return the answer as a reversed list.
|
|
||||||
|
|
||||||
|
|
||||||
(define (fieldspec-field-loop s start match-field num-fields nfields-exact?)
|
|
||||||
(let ((end (string-length s)))
|
|
||||||
(let lp ((i start) (nfields 0) (fields '()) (last-null? #f))
|
|
||||||
(let ((j (if last-null? (+ i 1) i)) ; Where to start next delim search.
|
|
||||||
|
|
||||||
;; Check to see if we made our quota before returning answer.
|
|
||||||
(finish-up (lambda ()
|
|
||||||
(if (and num-fields (< nfields num-fields))
|
|
||||||
(error "Too few fields in record." num-fields s)
|
|
||||||
fields))))
|
|
||||||
|
|
||||||
(cond ((> j end) (finish-up)) ; We are done. Finish up.
|
|
||||||
|
|
||||||
;; Read too many fields. Bomb out.
|
|
||||||
((and nfields-exact? (> nfields num-fields))
|
|
||||||
(error "Too many fields in record." num-fields s))
|
|
||||||
|
|
||||||
;; Made our lower-bound quota. Quit early.
|
|
||||||
((and num-fields (= nfields num-fields) (not nfields-exact?))
|
|
||||||
(if (= i end) fields ; Special case hackery.
|
|
||||||
(cons (substring s i end) fields)))
|
|
||||||
|
|
||||||
;; Match off another field & loop.
|
|
||||||
(else (receive (m0 m1) (match-field s j)
|
|
||||||
(if m0 (lp m1 (+ nfields 1)
|
|
||||||
(cons (substring s m0 m1) fields)
|
|
||||||
(= m0 m1))
|
|
||||||
(finish-up))))))))) ; No more matches. Finish up.
|
|
||||||
|
|
||||||
|
|
||||||
(define (infix-field-loop s start match-delim cons-field
|
|
||||||
num-fields nfields-exact?)
|
|
||||||
(let ((end (string-length s)))
|
|
||||||
(if (= start end) '() ; Specially hack empty string.
|
|
||||||
|
|
||||||
(let lp ((i start) (nfields 0) (fields '()) (last-null? #f))
|
|
||||||
(let ((finish-up (lambda ()
|
|
||||||
;; s[i,end) is the last field. Terminate the loop.
|
|
||||||
(cond ((and num-fields (< (+ nfields 1) num-fields))
|
|
||||||
(error "Too few fields in record."
|
|
||||||
num-fields s))
|
|
||||||
|
|
||||||
((and nfields-exact?
|
|
||||||
(>= nfields num-fields))
|
|
||||||
(error "Too many fields in record."
|
|
||||||
num-fields s))
|
|
||||||
|
|
||||||
(else
|
|
||||||
(cons (substring s i end) fields)))))
|
|
||||||
|
|
||||||
(j (if last-null? (+ i 1) i))) ; Where to start next search.
|
|
||||||
|
|
||||||
(cond
|
|
||||||
;; If we've read NUM-FIELDS fields, quit early .
|
|
||||||
((and num-fields (= nfields num-fields))
|
|
||||||
(if nfields-exact?
|
|
||||||
(error "Too many fields in record." num-fields s)
|
|
||||||
(cons (substring s i end) fields)))
|
|
||||||
|
|
||||||
|
|
||||||
((<= j end) ; Match off another field.
|
|
||||||
(receive (m0 m1) (match-delim s j)
|
|
||||||
(if m0
|
|
||||||
(lp m1 (+ nfields 1)
|
|
||||||
(cons-field s i m0 m1 fields)
|
|
||||||
(= m0 m1))
|
|
||||||
(finish-up)))) ; No more delimiters - finish up.
|
|
||||||
|
|
||||||
;; We've run off the end of the string. This is a weird
|
|
||||||
;; boundary case occuring with empty-string delimiters.
|
|
||||||
(else (finish-up))))))))
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
;;; Match off an optional initial delimiter,
|
|
||||||
;;; then jump off to the suffix parser.
|
|
||||||
|
|
||||||
(define (sloppy-suffix-field-loop s start match-delim cons-field
|
|
||||||
num-fields nfields-exact?)
|
|
||||||
;; If sloppy-suffix, skip an initial delimiter if it's there.
|
|
||||||
(let ((start (receive (i j) (match-delim s start)
|
|
||||||
(if (and i (zero? i)) j start))))
|
|
||||||
(suffix-field-loop s start match-delim cons-field
|
|
||||||
num-fields nfields-exact?)))
|
|
||||||
|
|
||||||
|
|
||||||
(define (suffix-field-loop s start match-delim cons-field
|
|
||||||
num-fields nfields-exact?)
|
|
||||||
(let ((end (string-length s)))
|
|
||||||
|
|
||||||
(let lp ((i start) (nfields 0) (fields '()) (last-null? #f))
|
|
||||||
(let ((j (if last-null? (+ i 1) i))) ; Where to start next delim search.
|
|
||||||
(cond ((= i end) ; We are done.
|
|
||||||
(if (and num-fields (< nfields num-fields)) ; Didn't make quota.
|
|
||||||
(error "Too few fields in record." num-fields s)
|
|
||||||
fields))
|
|
||||||
|
|
||||||
;; Read too many fields. Bomb out.
|
|
||||||
((and nfields-exact? (= nfields num-fields))
|
|
||||||
(error "Too many fields in record." num-fields s))
|
|
||||||
|
|
||||||
;; Made our lower-bound quota. Quit early.
|
|
||||||
((and num-fields (= nfields num-fields) (not nfields-exact?))
|
|
||||||
(cons (substring s i end) fields))
|
|
||||||
|
|
||||||
(else ; Match off another field.
|
|
||||||
(receive (m0 m1) (match-delim s j)
|
|
||||||
(if m0 (lp m1 (+ nfields 1)
|
|
||||||
(cons-field s i m0 m1 fields)
|
|
||||||
(= m0 m1))
|
|
||||||
(error "Missing field terminator" s)))))))))
|
|
||||||
|
|
||||||
|
|
||||||
;;; Now, build the exported procedures: {infix,suffix,sloppy-suffix}-splitter.
|
|
||||||
|
|
||||||
(define default-suffix-matcher (->delim-matcher "[ \t\n]+|$"))
|
|
||||||
(define default-infix-matcher (->delim-matcher "[ \t\n]+"))
|
|
||||||
|
|
||||||
(define infix-splitter
|
|
||||||
(make-field-parser-generator default-infix-matcher infix-field-loop))
|
|
||||||
(define suffix-splitter
|
|
||||||
(make-field-parser-generator default-suffix-matcher suffix-field-loop))
|
|
||||||
(define sloppy-suffix-splitter
|
|
||||||
(make-field-parser-generator default-suffix-matcher sloppy-suffix-field-loop))
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
;;; Delimited readers
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
||||||
;;; We repeatedly allocate a buffer and fill it with READ-DELIMITED!
|
|
||||||
;;; until we hit a delimiter or EOF. Each time through the loop, we
|
|
||||||
;;; double the total buffer space, so the loop terminates with a log
|
|
||||||
;;; number of reads, but uses at most double the optimal buffer space.
|
|
||||||
|
|
||||||
(define (read-delimited delims . maybe-port)
|
|
||||||
(let ((smart-substring (lambda (s end)
|
|
||||||
(if (= end (string-length s)) s
|
|
||||||
(substring s 0 end))))
|
|
||||||
(delims (->char-set delims)))
|
|
||||||
|
|
||||||
;; BUFLEN is total amount of buffer space allocated to date.
|
|
||||||
(let lp ((strs '()) (buflen 80) (buf (make-string 80)))
|
|
||||||
(cond ((apply read-delimited! delims buf maybe-port) =>
|
|
||||||
(lambda (i)
|
|
||||||
(if (null? strs) ; Gratuitous optimisation.
|
|
||||||
(smart-substring buf i)
|
|
||||||
(apply string-append
|
|
||||||
(reverse (if (eof-object? i)
|
|
||||||
strs
|
|
||||||
(cons (smart-substring buf i)
|
|
||||||
strs)))))))
|
|
||||||
|
|
||||||
(else (lp (cons buf strs)
|
|
||||||
(+ buflen buflen)
|
|
||||||
(make-string buflen)))))))
|
|
||||||
|
|
||||||
|
|
||||||
;;; (read-delimited! delims buf [port start end])
|
|
||||||
|
|
||||||
(define (read-delimited! delims buf . args) ; [port start end]
|
|
||||||
(receive (port start end)
|
|
||||||
(parse-optionals args (current-input-port) 0 (string-length buf))
|
|
||||||
(check-arg input-port? port read-delimited!)
|
|
||||||
(let ((delims (->char-set delims)))
|
|
||||||
; (if (fd-inport? port) ; ???
|
|
||||||
;
|
|
||||||
; ;; Handle fdports in C code for speed.
|
|
||||||
; (receive (err val)
|
|
||||||
; (%read-delimited-fdport!/errno delims buf port start end)
|
|
||||||
; (if err
|
|
||||||
; (errno-error err read-delimited!)
|
|
||||||
; val))
|
|
||||||
|
|
||||||
;; This is the code for other kinds of ports.
|
|
||||||
(let lp ((i start))
|
|
||||||
(and (< i end)
|
|
||||||
(let ((c (peek-char port)))
|
|
||||||
(if (or (eof-object? c)
|
|
||||||
(char-set-contains? delims c))
|
|
||||||
(- i start)
|
|
||||||
(begin (string-set! buf i (read-char port))
|
|
||||||
(lp (+ i 1))))))))))
|
|
||||||
;)
|
|
||||||
|
|
||||||
;(define-foreign %read-delimited-fdport!/errno (read_delim (string-desc delims)
|
|
||||||
; (string-desc buf)
|
|
||||||
; (desc port) ;???
|
|
||||||
; (fixnum start)
|
|
||||||
; (fixnum end))
|
|
||||||
; desc ; errno or #f
|
|
||||||
; desc) ; nread or #f or eof-object
|
|
||||||
|
|
||||||
(define (skip-char-set cset . maybe-port)
|
|
||||||
(let ((port (optional-arg maybe-port (current-input-port))))
|
|
||||||
(let lp ()
|
|
||||||
(let ((c (peek-char port)))
|
|
||||||
(cond ((and (char? c) (char-set-contains? cset c))
|
|
||||||
(read-char port)
|
|
||||||
(lp))
|
|
||||||
(else c))))))
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
;;; Reading records
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
||||||
|
|
||||||
(define default-record-delims (char-set #\newline))
|
|
||||||
|
|
||||||
;;; (record-reader [delims elide? handle-delim]) -> reader
|
|
||||||
;;; (reader [port]) -> string or eof
|
|
||||||
|
|
||||||
(define (record-reader . args)
|
|
||||||
(receive (delims elide? handle-delim)
|
|
||||||
(parse-optionals args default-record-delims #f 'trim)
|
|
||||||
(let ((delims (->char-set delims)))
|
|
||||||
|
|
||||||
(case handle-delim
|
|
||||||
((trim) ; TRIM-delimiter reader.
|
|
||||||
(lambda maybe-port
|
|
||||||
(let ((s (apply read-delimited delims maybe-port)))
|
|
||||||
(if (not (eof-object? s))
|
|
||||||
(if elide?
|
|
||||||
(apply skip-char-set delims maybe-port) ; Snarf delims.
|
|
||||||
(apply read-char maybe-port))) ; Just snarf one.
|
|
||||||
s)))
|
|
||||||
|
|
||||||
((concat split) ; CONCAT-delimiter & SPLIT-delimiter reader.
|
|
||||||
(let ((not-delims (char-set-invert delims)))
|
|
||||||
(lambda maybe-port
|
|
||||||
(let ((s (apply read-delimited delims maybe-port)))
|
|
||||||
(if (eof-object? s) s
|
|
||||||
(let ((delim (if elide?
|
|
||||||
(apply read-delimited not-delims maybe-port)
|
|
||||||
(string (apply read-char maybe-port)))))
|
|
||||||
(if (eq? handle-delim 'split)
|
|
||||||
(values s delim)
|
|
||||||
(if (eof-object? delim) s
|
|
||||||
(string-append s delim)))))))))
|
|
||||||
|
|
||||||
(else
|
|
||||||
(error "Illegal delimiter-action" handle-delim))))))
|
|
||||||
|
|
||||||
|
|
||||||
;;; {string, char, char-set, char predicate} -> char-set
|
|
||||||
|
|
||||||
(define (->char-set x)
|
|
||||||
(cond ((char-set? x) x)
|
|
||||||
((string? x) (string->char-set x))
|
|
||||||
((char? x) (char-set x))
|
|
||||||
((procedure? x) (predicate->char-set x))
|
|
||||||
(else (error "->char-set: Not a charset, string, char, or predicate."
|
|
||||||
x))))
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
(define blank-line-regexp (make-regexp "^[ \t]*\n$"))
|
|
||||||
|
|
||||||
;;; (read-paragraph [port])
|
|
||||||
(define (read-paragraph . maybe-port)
|
|
||||||
(let ((port (optional-arg maybe-port (current-input-port))))
|
|
||||||
|
|
||||||
;; First, skip all blank lines.
|
|
||||||
(let lp ()
|
|
||||||
(let ((line (read-line port #t)))
|
|
||||||
(cond ((eof-object? line) line)
|
|
||||||
((regexp-exec blank-line-regexp line) (lp))
|
|
||||||
|
|
||||||
;; Then, read in non-blank lines.
|
|
||||||
(else (let ((lines (let lp ((lines (list line)))
|
|
||||||
(let ((line (read-line port #t)))
|
|
||||||
(cond ((or (eof-object? line)
|
|
||||||
(regexp-exec blank-line-regexp
|
|
||||||
line))
|
|
||||||
lines)
|
|
||||||
(else (lp (cons line lines))))))))
|
|
||||||
|
|
||||||
;; Return the paragraph
|
|
||||||
(apply string-append (reverse lines)))))))))
|
|
||||||
|
|
||||||
;;; Reading and parsing records
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
||||||
;;; (field-reader [field-parser rec-reader]) -> reader
|
|
||||||
;;; (reader [port]) -> [raw-record parsed-record] or [eof #()]
|
|
||||||
;;;
|
|
||||||
;;; This is the field reader, which is basically just a composition of
|
|
||||||
;;; RECORD-READER and FIELD-PARSER.
|
|
||||||
|
|
||||||
(define default-field-parser (field-splitter))
|
|
||||||
|
|
||||||
(define (field-reader . args)
|
|
||||||
(receive (parser rec-reader)
|
|
||||||
(parse-optionals args default-field-parser read-line)
|
|
||||||
(lambda maybe-port
|
|
||||||
(let ((record (apply rec-reader maybe-port)))
|
|
||||||
(if (eof-object? record)
|
|
||||||
(values record '#())
|
|
||||||
(values record (parser record)))))))
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
;;; Parse fields by regexp
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
||||||
;;; This code parses up a record into fields by matching a regexp specifying
|
|
||||||
;;; the field against the record. The regexp describes the *field*. In the
|
|
||||||
;;; other routines, the regexp describes the *delimiters*. They are
|
|
||||||
;;; complimentary.
|
|
||||||
|
|
||||||
;;; Repeatedly do (APPLY PROC M STATE) to generate new state values,
|
|
||||||
;;; where M is a regexp match structure made from matching against STRING.
|
|
||||||
|
|
||||||
;(define (regexp-reduce string start regexp proc . state)
|
|
||||||
; (let ((end (string-length string))
|
|
||||||
; (regexp (if (string? regexp)
|
|
||||||
; (make-regexp regexp)
|
|
||||||
; regexp)))
|
|
||||||
;
|
|
||||||
; (let lp ((i start) (state state) (last-null? #f))
|
|
||||||
; (let ((j (if last-null? (+ i 1) i)))
|
|
||||||
; (cond ((and (<= j end) (regexp-exec regexp string j)) =>
|
|
||||||
; (lambda (m)
|
|
||||||
; (receive state (apply proc m state)
|
|
||||||
; (lp (match:end m) state (= (match:start m) (match:end m))))))
|
|
||||||
; (else (apply values state)))))))
|
|
||||||
;
|
|
||||||
;(define (all-regexp-matches regexp string)
|
|
||||||
; (reverse (regexp-reduce string 0 regexp
|
|
||||||
; (lambda (m ans) (cons (match:substring m 0) ans))
|
|
||||||
; '())))
|
|
||||||
|
|
||||||
;;; Previously in newports.scm
|
|
||||||
|
|
||||||
;;; Read in a line of data. Input is terminated by either a newline or EOF.
|
|
||||||
;;; The newline is trimmed from the string.
|
|
||||||
|
|
||||||
(define (read-line . rest)
|
|
||||||
(let ((port (if (null? rest) (current-input-port) (car rest))) ; Optional arg
|
|
||||||
(retain-newline? (and (not (null? rest)) ; parsing.
|
|
||||||
(not (null? (cdr rest)))
|
|
||||||
(cadr rest)))
|
|
||||||
|
|
||||||
;; S[I] := C. If this overflows S, grow it.
|
|
||||||
(deposit (lambda (s i c)
|
|
||||||
(let ((s (if (< i (string-length s)) s
|
|
||||||
(string-append s s)))) ; doubling hack
|
|
||||||
(string-set! s i c)
|
|
||||||
s)))
|
|
||||||
|
|
||||||
;; Precisely resize S to size NUMCHARS.
|
|
||||||
(trim (lambda (s numchars)
|
|
||||||
(if (= numchars (string-length s)) s
|
|
||||||
(substring s 0 numchars)))))
|
|
||||||
|
|
||||||
(let lp ((s (make-string 81)) (numchars 0))
|
|
||||||
(let ((c (read-char port)))
|
|
||||||
(cond ((eof-object? c)
|
|
||||||
(if (zero? numchars) c
|
|
||||||
(trim s numchars)))
|
|
||||||
|
|
||||||
((char=? c #\newline)
|
|
||||||
(if retain-newline?
|
|
||||||
(trim (deposit s numchars c)
|
|
||||||
(+ numchars 1))
|
|
||||||
(trim s numchars)))
|
|
||||||
|
|
||||||
(else (lp (deposit s numchars c)
|
|
||||||
(+ numchars 1))))))))
|
|
||||||
|
|
100
scsh/oldhere.scm
100
scsh/oldhere.scm
|
@ -1,100 +0,0 @@
|
||||||
;;; Here documents in Scheme for scsh scripts.
|
|
||||||
;;; These are like "here documents" for sh and csh shell scripts
|
|
||||||
;;; (i.e., the <<EOF redirection).
|
|
||||||
;;; Copyright (c) 1995 by Olin Shivers.
|
|
||||||
|
|
||||||
;;; #<EOF
|
|
||||||
;;; Hello, there.
|
|
||||||
;;; This is read by Scheme as a string,
|
|
||||||
;;; terminated by the first occurrence
|
|
||||||
;;; of newline-E-O-F.
|
|
||||||
;;; EOF
|
|
||||||
|
|
||||||
;;; Thus,
|
|
||||||
;;; #<foo
|
|
||||||
;;; Hello, world.
|
|
||||||
;;; foo
|
|
||||||
;;; is the same thing as
|
|
||||||
;;; "Hello, world."
|
|
||||||
|
|
||||||
;;; These are useful for writing down long, constant strings -- such
|
|
||||||
;;; as long, multi-line FORMAT strings, or arguments to Unix programs, e.g.
|
|
||||||
;;; ;; Free up some disk space for my netnews files.
|
|
||||||
;;; (run (csh -c #<EOF
|
|
||||||
;;; cd ~bdc
|
|
||||||
;;; rm -rf .
|
|
||||||
;;; echo All done.
|
|
||||||
;;;
|
|
||||||
;;; EOF))
|
|
||||||
|
|
||||||
;;; The syntax is as follows: the three characters "#<" introduce the
|
|
||||||
;;; here-string. The characters between the second "<" and the next newline
|
|
||||||
;;; are the *delimiter word." *All* chars between the second "<" and the next
|
|
||||||
;;; newline comprise the delimiter word -- including any white space. The
|
|
||||||
;;; newline char separates the delimiter word from the body of the string. The
|
|
||||||
;;; string body is terminated by a newline followed by the delimiter string.
|
|
||||||
;;; Absolutely *no* interpretation is done on the input string, except for
|
|
||||||
;;; scanning for the terminating delimiter word. Control chars, white space,
|
|
||||||
;;; quotes, backslash chars -- everything is copied as-is.
|
|
||||||
;;;
|
|
||||||
;;; If EOF is encountered before reading the end of the here string, an
|
|
||||||
;;; error is signalled.
|
|
||||||
|
|
||||||
(define (read-here-string port)
|
|
||||||
;; First, read in the delimiter.
|
|
||||||
(let ((delim (read-line port)))
|
|
||||||
(cond ((eof-object? delim)
|
|
||||||
(reading-error port "EOF while reading #< here-string delimiter."))
|
|
||||||
((zero? (string-length delim))
|
|
||||||
(reading-error port "#< here-string empty delimiter"))
|
|
||||||
|
|
||||||
;; This loop works as follows. We enter the loop after having
|
|
||||||
;; read a newline. We scan into the text until we discover
|
|
||||||
;; delimiter match/no-match. If match, we exit the loop;
|
|
||||||
;; if no match, we read in the rest of the line and iterate.
|
|
||||||
;; TEXT is the text we've read so far -- a list of strings in
|
|
||||||
;; reverse order.
|
|
||||||
(else
|
|
||||||
(let lp ((text '()))
|
|
||||||
(cond ((delimiter-scan delim port) =>
|
|
||||||
(lambda (line-start)
|
|
||||||
(let ((text (cons line-start text))
|
|
||||||
(ls-len (string-length line-start)))
|
|
||||||
(lp (if (char=? #\newline (string-ref line-start
|
|
||||||
(- ls-len 1)))
|
|
||||||
text
|
|
||||||
(let ((line-rest (read-line port 'concat)))
|
|
||||||
(if (eof-object? line-rest)
|
|
||||||
(reading-error port
|
|
||||||
"EOF while reading #< here-string.")
|
|
||||||
(cons line-rest text))))))))
|
|
||||||
|
|
||||||
;; We're done. The last line, tho, needs its newline
|
|
||||||
;; stripped off.
|
|
||||||
((null? text) "")
|
|
||||||
(else (let* ((last-chunk (car text))
|
|
||||||
(lc-len (string-length last-chunk))
|
|
||||||
(last-chunk (substring last-chunk 0 (- lc-len 1)))
|
|
||||||
(text (cons last-chunk (cdr text))))
|
|
||||||
(make-immutable! (apply string-append
|
|
||||||
(reverse text)))))))))))
|
|
||||||
|
|
||||||
|
|
||||||
;;; If the next chars read from PORT match DELIM, return false.
|
|
||||||
;;; Otherwise, return the string you read from PORT to determine the non-match.
|
|
||||||
;;; If EOF is encountered, report an error.
|
|
||||||
|
|
||||||
(define (delimiter-scan delim port)
|
|
||||||
(let ((len (string-length delim)))
|
|
||||||
(let lp ((i 0))
|
|
||||||
(and (< i len)
|
|
||||||
(let ((c (read-char port)))
|
|
||||||
(cond ((eof-object? c)
|
|
||||||
(reading-error port "EOF while reading #< here string."))
|
|
||||||
((char=? c (string-ref delim i))
|
|
||||||
(lp (+ i 1)))
|
|
||||||
(else (string-append (substring delim 0 i)
|
|
||||||
(string c)))))))))
|
|
||||||
|
|
||||||
;(define-sharp-macro #\<
|
|
||||||
; (lambda (c port) (read-here-string port)))
|
|
|
@ -301,7 +301,7 @@
|
||||||
(cons wptr result)
|
(cons wptr result)
|
||||||
result)))
|
result)))
|
||||||
'()
|
'()
|
||||||
lis))
|
list))
|
||||||
|
|
||||||
;;; Add a newly-reaped proc to the list.
|
;;; Add a newly-reaped proc to the list.
|
||||||
(define (add-reaped-proc! pid status)
|
(define (add-reaped-proc! pid status)
|
||||||
|
|
|
@ -150,7 +150,7 @@
|
||||||
&opt (proc (:exact-integer :value) :value)
|
&opt (proc (:exact-integer :value) :value)
|
||||||
:exact-integer)
|
:exact-integer)
|
||||||
:value))
|
:value))
|
||||||
(regexp-fold-right (proc (:value (proc (:value :exact-integer :value) :value)
|
(regexp-fold (proc (:value (proc (:value :exact-integer :value) :value)
|
||||||
:value
|
:value
|
||||||
:string
|
:string
|
||||||
&opt (proc (:exact-integer :value) :value)
|
&opt (proc (:exact-integer :value) :value)
|
||||||
|
@ -164,9 +164,9 @@
|
||||||
(compound-interface posix-re-interface
|
(compound-interface posix-re-interface
|
||||||
basic-re-interface
|
basic-re-interface
|
||||||
(export (regexp-match? (proc (:value) :boolean))
|
(export (regexp-match? (proc (:value) :boolean))
|
||||||
(match:start (proc (:value &opt :exact-integer) :value))
|
(match:start (proc (:value :exact-integer) :value))
|
||||||
(match:end (proc (:value &opt :exact-integer) :value))
|
(match:end (proc (:value :exact-integer) :value))
|
||||||
(match:substring (proc (:value &opt :exact-integer) :value))
|
(match:substring (proc (:value :exact-integer) :value))
|
||||||
(clean-up-cres (proc () :unspecific))
|
(clean-up-cres (proc () :unspecific))
|
||||||
(regexp-search (proc (:value :string &opt :exact-integer)
|
(regexp-search (proc (:value :string &opt :exact-integer)
|
||||||
:value))
|
:value))
|
||||||
|
|
|
@ -162,49 +162,44 @@
|
||||||
((c sre %word) (non-cset) re-word)
|
((c sre %word) (non-cset) re-word)
|
||||||
|
|
||||||
((pair? sre)
|
((pair? sre)
|
||||||
(let ((hygn-eq? (lambda (the-sym) (c (car sre) (r the-sym)))))
|
(case (car sre)
|
||||||
(cond
|
((*) (non-cset) (re-repeat 0 #f (parse-seq (cdr sre))))
|
||||||
((hygn-eq? '*) (non-cset) (re-repeat 0 #f (parse-seq (cdr sre))))
|
((+) (non-cset) (re-repeat 1 #f (parse-seq (cdr sre))))
|
||||||
((hygn-eq? '+) (non-cset) (re-repeat 1 #f (parse-seq (cdr sre))))
|
((?) (non-cset) (re-repeat 0 1 (parse-seq (cdr sre))))
|
||||||
((hygn-eq? '?) (non-cset) (re-repeat 0 1 (parse-seq (cdr sre))))
|
((=) (non-cset) (let ((n (cadr sre)))
|
||||||
((hygn-eq? '=) (non-cset) (let ((n (cadr sre)))
|
|
||||||
(re-repeat n n (parse-seq (cddr sre)))))
|
(re-repeat n n (parse-seq (cddr sre)))))
|
||||||
((hygn-eq? '>=) (non-cset) (re-repeat (cadr sre) #f (parse-seq (cddr sre))))
|
((>=) (non-cset) (re-repeat (cadr sre) #f (parse-seq (cddr sre))))
|
||||||
((hygn-eq? '**) (non-cset) (re-repeat (cadr sre) (caddr sre)
|
((**) (non-cset) (re-repeat (cadr sre) (caddr sre)
|
||||||
(parse-seq (cdddr sre))))
|
(parse-seq (cdddr sre))))
|
||||||
|
|
||||||
;; Choice is special wrt cset? because it's "polymorphic".
|
;; Choice is special wrt cset? because it's "polymorphic".
|
||||||
;; Note that RE-CHOICE guarantees to construct a char-set
|
;; Note that RE-CHOICE guarantees to construct a char-set
|
||||||
;; or single-char string regexp if all of its args are char
|
;; or single-char string regexp if all of its args are char
|
||||||
;; classes.
|
;; classes.
|
||||||
((or (hygn-eq? '|)
|
((| or) (let ((elts (map (lambda (sre)
|
||||||
(hygn-eq? 'or))
|
|
||||||
(let ((elts (map (lambda (sre)
|
|
||||||
(recur sre case-sensitive? cset?))
|
(recur sre case-sensitive? cset?))
|
||||||
(cdr sre))))
|
(cdr sre))))
|
||||||
(if cset?
|
(if cset?
|
||||||
(assoc-cset-op char-set-union 'char-set-union elts r)
|
(assoc-cset-op char-set-union 'char-set-union elts r)
|
||||||
(re-choice elts))))
|
(re-choice elts))))
|
||||||
|
|
||||||
((or (hygn-eq? ':)
|
((: seq) (non-cset) (parse-seq (cdr sre)))
|
||||||
(hygn-eq? 'seq))
|
|
||||||
(non-cset) (parse-seq (cdr sre)))
|
|
||||||
|
|
||||||
((hygn-eq? 'word) (non-cset) (parse-seq `(,%bow ,@(cdr sre) ,%eow)))
|
((word) (non-cset) (parse-seq `(,%bow ,@(cdr sre) ,%eow)))
|
||||||
((hygn-eq? 'word+)
|
((word+)
|
||||||
(recur `(,(r 'word) (,(r '+) (,(r '&) (,(r '|) ,(r 'alphanum) "_")
|
(recur `(,(r 'word) (,(r '+) (,(r '&) (,(r '|) ,(r 'alphanum) "_")
|
||||||
(,(r '|) . ,(cdr sre)))))
|
(,(r '|) . ,(cdr sre)))))
|
||||||
case-sensitive?
|
case-sensitive?
|
||||||
cset?))
|
cset?))
|
||||||
|
|
||||||
((hygn-eq? 'submatch) (non-cset) (re-submatch (parse-seq (cdr sre))))
|
((submatch) (non-cset) (re-submatch (parse-seq (cdr sre))))
|
||||||
((hygn-eq? 'dsm) (non-cset) (re-dsm (parse-seq (cdddr sre))
|
((dsm) (non-cset) (re-dsm (parse-seq (cdddr sre))
|
||||||
(cadr sre)
|
(cadr sre)
|
||||||
(caddr sre)))
|
(caddr sre)))
|
||||||
|
|
||||||
;; We could be more aggressive and push the uncase op down into
|
;; We could be more aggressive and push the uncase op down into
|
||||||
;; partially-static regexps, but enough is enough.
|
;; partially-static regexps, but enough is enough.
|
||||||
((hygn-eq? 'uncase)
|
((uncase)
|
||||||
(let ((re-or-cset (parse-seq (cdr sre)))) ; Depending on CSET?.
|
(let ((re-or-cset (parse-seq (cdr sre)))) ; Depending on CSET?.
|
||||||
(if cset?
|
(if cset?
|
||||||
|
|
||||||
|
@ -218,22 +213,22 @@
|
||||||
,(regexp->scheme (simplify-regexp re-or-cset) r))))))
|
,(regexp->scheme (simplify-regexp re-or-cset) r))))))
|
||||||
|
|
||||||
;; These just change the lexical case-sensitivity context.
|
;; These just change the lexical case-sensitivity context.
|
||||||
((hygn-eq? 'w/nocase) (parse-seq/context (cdr sre) #f))
|
((w/nocase) (parse-seq/context (cdr sre) #f))
|
||||||
((hygn-eq? 'w/case) (parse-seq/context (cdr sre) #t))
|
((w/case) (parse-seq/context (cdr sre) #t))
|
||||||
|
|
||||||
;; ,<exp> and ,@<exp>
|
;; ,<exp> and ,@<exp>
|
||||||
((hygn-eq? 'unquote)
|
((unquote)
|
||||||
(let ((exp (cadr sre)))
|
(let ((exp (cadr sre)))
|
||||||
(if cset?
|
(if cset?
|
||||||
`(,%coerce-dynamic-charset ,exp)
|
`(,%coerce-dynamic-charset ,exp)
|
||||||
`(,%flush-submatches (,%coerce-dynamic-regexp ,exp)))))
|
`(,%flush-submatches (,%coerce-dynamic-regexp ,exp)))))
|
||||||
((hygn-eq? 'unquote-splicing)
|
((unquote-splicing)
|
||||||
(let ((exp (cadr sre)))
|
(let ((exp (cadr sre)))
|
||||||
(if cset?
|
(if cset?
|
||||||
`(,%coerce-dynamic-charset ,exp)
|
`(,%coerce-dynamic-charset ,exp)
|
||||||
`(,%coerce-dynamic-regexp ,exp))))
|
`(,%coerce-dynamic-regexp ,exp))))
|
||||||
|
|
||||||
((hygn-eq? '~) (let* ((cs (assoc-cset-op char-set-union 'char-set-union
|
((~) (let* ((cs (assoc-cset-op char-set-union 'char-set-union
|
||||||
(map parse-char-class (cdr sre))
|
(map parse-char-class (cdr sre))
|
||||||
r))
|
r))
|
||||||
(cs (if (char-set? cs)
|
(cs (if (char-set? cs)
|
||||||
|
@ -241,12 +236,12 @@
|
||||||
`(,(r 'char-set-complement) ,cs))))
|
`(,(r 'char-set-complement) ,cs))))
|
||||||
(if cset? cs (make-re-char-set cs))))
|
(if cset? cs (make-re-char-set cs))))
|
||||||
|
|
||||||
((hygn-eq? '&) (let ((cs (assoc-cset-op char-set-intersection 'char-set-intersection
|
((&) (let ((cs (assoc-cset-op char-set-intersection 'char-set-intersection
|
||||||
(map parse-char-class (cdr sre))
|
(map parse-char-class (cdr sre))
|
||||||
r)))
|
r)))
|
||||||
(if cset? cs (make-re-char-set cs))))
|
(if cset? cs (make-re-char-set cs))))
|
||||||
|
|
||||||
((hygn-eq? '-) (if (pair? (cdr sre))
|
((-) (if (pair? (cdr sre))
|
||||||
(let* ((cs1 (parse-char-class (cadr sre)))
|
(let* ((cs1 (parse-char-class (cadr sre)))
|
||||||
(cs2 (assoc-cset-op char-set-union 'char-set-union
|
(cs2 (assoc-cset-op char-set-union 'char-set-union
|
||||||
(map parse-char-class (cddr sre))
|
(map parse-char-class (cddr sre))
|
||||||
|
@ -263,10 +258,10 @@
|
||||||
(if cset? cs (make-re-char-set cs)))
|
(if cset? cs (make-re-char-set cs)))
|
||||||
(error "SRE set-difference operator (- ...) requires at least one argument")))
|
(error "SRE set-difference operator (- ...) requires at least one argument")))
|
||||||
|
|
||||||
((hygn-eq? '/) (let ((cset (range-class->char-set (cdr sre) case-sensitive?)))
|
((/) (let ((cset (range-class->char-set (cdr sre) case-sensitive?)))
|
||||||
(if cset? cset (make-re-char-set cset))))
|
(if cset? cset (make-re-char-set cset))))
|
||||||
|
|
||||||
((hygn-eq? 'posix-string)
|
((posix-string)
|
||||||
(if (and (= 1 (length (cdr sre)))
|
(if (and (= 1 (length (cdr sre)))
|
||||||
(string? (cadr sre)))
|
(string? (cadr sre)))
|
||||||
(posix-string->regexp (cadr sre))
|
(posix-string->regexp (cadr sre))
|
||||||
|
@ -278,33 +273,27 @@
|
||||||
(cs (if case-sensitive? cs (uncase-char-set cs))))
|
(cs (if case-sensitive? cs (uncase-char-set cs))))
|
||||||
(if cset? cs (make-re-char-set cs)))
|
(if cset? cs (make-re-char-set cs)))
|
||||||
|
|
||||||
(error "Illegal SRE" sre))))))
|
(error "Illegal SRE" sre)))))
|
||||||
|
|
||||||
;; It must be a char-class name (ANY, ALPHABETIC, etc.)
|
;; It must be a char-class name (ANY, ALPHABETIC, etc.)
|
||||||
(else
|
(else (let ((cs (case sre
|
||||||
(letrec ((hygn-memq? (lambda (sym-list)
|
((any) char-set:full)
|
||||||
(if (null? sym-list)
|
((nonl) nonl-chars)
|
||||||
#f
|
((lower-case lower) char-set:lower-case)
|
||||||
(or (c sre (r (car sym-list)))
|
((upper-case upper) char-set:upper-case)
|
||||||
(hygn-memq? (cdr sym-list)))))))
|
((alphabetic alpha) char-set:letter)
|
||||||
(let ((cs (cond
|
((numeric digit num) char-set:digit)
|
||||||
((hygn-memq? '(any)) char-set:full)
|
((alphanumeric alnum alphanum) char-set:letter+digit)
|
||||||
((hygn-memq? '(nonl)) nonl-chars)
|
((punctuation punct) char-set:punctuation)
|
||||||
((hygn-memq? '(lower-case lower)) char-set:lower-case)
|
((graphic graph) char-set:graphic)
|
||||||
((hygn-memq? '(upper-case upper)) char-set:upper-case)
|
((blank) char-set:blank)
|
||||||
((hygn-memq? '(alphabetic alpha)) char-set:letter)
|
((whitespace space white) char-set:whitespace)
|
||||||
((hygn-memq? '(numeric digit num)) char-set:digit)
|
((printing print) char-set:printing)
|
||||||
((hygn-memq? '(alphanumeric alnum alphanum)) char-set:letter+digit)
|
((control cntrl) char-set:iso-control)
|
||||||
((hygn-memq? '(punctuation punct)) char-set:punctuation)
|
((hex-digit xdigit hex) char-set:hex-digit)
|
||||||
((hygn-memq? '(graphic graph)) char-set:graphic)
|
((ascii) char-set:ascii)
|
||||||
((hygn-memq? '(blank)) char-set:blank)
|
|
||||||
((hygn-memq? '(whitespace space white)) char-set:whitespace)
|
|
||||||
((hygn-memq? '(printing print)) char-set:printing)
|
|
||||||
((hygn-memq? '(control cntrl)) char-set:iso-control)
|
|
||||||
((hygn-memq? '(hex-digit xdigit hex)) char-set:hex-digit)
|
|
||||||
((hygn-memq? '(ascii)) char-set:ascii)
|
|
||||||
(else (error "Illegal regular expression" sre)))))
|
(else (error "Illegal regular expression" sre)))))
|
||||||
(if cset? cs (make-re-char-set cs)))))))))
|
(if cset? cs (make-re-char-set cs))))))))
|
||||||
|
|
||||||
|
|
||||||
;;; In a CSET? true context, S must be a 1-char string; convert to a char set
|
;;; In a CSET? true context, S must be a 1-char string; convert to a char set
|
||||||
|
|
|
@ -498,7 +498,7 @@
|
||||||
(values re #f))))
|
(values re #f))))
|
||||||
|
|
||||||
((re-submatch? re)
|
((re-submatch? re)
|
||||||
(receive (new-body body-changed?) (recur (re-submatch:body re))
|
(receive (new-body body-changed?) (recur (re-submatch? re))
|
||||||
(if body-changed?
|
(if body-changed?
|
||||||
(values (%make-re-submatch new-body
|
(values (%make-re-submatch new-body
|
||||||
(re-submatch:pre-dsm re)
|
(re-submatch:pre-dsm re)
|
||||||
|
|
|
@ -140,8 +140,7 @@
|
||||||
|
|
||||||
;; Regular letter -- either alone, or startpoint of a range.
|
;; Regular letter -- either alone, or startpoint of a range.
|
||||||
(else (if (and (< (+ i1 1) len)
|
(else (if (and (< (+ i1 1) len)
|
||||||
(char=? #\- (string-ref s i1))
|
(char=? #\- (string-ref s i1)))
|
||||||
(not (char=? #\] (string-ref s (+ i1 1)))))
|
|
||||||
|
|
||||||
;; Range
|
;; Range
|
||||||
(let* ((i-tochar (+ i1 1))
|
(let* ((i-tochar (+ i1 1))
|
||||||
|
|
|
@ -171,7 +171,6 @@
|
||||||
|
|
||||||
string-lib
|
string-lib
|
||||||
|
|
||||||
fluids ; For exec-path-list
|
|
||||||
loopholes ; For my bogus CALL-TERMINALLY implementation.
|
loopholes ; For my bogus CALL-TERMINALLY implementation.
|
||||||
|
|
||||||
scheme
|
scheme
|
||||||
|
@ -248,8 +247,6 @@
|
||||||
command-processor ; command-output
|
command-processor ; command-output
|
||||||
filenames ; translate
|
filenames ; translate
|
||||||
scheme-level-2-internal ; usual-resumer
|
scheme-level-2-internal ; usual-resumer
|
||||||
package-commands-internal ;user-environment
|
|
||||||
environments ; with-interaction-environment
|
|
||||||
scheme)
|
scheme)
|
||||||
(files startup)
|
(files startup)
|
||||||
(optimize auto-integrate)
|
(optimize auto-integrate)
|
||||||
|
@ -359,7 +356,7 @@
|
||||||
(export repl)
|
(export repl)
|
||||||
awk-interface
|
awk-interface
|
||||||
odbc-interface
|
odbc-interface
|
||||||
char-predicates-interface; Urk -- Some of this is R5RS!
|
char-set-predicates-interface; Urk -- Some of this is R5RS!
|
||||||
obsolete-char-set-interface
|
obsolete-char-set-interface
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -375,7 +372,7 @@
|
||||||
awk-package
|
awk-package
|
||||||
odbc-package
|
odbc-package
|
||||||
field-reader-package
|
field-reader-package
|
||||||
char-predicates-lib ; Urk -- Some of this is R5RS!
|
char-set-predicates-lib ; Urk -- Some of this is R5RS!
|
||||||
scheme)
|
scheme)
|
||||||
|
|
||||||
(access scsh-top-package)
|
(access scsh-top-package)
|
||||||
|
|
|
@ -297,8 +297,7 @@
|
||||||
(close-fdes (open-fdes fname oflags #o600))
|
(close-fdes (open-fdes fname oflags #o600))
|
||||||
fname)
|
fname)
|
||||||
(if (null? maybe-prefix) '()
|
(if (null? maybe-prefix) '()
|
||||||
(list (string-append (constant-format-string (car maybe-prefix))
|
(list (string-append (car maybe-prefix) ".~a"))))))
|
||||||
".~a"))))))
|
|
||||||
|
|
||||||
(define *temp-file-template*
|
(define *temp-file-template*
|
||||||
(make-fluid (string-append "/usr/tmp/" (number->string (pid)) ".~a")))
|
(make-fluid (string-append "/usr/tmp/" (number->string (pid)) ".~a")))
|
||||||
|
@ -317,23 +316,6 @@
|
||||||
(loop (+ i 1)))))))))
|
(loop (+ i 1)))))))))
|
||||||
|
|
||||||
|
|
||||||
;; Double tildes in S.
|
|
||||||
;; Using the return value as a format string will output exactly S.
|
|
||||||
(define (constant-format-string s) ; Ugly code. Would be much clearer
|
|
||||||
(let* ((len (string-length s)) ; if written with string SRFI.
|
|
||||||
(tilde? (lambda (s i) (char=? #\~ (string-ref s i))))
|
|
||||||
(newlen (do ((i (- len 1) (- i 1))
|
|
||||||
(ans 0 (+ ans (if (tilde? s i) 2 1))))
|
|
||||||
((< i 0) ans)))
|
|
||||||
(fs (make-string newlen)))
|
|
||||||
(let lp ((i 0) (j 0))
|
|
||||||
(cond ((< i len)
|
|
||||||
(let ((j (cond ((tilde? s i) (string-set! fs j #\~) (+ j 1))
|
|
||||||
(else j))))
|
|
||||||
(string-set! fs j (string-ref s i))
|
|
||||||
(lp (+ i 1) (+ j 1))))))
|
|
||||||
fs))
|
|
||||||
|
|
||||||
|
|
||||||
;;; Roughly equivalent to (pipe).
|
;;; Roughly equivalent to (pipe).
|
||||||
;;; Returns two file ports [iport oport] open on a temp file.
|
;;; Returns two file ports [iport oport] open on a temp file.
|
||||||
|
@ -682,7 +664,7 @@
|
||||||
(%exec prog (cons prog arglist) env))
|
(%exec prog (cons prog arglist) env))
|
||||||
|
|
||||||
;(define (exec-path/env prog env . arglist)
|
;(define (exec-path/env prog env . arglist)
|
||||||
; (cond ((exec-path-search (stringify prog) (fluid exec-path-list)) =>
|
; (cond ((exec-path-search (stringify prog) exec-path-list) =>
|
||||||
; (lambda (binary)
|
; (lambda (binary)
|
||||||
; (apply exec/env binary env arglist)))
|
; (apply exec/env binary env arglist)))
|
||||||
; (else (error "No executable found." prog arglist))))
|
; (else (error "No executable found." prog arglist))))
|
||||||
|
@ -704,7 +686,7 @@
|
||||||
(for-each (lambda (dir)
|
(for-each (lambda (dir)
|
||||||
(let ((binary (string-append dir "/" prog)))
|
(let ((binary (string-append dir "/" prog)))
|
||||||
(%%exec/errno binary argv env)))
|
(%%exec/errno binary argv env)))
|
||||||
(fluid exec-path-list)))))
|
exec-path-list))))
|
||||||
|
|
||||||
(error "No executable found." prog arglist))
|
(error "No executable found." prog arglist))
|
||||||
|
|
||||||
|
@ -764,7 +746,7 @@
|
||||||
|
|
||||||
;;; Some globals:
|
;;; Some globals:
|
||||||
(define home-directory "")
|
(define home-directory "")
|
||||||
(define exec-path-list (make-fluid '()))
|
(define exec-path-list '())
|
||||||
|
|
||||||
(define (init-scsh-vars quietly?)
|
(define (init-scsh-vars quietly?)
|
||||||
(set! home-directory
|
(set! home-directory
|
||||||
|
@ -772,7 +754,7 @@
|
||||||
(else (if (not quietly?)
|
(else (if (not quietly?)
|
||||||
(warn "Starting up with no home directory ($HOME)."))
|
(warn "Starting up with no home directory ($HOME)."))
|
||||||
"/")))
|
"/")))
|
||||||
(set-fluid! exec-path-list
|
(set! exec-path-list
|
||||||
(cond ((getenv "PATH") => split-colon-list)
|
(cond ((getenv "PATH") => split-colon-list)
|
||||||
(else (if (not quietly?)
|
(else (if (not quietly?)
|
||||||
(warn "Starting up with no path ($PATH)."))
|
(warn "Starting up with no path ($PATH)."))
|
||||||
|
|
|
@ -42,20 +42,10 @@
|
||||||
;;; This is what we export to the user for his programs.
|
;;; This is what we export to the user for his programs.
|
||||||
|
|
||||||
(define (dump-scsh-program start filename)
|
(define (dump-scsh-program start filename)
|
||||||
(let ((context (user-context)))
|
(really-dump-scsh-program (lambda (args)
|
||||||
(really-dump-scsh-program
|
|
||||||
(lambda (args)
|
|
||||||
(with-new-session context ; "Log in" user.
|
|
||||||
(current-input-port) (current-output-port)
|
|
||||||
args
|
|
||||||
#f
|
|
||||||
(lambda ()
|
|
||||||
(with-interaction-environment
|
|
||||||
(user-environment) ; <-- from CONTEXT.
|
|
||||||
(lambda ()
|
|
||||||
(init-scsh-vars #t) ; Do it quietly.
|
(init-scsh-vars #t) ; Do it quietly.
|
||||||
(start args))))))
|
(start args))
|
||||||
filename)))
|
filename))
|
||||||
|
|
||||||
|
|
||||||
(define (scsh-stand-alone-resumer start)
|
(define (scsh-stand-alone-resumer start)
|
||||||
|
|
|
@ -891,10 +891,7 @@
|
||||||
|
|
||||||
(define (alist->env-vec alist)
|
(define (alist->env-vec alist)
|
||||||
(list->vector (map (lambda (var.val)
|
(list->vector (map (lambda (var.val)
|
||||||
(string-append (car var.val) "="
|
(string-append (car var.val) "=" (cdr var.val)))
|
||||||
(let ((val (cdr var.val)))
|
|
||||||
(if (string? val) val
|
|
||||||
(string-join val ":")))))
|
|
||||||
alist)))
|
alist)))
|
||||||
|
|
||||||
;;; ENV->ALIST
|
;;; ENV->ALIST
|
||||||
|
|
|
@ -217,7 +217,7 @@ scheme_value date2time(int sec, int min, int hour,
|
||||||
|
|
||||||
d.tm_sec = sec; d.tm_min = min; d.tm_hour = hour;
|
d.tm_sec = sec; d.tm_min = min; d.tm_hour = hour;
|
||||||
d.tm_mday = mday; d.tm_mon = month; d.tm_year = year;
|
d.tm_mday = mday; d.tm_mon = month; d.tm_year = year;
|
||||||
d.tm_wday = 0; d.tm_yday = 0;
|
d.tm_wday = 0; d.tm_yday = 0; d.tm_isdst = summer;
|
||||||
|
|
||||||
if( FIXNUMP(tz_secs) ) { /* Offset from GMT in seconds. */
|
if( FIXNUMP(tz_secs) ) { /* Offset from GMT in seconds. */
|
||||||
char **oldenv = environ; /* Set TZ to UTC */
|
char **oldenv = environ; /* Set TZ to UTC */
|
||||||
|
@ -232,16 +232,12 @@ scheme_value date2time(int sec, int min, int hour,
|
||||||
environ = oldenv;
|
environ = oldenv;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ### Note that we *still* don't implement the manual paragraph
|
|
||||||
with "When calcultating with time-zones, the date's SUMMER?
|
|
||||||
field is used to resolve ambiguities. */
|
|
||||||
else if( STRINGP(tz_name) ) { /* Time zone */
|
else if( STRINGP(tz_name) ) { /* Time zone */
|
||||||
char *newenv[2];
|
char *newenv[2];
|
||||||
char **oldenv = make_newenv(tz_name, newenv);
|
char **oldenv = make_newenv(tz_name, newenv);
|
||||||
if( !oldenv ) return ENTER_FIXNUM(errno);
|
if( !oldenv ) return ENTER_FIXNUM(errno);
|
||||||
tzset(); /* NetBSD, SunOS POSIX-noncompliance requires this. */
|
tzset(); /* NetBSD, SunOS POSIX-noncompliance requires this. */
|
||||||
errno = 0;
|
errno = 0;
|
||||||
d.tm_isdst = -1;
|
|
||||||
t = mktime(&d);
|
t = mktime(&d);
|
||||||
if( t == -1 ) return ENTER_FIXNUM(errno ? errno : -1);
|
if( t == -1 ) return ENTER_FIXNUM(errno ? errno : -1);
|
||||||
revert_env(oldenv);
|
revert_env(oldenv);
|
||||||
|
@ -250,7 +246,6 @@ scheme_value date2time(int sec, int min, int hour,
|
||||||
else { /* Local time */
|
else { /* Local time */
|
||||||
tzset(); /* NetBSD, SunOS POSIX-noncompliance requires this. */
|
tzset(); /* NetBSD, SunOS POSIX-noncompliance requires this. */
|
||||||
errno = 0;
|
errno = 0;
|
||||||
d.tm_isdst = -1;
|
|
||||||
t = mktime(&d);
|
t = mktime(&d);
|
||||||
if( t == -1) return ENTER_FIXNUM(errno ? errno : -1);
|
if( t == -1) return ENTER_FIXNUM(errno ? errno : -1);
|
||||||
}
|
}
|
||||||
|
|
2
unix.c
2
unix.c
|
@ -523,7 +523,7 @@ fill_the_table(void)
|
||||||
entry.n_scnum != N_UNDEF &&
|
entry.n_scnum != N_UNDEF &&
|
||||||
entry.n_scnum != N_DEBUG)
|
entry.n_scnum != N_DEBUG)
|
||||||
{
|
{
|
||||||
extern char *ldgetname(LDFILE *, void *);
|
extern char *ldgetname(LDFILE *, SYMENT *);
|
||||||
char *p = ldgetname(f, &entry);
|
char *p = ldgetname(f, &entry);
|
||||||
|
|
||||||
if (p != NULL && p[0] == '.') {
|
if (p != NULL && p[0] == '.') {
|
||||||
|
|
Loading…
Reference in New Issue