mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-04-30 03:40:34 +02:00
Merge branch 'master' of git://git.savannah.gnu.org/guile
This commit is contained in:
commit
2f9ae9b104
158 changed files with 17374 additions and 3404 deletions
6
README
6
README
|
@ -61,6 +61,12 @@ Guile requires the following external packages:
|
|||
libltdl is used for loading extensions at run-time. It is
|
||||
available from http://www.gnu.org/software/libtool/
|
||||
|
||||
- GNU libunistring
|
||||
|
||||
libunistring is used for Unicode string operations, such as the
|
||||
`utf*->string' procedures. It is available from
|
||||
http://www.gnu.org/software/libunistring/ .
|
||||
|
||||
|
||||
Special Instructions For Some Systems =====================================
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
SCM_BENCHMARKS = benchmarks/0-reference.bm \
|
||||
benchmarks/bytevectors.bm \
|
||||
benchmarks/continuations.bm \
|
||||
benchmarks/if.bm \
|
||||
benchmarks/logand.bm \
|
||||
|
|
99
benchmark-suite/benchmarks/bytevectors.bm
Normal file
99
benchmark-suite/benchmarks/bytevectors.bm
Normal file
|
@ -0,0 +1,99 @@
|
|||
;;; -*- mode: scheme; coding: latin-1; -*-
|
||||
;;; R6RS Byte Vectors.
|
||||
;;;
|
||||
;;; Copyright 2009 Ludovic Courtès <ludo@gnu.org>
|
||||
;;;
|
||||
;;;
|
||||
;;; This program is free software; you can redistribute it and/or modify
|
||||
;;; it under the terms of the GNU General Public License as published by
|
||||
;;; the Free Software Foundation; either version 2 of the License, or
|
||||
;;; (at your option) any later version.
|
||||
;;;
|
||||
;;; This program is distributed in the hope that it will be useful,
|
||||
;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
;;; GNU General Public License for more details.
|
||||
;;;
|
||||
;;; You should have received a copy of the GNU General Public License
|
||||
;;; along with this program; if not, write to the Free Software
|
||||
;;; Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
(define-module (benchmarks bytevector)
|
||||
:use-module (rnrs bytevector)
|
||||
:use-module (srfi srfi-4)
|
||||
:use-module (benchmark-suite lib))
|
||||
|
||||
(define bv (make-bytevector 16384))
|
||||
|
||||
(define %native-endianness
|
||||
(native-endianness))
|
||||
|
||||
(define %foreign-endianness
|
||||
(if (eq? (native-endianness) (endianness little))
|
||||
(endianness big)
|
||||
(endianness little)))
|
||||
|
||||
(define u8v (make-u8vector 16384))
|
||||
(define u16v (make-u16vector 8192))
|
||||
(define u32v (make-u32vector 4196))
|
||||
(define u64v (make-u64vector 2048))
|
||||
|
||||
|
||||
(with-benchmark-prefix "ref/set!"
|
||||
|
||||
(benchmark "bytevector-u8-ref" 1000000
|
||||
(bytevector-u8-ref bv 0))
|
||||
|
||||
(benchmark "bytevector-u16-ref (foreign)" 1000000
|
||||
(bytevector-u16-ref bv 0 %foreign-endianness))
|
||||
|
||||
(benchmark "bytevector-u16-ref (native)" 1000000
|
||||
(bytevector-u16-ref bv 0 %native-endianness))
|
||||
|
||||
(benchmark "bytevector-u16-native-ref" 1000000
|
||||
(bytevector-u16-native-ref bv 0))
|
||||
|
||||
(benchmark "bytevector-u32-ref (foreign)" 1000000
|
||||
(bytevector-u32-ref bv 0 %foreign-endianness))
|
||||
|
||||
(benchmark "bytevector-u32-ref (native)" 1000000
|
||||
(bytevector-u32-ref bv 0 %native-endianness))
|
||||
|
||||
(benchmark "bytevector-u32-native-ref" 1000000
|
||||
(bytevector-u32-native-ref bv 0))
|
||||
|
||||
(benchmark "bytevector-u64-ref (foreign)" 1000000
|
||||
(bytevector-u64-ref bv 0 %foreign-endianness))
|
||||
|
||||
(benchmark "bytevector-u64-ref (native)" 1000000
|
||||
(bytevector-u64-ref bv 0 %native-endianness))
|
||||
|
||||
(benchmark "bytevector-u64-native-ref" 1000000
|
||||
(bytevector-u16-native-ref bv 0)))
|
||||
|
||||
|
||||
(with-benchmark-prefix "lists"
|
||||
|
||||
(benchmark "bytevector->u8-list" 2000
|
||||
(bytevector->u8-list bv))
|
||||
|
||||
(benchmark "bytevector->uint-list 16-bit" 2000
|
||||
(bytevector->uint-list bv (native-endianness) 2))
|
||||
|
||||
(benchmark "bytevector->uint-list 64-bit" 2000
|
||||
(bytevector->uint-list bv (native-endianness) 8)))
|
||||
|
||||
|
||||
(with-benchmark-prefix "SRFI-4" ;; for comparison
|
||||
|
||||
(benchmark "u8vector-ref" 1000000
|
||||
(u8vector-ref u8v 0))
|
||||
|
||||
(benchmark "u16vector-ref" 1000000
|
||||
(u16vector-ref u16v 0))
|
||||
|
||||
(benchmark "u32vector-ref" 1000000
|
||||
(u32vector-ref u32v 0))
|
||||
|
||||
(benchmark "u64vector-ref" 1000000
|
||||
(u64vector-ref u64v 0)))
|
|
@ -47,7 +47,7 @@ for cc_temp in $CC""; do
|
|||
done
|
||||
cc_basename=`echo "$cc_temp" | sed -e 's%^.*/%%'`
|
||||
|
||||
# Code taken from libtool.m4's AC_LIBTOOL_PROG_COMPILER_PIC.
|
||||
# Code taken from libtool.m4's _LT_COMPILER_PIC.
|
||||
|
||||
wl=
|
||||
if test "$GCC" = yes; then
|
||||
|
@ -64,7 +64,7 @@ else
|
|||
;;
|
||||
esac
|
||||
;;
|
||||
mingw* | cygwin* | pw32* | os2*)
|
||||
mingw* | cygwin* | pw32* | os2* | cegcc*)
|
||||
;;
|
||||
hpux9* | hpux10* | hpux11*)
|
||||
wl='-Wl,'
|
||||
|
@ -76,7 +76,13 @@ else
|
|||
;;
|
||||
linux* | k*bsd*-gnu)
|
||||
case $cc_basename in
|
||||
icc* | ecc*)
|
||||
ecc*)
|
||||
wl='-Wl,'
|
||||
;;
|
||||
icc* | ifort*)
|
||||
wl='-Wl,'
|
||||
;;
|
||||
lf95*)
|
||||
wl='-Wl,'
|
||||
;;
|
||||
pgcc | pgf77 | pgf90)
|
||||
|
@ -124,7 +130,7 @@ else
|
|||
esac
|
||||
fi
|
||||
|
||||
# Code taken from libtool.m4's AC_LIBTOOL_PROG_LD_SHLIBS.
|
||||
# Code taken from libtool.m4's _LT_LINKER_SHLIBS.
|
||||
|
||||
hardcode_libdir_flag_spec=
|
||||
hardcode_libdir_separator=
|
||||
|
@ -132,7 +138,7 @@ hardcode_direct=no
|
|||
hardcode_minus_L=no
|
||||
|
||||
case "$host_os" in
|
||||
cygwin* | mingw* | pw32*)
|
||||
cygwin* | mingw* | pw32* | cegcc*)
|
||||
# FIXME: the MSVC++ port hasn't been tested in a loooong time
|
||||
# When not using gcc, we currently assume that we are using
|
||||
# Microsoft Visual C++.
|
||||
|
@ -182,7 +188,7 @@ if test "$with_gnu_ld" = yes; then
|
|||
ld_shlibs=no
|
||||
fi
|
||||
;;
|
||||
cygwin* | mingw* | pw32*)
|
||||
cygwin* | mingw* | pw32* | cegcc*)
|
||||
# hardcode_libdir_flag_spec is actually meaningless, as there is
|
||||
# no search path for DLLs.
|
||||
hardcode_libdir_flag_spec='-L$libdir'
|
||||
|
@ -326,7 +332,7 @@ else
|
|||
;;
|
||||
bsdi[45]*)
|
||||
;;
|
||||
cygwin* | mingw* | pw32*)
|
||||
cygwin* | mingw* | pw32* | cegcc*)
|
||||
# When not using gcc, we currently assume that we are using
|
||||
# Microsoft Visual C++.
|
||||
# hardcode_libdir_flag_spec is actually meaningless, as there is
|
||||
|
@ -494,7 +500,7 @@ else
|
|||
fi
|
||||
|
||||
# Check dynamic linker characteristics
|
||||
# Code taken from libtool.m4's AC_LIBTOOL_SYS_DYNAMIC_LINKER.
|
||||
# Code taken from libtool.m4's _LT_SYS_DYNAMIC_LINKER.
|
||||
# Unlike libtool.m4, here we don't care about _all_ names of the library, but
|
||||
# only about the one the linker finds when passed -lNAME. This is the last
|
||||
# element of library_names_spec in libtool.m4, or possibly two of them if the
|
||||
|
@ -517,7 +523,7 @@ case "$host_os" in
|
|||
bsdi[45]*)
|
||||
library_names_spec='$libname$shrext'
|
||||
;;
|
||||
cygwin* | mingw* | pw32*)
|
||||
cygwin* | mingw* | pw32* | cegcc*)
|
||||
shrext=.dll
|
||||
library_names_spec='$libname.dll.a $libname.lib'
|
||||
;;
|
||||
|
|
|
@ -836,6 +836,13 @@ AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <gmp.h>]],
|
|||
[],
|
||||
[AC_MSG_ERROR([At least GNU MP 4.1 is required, see README])])
|
||||
|
||||
dnl GNU libunistring tests.
|
||||
if test "x$LTLIBUNISTRING" != "x"; then
|
||||
LIBS="$LTLIBUNISTRING $LIBS"
|
||||
else
|
||||
AC_MSG_ERROR([GNU libunistring is required, please install it.])
|
||||
fi
|
||||
|
||||
dnl i18n tests
|
||||
#AC_CHECK_HEADERS([libintl.h])
|
||||
#AC_CHECK_FUNCS(gettext)
|
||||
|
|
|
@ -162,18 +162,10 @@ appropriate module first, though:
|
|||
Returns @code{#t} iff @var{obj} is a compiled procedure.
|
||||
@end deffn
|
||||
|
||||
@deffn {Scheme Procedure} program-bytecode program
|
||||
@deffnx {C Function} scm_program_bytecode (program)
|
||||
Returns the object code associated with this program, as a
|
||||
@code{u8vector}.
|
||||
@end deffn
|
||||
|
||||
@deffn {Scheme Procedure} program-base program
|
||||
@deffnx {C Function} scm_program_base (program)
|
||||
Returns the address in memory corresponding to the start of
|
||||
@var{program}'s object code, as an integer. This is useful mostly when
|
||||
you map the value of an instruction pointer from the VM to actual
|
||||
instructions.
|
||||
@deffn {Scheme Procedure} program-objcode program
|
||||
@deffnx {C Function} scm_program_objcode (program)
|
||||
Returns the object code associated with this program. @xref{Bytecode
|
||||
and Objcode}, for more information.
|
||||
@end deffn
|
||||
|
||||
@deffn {Scheme Procedure} program-objects program
|
||||
|
@ -184,9 +176,9 @@ vector. @xref{VM Programs}, for more information.
|
|||
|
||||
@deffn {Scheme Procedure} program-module program
|
||||
@deffnx {C Function} scm_program_module (program)
|
||||
Returns the module that was current when this program was created.
|
||||
Free variables in this program are looked up with respect to this
|
||||
module.
|
||||
Returns the module that was current when this program was created. Can
|
||||
return @code{#f} if the compiler could determine that this information
|
||||
was unnecessary.
|
||||
@end deffn
|
||||
|
||||
@deffn {Scheme Procedure} program-external program
|
||||
|
@ -250,9 +242,9 @@ REPL. The only tricky bit is that @var{extp} is a boolean, declaring
|
|||
whether the binding is heap-allocated or not. @xref{VM Concepts}, for
|
||||
more information.
|
||||
|
||||
Note that bindings information are stored in a program as part of its
|
||||
metadata thunk, so including them in the generated object code does
|
||||
not impose a runtime performance penalty.
|
||||
Note that bindings information is stored in a program as part of its
|
||||
metadata thunk, so including it in the generated object code does not
|
||||
impose a runtime performance penalty.
|
||||
@end deffn
|
||||
|
||||
@deffn {Scheme Procedure} program-sources program
|
||||
|
|
|
@ -22,9 +22,10 @@ know how to compile your .scm file.
|
|||
@menu
|
||||
* Compiler Tower::
|
||||
* The Scheme Compiler::
|
||||
* GHIL::
|
||||
* Tree-IL::
|
||||
* GLIL::
|
||||
* Object Code::
|
||||
* Assembly::
|
||||
* Bytecode and Objcode::
|
||||
* Extending the Compiler::
|
||||
@end menu
|
||||
|
||||
|
@ -52,7 +53,7 @@ They are registered with the @code{define-language} form.
|
|||
|
||||
@deffn {Scheme Syntax} define-language @
|
||||
name title version reader printer @
|
||||
[parser=#f] [read-file=#f] [compilers='()] [evaluator=#f]
|
||||
[parser=#f] [compilers='()] [decompilers='()] [evaluator=#f]
|
||||
Define a language.
|
||||
|
||||
This syntax defines a @code{#<language>} object, bound to @var{name}
|
||||
|
@ -62,17 +63,15 @@ for Scheme:
|
|||
|
||||
@example
|
||||
(define-language scheme
|
||||
#:title "Guile Scheme"
|
||||
#:version "0.5"
|
||||
#:reader read
|
||||
#:read-file read-file
|
||||
#:compilers `((,ghil . ,compile-ghil))
|
||||
#:evaluator (lambda (x module) (primitive-eval x))
|
||||
#:printer write)
|
||||
#:title "Guile Scheme"
|
||||
#:version "0.5"
|
||||
#:reader read
|
||||
#:compilers `((tree-il . ,compile-tree-il)
|
||||
(ghil . ,compile-ghil))
|
||||
#:decompilers `((tree-il . ,decompile-tree-il))
|
||||
#:evaluator (lambda (x module) (primitive-eval x))
|
||||
#:printer write)
|
||||
@end example
|
||||
|
||||
In this example, from @code{(language scheme spec)}, @code{read-file}
|
||||
reads expressions from a port and wraps them in a @code{begin} block.
|
||||
@end deffn
|
||||
|
||||
The interesting thing about having languages defined this way is that
|
||||
|
@ -85,12 +84,12 @@ Guile Scheme interpreter 0.5 on Guile 1.9.0
|
|||
Copyright (C) 2001-2008 Free Software Foundation, Inc.
|
||||
|
||||
Enter `,help' for help.
|
||||
scheme@@(guile-user)> ,language ghil
|
||||
Guile High Intermediate Language (GHIL) interpreter 0.3 on Guile 1.9.0
|
||||
scheme@@(guile-user)> ,language tree-il
|
||||
Tree Intermediate Language interpreter 1.0 on Guile 1.9.0
|
||||
Copyright (C) 2001-2008 Free Software Foundation, Inc.
|
||||
|
||||
Enter `,help' for help.
|
||||
ghil@@(guile-user)>
|
||||
tree-il@@(guile-user)>
|
||||
@end example
|
||||
|
||||
Languages can be looked up by name, as they were above.
|
||||
|
@ -128,17 +127,25 @@ The normal tower of languages when compiling Scheme goes like this:
|
|||
|
||||
@itemize
|
||||
@item Scheme, which we know and love
|
||||
@item Guile High Intermediate Language (GHIL)
|
||||
@item Tree Intermediate Language (Tree-IL)
|
||||
@item Guile Low Intermediate Language (GLIL)
|
||||
@item Object code
|
||||
@item Assembly
|
||||
@item Bytecode
|
||||
@item Objcode
|
||||
@end itemize
|
||||
|
||||
Object code may be serialized to disk directly, though it has a cookie
|
||||
and version prepended to the front. But when compiling Scheme at
|
||||
run time, you want a Scheme value, e.g. a compiled procedure. For this
|
||||
reason, so as not to break the abstraction, Guile defines a fake
|
||||
language, @code{value}. Compiling to @code{value} loads the object
|
||||
code into a procedure, and wakes the sleeping giant.
|
||||
and version prepended to the front. But when compiling Scheme at run
|
||||
time, you want a Scheme value: for example, a compiled procedure. For
|
||||
this reason, so as not to break the abstraction, Guile defines a fake
|
||||
language at the bottom of the tower:
|
||||
|
||||
@itemize
|
||||
@item Value
|
||||
@end itemize
|
||||
|
||||
Compiling to @code{value} loads the object code into a procedure, and
|
||||
wakes the sleeping giant.
|
||||
|
||||
Perhaps this strangeness can be explained by example:
|
||||
@code{compile-file} defaults to compiling to object code, because it
|
||||
|
@ -156,340 +163,254 @@ different worlds indefinitely, as shown by the following quine:
|
|||
@node The Scheme Compiler
|
||||
@subsection The Scheme Compiler
|
||||
|
||||
The job of the Scheme compiler is to expand all macros and to resolve
|
||||
all symbols to lexical variables. Its target language, GHIL, is fairly
|
||||
close to Scheme itself, so this process is not very complicated.
|
||||
The job of the Scheme compiler is to expand all macros and all of
|
||||
Scheme to its most primitive expressions. The definition of
|
||||
``primitive'' is given by the inventory of constructs provided by
|
||||
Tree-IL, the target language of the Scheme compiler: procedure
|
||||
applications, conditionals, lexical references, etc. This is described
|
||||
more fully in the next section.
|
||||
|
||||
The Scheme compiler is driven by a table of @dfn{translators},
|
||||
declared with the @code{define-scheme-translator} form, defined in the
|
||||
module, @code{(language scheme compile-ghil)}.
|
||||
The tricky and amusing thing about the Scheme-to-Tree-IL compiler is
|
||||
that it is completely implemented by the macro expander. Since the
|
||||
macro expander has to run over all of the source code already in order
|
||||
to expand macros, it might as well do the analysis at the same time,
|
||||
producing Tree-IL expressions directly.
|
||||
|
||||
@deffn {Scheme Syntax} define-scheme-translator head clause1 clause2...
|
||||
The best documentation of this form is probably an example. Here is
|
||||
the translator for @code{if}:
|
||||
Because this compiler is actually the macro expander, it is
|
||||
extensible. Any macro which the user writes becomes part of the
|
||||
compiler.
|
||||
|
||||
@example
|
||||
(define-scheme-translator if
|
||||
;; (if TEST THEN [ELSE])
|
||||
((,test ,then)
|
||||
(make-ghil-if e l (retrans test) (retrans then) (retrans '(begin))))
|
||||
((,test ,then ,else)
|
||||
(make-ghil-if e l (retrans test) (retrans then) (retrans else))))
|
||||
@end example
|
||||
The Scheme-to-Tree-IL expander may be invoked using the generic
|
||||
@code{compile} procedure:
|
||||
|
||||
The match syntax is from the @code{pmatch} macro, defined in
|
||||
@code{(system base pmatch)}. The result of a clause should be a valid
|
||||
GHIL value. If no clause matches, a syntax error is signalled.
|
||||
@lisp
|
||||
(compile '(+ 1 2) #:from 'scheme #:to 'tree-il)
|
||||
@result{}
|
||||
#<<application> src: #f
|
||||
proc: #<<toplevel-ref> src: #f name: +>
|
||||
args: (#<<const> src: #f exp: 1>
|
||||
#<<const> src: #f exp: 2>)>
|
||||
@end lisp
|
||||
|
||||
In the body of the clauses, the following bindings are introduced:
|
||||
@itemize
|
||||
@item @code{e}, the current environment
|
||||
@item @code{l}, the current source location (or @code{#f})
|
||||
@item @code{retrans}, a procedure that may be called to compile
|
||||
subexpressions
|
||||
@end itemize
|
||||
Or, since Tree-IL is so close to Scheme, it is often useful to expand
|
||||
Scheme to Tree-IL, then translate back to Scheme. For that reason the
|
||||
expander provides two interfaces. The former is equivalent to calling
|
||||
@code{(sc-expand '(+ 1 2) 'c)}, where the @code{'c} is for
|
||||
``compile''. With @code{'e} (the default), the result is translated
|
||||
back to Scheme:
|
||||
|
||||
Note that translators are looked up by @emph{value}, not by name. That
|
||||
is to say, the translator is keyed under the @emph{value} of
|
||||
@code{if}, which normally prints as @code{#<primitive-builtin-macro!
|
||||
if>}.
|
||||
@end deffn
|
||||
@lisp
|
||||
(sc-expand '(+ 1 2))
|
||||
@result{} (+ 1 2)
|
||||
(sc-expand '(let ((x 10)) (* x x)))
|
||||
@result{} (let ((x84 10)) (* x84 x84))
|
||||
@end lisp
|
||||
|
||||
Users can extend the compiler by defining new translators.
|
||||
Additionally, some forms can be inlined directly to
|
||||
instructions -- @xref{Inlined Scheme Instructions}, for a list. The
|
||||
actual inliners are defined in @code{(language scheme inline)}:
|
||||
The second example shows that as part of its job, the macro expander
|
||||
renames lexically-bound variables. The original names are preserved
|
||||
when compiling to Tree-IL, but can't be represented in Scheme: a
|
||||
lexical binding only has one name. It is for this reason that the
|
||||
@emph{native} output of the expander is @emph{not} Scheme. There's too
|
||||
much information we would lose if we translated to Scheme directly:
|
||||
lexical variable names, source locations, and module hygiene.
|
||||
|
||||
@deffn {Scheme Syntax} define-inline head arity1 result1 arity2 result2...
|
||||
Defines an inliner for @code{head}. As in
|
||||
@code{define-scheme-translator}, inliners are keyed by value and not
|
||||
by name.
|
||||
Note however that @code{sc-expand} does not have the same signature as
|
||||
@code{compile-tree-il}. @code{compile-tree-il} is a small wrapper
|
||||
around @code{sc-expand}, to make it conform to the general form of
|
||||
compiler procedures in Guile's language tower.
|
||||
|
||||
Expressions are matched on their arities. For example:
|
||||
Compiler procedures take two arguments, an expression and an
|
||||
environment. They return three values: the compiled expression, the
|
||||
corresponding environment for the target language, and a
|
||||
``continuation environment''. The compiled expression and environment
|
||||
will serve as input to the next language's compiler. The
|
||||
``continuation environment'' can be used to compile another expression
|
||||
from the same source language within the same module.
|
||||
|
||||
@example
|
||||
(define-inline eq?
|
||||
(x y) (eq? x y))
|
||||
@end example
|
||||
For example, you might compile the expression, @code{(define-module
|
||||
(foo))}. This will result in a Tree-IL expression and environment. But
|
||||
if you compiled a second expression, you would want to take into
|
||||
account the compile-time effect of compiling the previous expression,
|
||||
which puts the user in the @code{(foo)} module. That is purpose of the
|
||||
``continuation environment''; you would pass it as the environment
|
||||
when compiling the subsequent expression.
|
||||
|
||||
This inlines calls to the Scheme procedure, @code{eq?}, to the
|
||||
instruction @code{eq?}.
|
||||
|
||||
A more complicated example would be:
|
||||
|
||||
@example
|
||||
(define-inline +
|
||||
() 0
|
||||
(x) x
|
||||
(x y) (add x y)
|
||||
(x y . rest) (add x (+ y . rest)))
|
||||
@end example
|
||||
@end deffn
|
||||
|
||||
Compilers take two arguments, an expression and an environment, and
|
||||
return two values as well: an expression in the target language, and
|
||||
an environment suitable for the target language. The format of the
|
||||
environment is language-dependent.
|
||||
|
||||
For Scheme, an environment may be one of three things:
|
||||
For Scheme, an environment may be one of two things:
|
||||
@itemize
|
||||
@item @code{#f}, in which case compilation is performed in the context
|
||||
of the current module;
|
||||
@item a module, which specifies the context of the compilation; or
|
||||
@item a @dfn{compile environment}, which specifies lexical variables
|
||||
as well.
|
||||
of the current module; or
|
||||
@item a module, which specifies the context of the compilation.
|
||||
@end itemize
|
||||
|
||||
The format of a compile environment for scheme is @code{(@var{module}
|
||||
@var{lexicals} . @var{externals})}, though users are strongly
|
||||
discouraged from constructing these environments themselves. Instead,
|
||||
if you need this functionality -- as in GOOPS' dynamic method compiler
|
||||
-- capture an environment with @code{compile-time-environment}, then
|
||||
pass that environment to @code{compile}.
|
||||
@node Tree-IL
|
||||
@subsection Tree-IL
|
||||
|
||||
@deffn {Scheme Procedure} compile-time-environment
|
||||
A special function known to the compiler that, when compiled, will
|
||||
return a representation of the lexical environment in place at compile
|
||||
time. Useful for supporting some forms of dynamic compilation. Returns
|
||||
@code{#f} if called from the interpreter.
|
||||
@end deffn
|
||||
|
||||
@node GHIL
|
||||
@subsection GHIL
|
||||
|
||||
Guile High Intermediate Language (GHIL) is a structured intermediate
|
||||
Tree Intermediate Language (Tree-IL) is a structured intermediate
|
||||
language that is close in expressive power to Scheme. It is an
|
||||
expanded, pre-analyzed Scheme.
|
||||
|
||||
GHIL is ``structured'' in the sense that its representation is based
|
||||
on records, not S-expressions. This gives a rigidity to the language
|
||||
that ensures that compiling to a lower-level language only requires a
|
||||
limited set of transformations. Practically speaking, consider the
|
||||
GHIL type, @code{<ghil-quote>}, which has fields named @code{env},
|
||||
@code{loc}, and @code{exp}. Instances of this type are records created
|
||||
via @code{make-ghil-quote}, and whose fields are accessed as
|
||||
@code{ghil-quote-env}, @code{ghil-quote-loc}, and
|
||||
@code{ghil-quote-exp}. There is also a predicate, @code{ghil-quote?}.
|
||||
@xref{Records}, for more information on records.
|
||||
Tree-IL is ``structured'' in the sense that its representation is
|
||||
based on records, not S-expressions. This gives a rigidity to the
|
||||
language that ensures that compiling to a lower-level language only
|
||||
requires a limited set of transformations. Practically speaking,
|
||||
consider the Tree-IL type, @code{<const>}, which has two fields,
|
||||
@code{src} and @code{exp}. Instances of this type are records created
|
||||
via @code{make-const}, and whose fields are accessed as
|
||||
@code{const-src}, and @code{const-exp}. There is also a predicate,
|
||||
@code{const?}. @xref{Records}, for more information on records.
|
||||
|
||||
Expressions of GHIL name their environments explicitly, and all
|
||||
variables are referenced by identity in addition to by name.
|
||||
@code{(language ghil)} defines a number of routines to deal explicitly
|
||||
with variables and environments:
|
||||
@c alpha renaming
|
||||
|
||||
@deftp {Scheme Variable} <ghil-toplevel-env> [table='()]
|
||||
A toplevel environment. The @var{table} holds all toplevel variables
|
||||
that have been resolved in this environment.
|
||||
@end deftp
|
||||
@deftp {Scheme Variable} <ghil-env> parent [table='()] [variables='()]
|
||||
A lexical environment. @var{parent} will be the enclosing lexical
|
||||
environment, or a toplevel environment. @var{table} holds an alist
|
||||
mapping symbols to variables bound in this environment, while
|
||||
@var{variables} holds a cumulative list of all variables ever defined
|
||||
in this environment.
|
||||
All Tree-IL types have a @code{src} slot, which holds source location
|
||||
information for the expression. This information, if present, will be
|
||||
residualized into the compiled object code, allowing backtraces to
|
||||
show source information. The format of @code{src} is the same as that
|
||||
returned by Guile's @code{source-properties} function. @xref{Source
|
||||
Properties}, for more information.
|
||||
|
||||
Lexical environments correspond to procedures. Bindings introduced
|
||||
e.g. by Scheme's @code{let} add to the bindings in a lexical
|
||||
environment. An example of a case in which a variable might be in
|
||||
@var{variables} but not in @var{table} would be a variable that is in
|
||||
the same procedure, but is out of scope.
|
||||
@end deftp
|
||||
@deftp {Scheme Variable} <ghil-var> env name kind [index=#f]
|
||||
A variable. @var{kind} is one of @code{argument}, @code{local},
|
||||
@code{external}, @code{toplevel}, @code{public}, or @code{private};
|
||||
see the procedures below for more information. @var{index} is used in
|
||||
compilation.
|
||||
@end deftp
|
||||
|
||||
@deffn {Scheme Procedure} ghil-var-is-bound? env sym
|
||||
Recursively look up a variable named @var{sym} in @var{env}, and
|
||||
return it or @code{#f} if none is found.
|
||||
@end deffn
|
||||
@deffn {Scheme Procedure} ghil-var-for-ref! env sym
|
||||
Recursively look up a variable named @var{sym} in @var{env}, and
|
||||
return it. If the symbol was not bound, return a new toplevel
|
||||
variable.
|
||||
@end deffn
|
||||
@deffn {Scheme Procedure} ghil-var-for-set! env sym
|
||||
Like @code{ghil-var-for-ref!}, except that the returned variable will
|
||||
be marked as @code{external}. @xref{Variables and the VM}.
|
||||
@end deffn
|
||||
@deffn {Scheme Procedure} ghil-var-define! toplevel-env sym
|
||||
Return an existing or new toplevel variable named @var{sym}.
|
||||
@var{toplevel-env} must be a toplevel environment.
|
||||
@end deffn
|
||||
@deffn {Scheme Procedure} ghil-var-at-module! env modname sym interface?
|
||||
Return a variable that will be resolved at run-time with respect to a
|
||||
specific module named @var{modname}. If @var{interface?} is true, the
|
||||
variable will be of type @code{public}, otherwise @code{private}.
|
||||
@end deffn
|
||||
@deffn {Scheme Procedure} call-with-ghil-environment env syms func
|
||||
Bind @var{syms} to fresh variables within a new lexical environment
|
||||
whose parent is @var{env}, and call @var{func} as @code{(@var{func}
|
||||
@var{new-env} @var{new-vars})}.
|
||||
@end deffn
|
||||
@deffn {Scheme Procedure} call-with-ghil-bindings env syms func
|
||||
Like @code{call-with-ghil-environment}, except the existing
|
||||
environment @var{env} is re-used. For that reason, @var{func} is
|
||||
invoked as @code{(@var{func} @var{new-vars})}
|
||||
@end deffn
|
||||
|
||||
In the aforementioned @code{<ghil-quote>} type, the @var{env} slot
|
||||
holds a pointer to the environment in which the expression occurs. The
|
||||
@var{loc} slot holds source location information, so that errors
|
||||
corresponding to this expression can be mapped back to the initial
|
||||
expression in the higher-level language, e.g. Scheme. @xref{Compiled
|
||||
Procedures}, for more information on source location objects.
|
||||
|
||||
GHIL also has a declarative serialization format, which makes writing
|
||||
and reading it a tractable problem for the human mind. Since all GHIL
|
||||
language constructs contain @code{env} and @code{loc} pointers, they
|
||||
are left out of the serialization. (Serializing @code{env} structures
|
||||
would be difficult, as they are often circular.) What is left is the
|
||||
type of expression, and the remaining slots defined in the expression
|
||||
type.
|
||||
|
||||
For example, an S-expression representation of the @code{<ghil-quote>}
|
||||
expression would be:
|
||||
Although Tree-IL objects are represented internally using records,
|
||||
there is also an equivalent S-expression external representation for
|
||||
each kind of Tree-IL. For example, an the S-expression representation
|
||||
of @code{#<const src: #f exp: 3>} expression would be:
|
||||
|
||||
@example
|
||||
(quote 3)
|
||||
(const 3)
|
||||
@end example
|
||||
|
||||
It's deceptively like Scheme. The general rule is, for a type defined
|
||||
as @code{<ghil-@var{foo}> env loc @var{slot1} @var{slot2}...}, the
|
||||
S-expression representation will be @code{(@var{foo} @var{slot1}
|
||||
@var{slot2}...)}. Users may program with this format directly at the
|
||||
REPL:
|
||||
Users may program with this format directly at the REPL:
|
||||
|
||||
@example
|
||||
scheme@@(guile-user)> ,language ghil
|
||||
Guile High Intermediate Language (GHIL) interpreter 0.3 on Guile 1.9.0
|
||||
scheme@@(guile-user)> ,language tree-il
|
||||
Tree Intermediate Language interpreter 1.0 on Guile 1.9.0
|
||||
Copyright (C) 2001-2008 Free Software Foundation, Inc.
|
||||
|
||||
Enter `,help' for help.
|
||||
ghil@@(guile-user)> (call (ref +) (quote 32) (quote 10))
|
||||
tree-il@@(guile-user)> (apply (primitive +) (const 32) (const 10))
|
||||
@result{} 42
|
||||
@end example
|
||||
|
||||
For convenience, some slots are serialized as rest arguments; those
|
||||
are noted below. The other caveat is that variables are serialized as
|
||||
their names only, and not their identities.
|
||||
The @code{src} fields are left out of the external representation.
|
||||
|
||||
@deftp {Scheme Variable} <ghil-void> env loc
|
||||
The unspecified value.
|
||||
@deftp {Scheme Variable} <void> src
|
||||
@deftpx {External Representation} (void)
|
||||
An empty expression. In practice, equivalent to Scheme's @code{(if #f
|
||||
#f)}.
|
||||
@end deftp
|
||||
@deftp {Scheme Variable} <ghil-quote> env loc exp
|
||||
A quoted expression.
|
||||
@deftp {Scheme Variable} <const> src exp
|
||||
@deftpx {External Representation} (const @var{exp})
|
||||
A constant.
|
||||
@end deftp
|
||||
@deftp {Scheme Variable} <primitive-ref> src name
|
||||
@deftpx {External Representation} (primitive @var{name})
|
||||
A reference to a ``primitive''. A primitive is a procedure that, when
|
||||
compiled, may be open-coded. For example, @code{cons} is usually
|
||||
recognized as a primitive, so that it compiles down to a single
|
||||
instruction.
|
||||
|
||||
Note that unlike in Scheme, there are no self-quoting expressions; all
|
||||
constants must come from @code{quote} expressions.
|
||||
Compilation of Tree-IL usually begins with a pass that resolves some
|
||||
@code{<module-ref>} and @code{<toplevel-ref>} expressions to
|
||||
@code{<primitive-ref>} expressions. The actual compilation pass
|
||||
has special cases for applications of certain primitives, like
|
||||
@code{apply} or @code{cons}.
|
||||
@end deftp
|
||||
@deftp {Scheme Variable} <ghil-quasiquote> env loc exp
|
||||
A quasiquoted expression. The expression is treated as a constant,
|
||||
except for embedded @code{unquote} and @code{unquote-splicing} forms.
|
||||
@deftp {Scheme Variable} <lexical-ref> src name gensym
|
||||
@deftpx {External Representation} (lexical @var{name} @var{gensym})
|
||||
A reference to a lexically-bound variable. The @var{name} is the
|
||||
original name of the variable in the source program. @var{gensym} is a
|
||||
unique identifier for this variable.
|
||||
@end deftp
|
||||
@deftp {Scheme Variable} <ghil-unquote> env loc exp
|
||||
Like Scheme's @code{unquote}; only valid within a quasiquote.
|
||||
@deftp {Scheme Variable} <lexical-set> src name gensym exp
|
||||
@deftpx {External Representation} (set! (lexical @var{name} @var{gensym}) @var{exp})
|
||||
Sets a lexically-bound variable.
|
||||
@end deftp
|
||||
@deftp {Scheme Variable} <ghil-unquote-splicing> env loc exp
|
||||
Like Scheme's @code{unquote-splicing}; only valid within a quasiquote.
|
||||
@deftp {Scheme Variable} <module-ref> src mod name public?
|
||||
@deftpx {External Representation} (@@ @var{mod} @var{name})
|
||||
@deftpx {External Representation} (@@@@ @var{mod} @var{name})
|
||||
A reference to a variable in a specific module. @var{mod} should be
|
||||
the name of the module, e.g. @code{(guile-user)}.
|
||||
|
||||
If @var{public?} is true, the variable named @var{name} will be looked
|
||||
up in @var{mod}'s public interface, and serialized with @code{@@};
|
||||
otherwise it will be looked up among the module's private bindings,
|
||||
and is serialized with @code{@@@@}.
|
||||
@end deftp
|
||||
@deftp {Scheme Variable} <ghil-ref> env loc var
|
||||
A variable reference. Note that for purposes of serialization,
|
||||
@var{var} is serialized as its name, as a symbol.
|
||||
@deftp {Scheme Variable} <module-set> src mod name public? exp
|
||||
@deftpx {External Representation} (set! (@@ @var{mod} @var{name}) @var{exp})
|
||||
@deftpx {External Representation} (set! (@@@@ @var{mod} @var{name}) @var{exp})
|
||||
Sets a variable in a specific module.
|
||||
@end deftp
|
||||
@deftp {Scheme Variable} <ghil-set> env loc var val
|
||||
A variable mutation. @var{var} is serialized as a symbol.
|
||||
@deftp {Scheme Variable} <toplevel-ref> src name
|
||||
@deftpx {External Representation} (toplevel @var{name})
|
||||
References a variable from the current procedure's module.
|
||||
@end deftp
|
||||
@deftp {Scheme Variable} <ghil-define> env loc var val
|
||||
A toplevel variable definition. See @code{ghil-var-define!}.
|
||||
@deftp {Scheme Variable} <toplevel-set> src name exp
|
||||
@deftpx {External Representation} (set! (toplevel @var{name}) @var{exp})
|
||||
Sets a variable in the current procedure's module.
|
||||
@end deftp
|
||||
@deftp {Scheme Variable} <ghil-if> env loc test then else
|
||||
@deftp {Scheme Variable} <toplevel-define> src name exp
|
||||
@deftpx {External Representation} (define (toplevel @var{name}) @var{exp})
|
||||
Defines a new top-level variable in the current procedure's module.
|
||||
@end deftp
|
||||
@deftp {Scheme Variable} <conditional> src test then else
|
||||
@deftpx {External Representation} (if @var{test} @var{then} @var{else})
|
||||
A conditional. Note that @var{else} is not optional.
|
||||
@end deftp
|
||||
@deftp {Scheme Variable} <ghil-and> env loc . exps
|
||||
Like Scheme's @code{and}.
|
||||
@end deftp
|
||||
@deftp {Scheme Variable} <ghil-or> env loc . exps
|
||||
Like Scheme's @code{or}.
|
||||
@end deftp
|
||||
@deftp {Scheme Variable} <ghil-begin> env loc . body
|
||||
Like Scheme's @code{begin}.
|
||||
@end deftp
|
||||
@deftp {Scheme Variable} <ghil-bind> env loc vars exprs . body
|
||||
Like a deconstructed @code{let}: each element of @var{vars} will be
|
||||
bound to the corresponding GHIL expression in @var{exprs}.
|
||||
|
||||
Note that for purposes of the serialization format, @var{exprs} are
|
||||
evaluated before the new bindings are added to the environment. For
|
||||
@code{letrec} semantics, there also exists a @code{bindrec} parse
|
||||
flavor. This is useful for writing GHIL at the REPL, but the
|
||||
serializer does not currently have the cleverness needed to determine
|
||||
whether a @code{<ghil-bind>} has @code{let} or @code{letrec}
|
||||
semantics, and thus only serializes @code{<ghil-bind>} as @code{bind}.
|
||||
@end deftp
|
||||
@deftp {Scheme Variable} <ghil-mv-bind> env loc vars rest producer . body
|
||||
Like Scheme's @code{receive} -- binds the values returned by
|
||||
applying @code{producer}, which should be a thunk, to the
|
||||
@code{lambda}-like bindings described by @var{vars} and @var{rest}.
|
||||
@end deftp
|
||||
@deftp {Scheme Variable} <ghil-lambda> env loc vars rest meta . body
|
||||
A closure. @var{vars} is the argument list, serialized as a list of
|
||||
symbols. @var{rest} is a boolean, which is @code{#t} iff the last
|
||||
argument is a rest argument. @var{meta} is an association list of
|
||||
properties. The actual @var{body} should be a list of GHIL
|
||||
expressions.
|
||||
@end deftp
|
||||
@deftp {Scheme Variable} <ghil-call> env loc proc . args
|
||||
@deftp {Scheme Variable} <application> src proc args
|
||||
@deftpx {External Representation} (apply @var{proc} . @var{args})
|
||||
A procedure call.
|
||||
@end deftp
|
||||
@deftp {Scheme Variable} <ghil-mv-call> env loc producer consumer
|
||||
Like Scheme's @code{call-with-values}.
|
||||
@deftp {Scheme Variable} <sequence> src exps
|
||||
@deftpx {External Representation} (begin . @var{exps})
|
||||
Like Scheme's @code{begin}.
|
||||
@end deftp
|
||||
@deftp {Scheme Variable} <ghil-inline> env loc op . args
|
||||
An inlined VM instruction. @var{op} should be the instruction name as
|
||||
a symbol, and @var{args} should be its arguments, as GHIL expressions.
|
||||
@deftp {Scheme Variable} <lambda> src names vars meta body
|
||||
@deftpx {External Representation} (lambda @var{names} @var{vars} @var{meta} @var{body})
|
||||
A closure. @var{names} is original binding form, as given in the
|
||||
source code, which may be an improper list. @var{vars} are gensyms
|
||||
corresponding to the @var{names}. @var{meta} is an association list of
|
||||
properties. The actual @var{body} is a single Tree-IL expression.
|
||||
@end deftp
|
||||
@deftp {Scheme Variable} <ghil-values> env loc . values
|
||||
Like Scheme's @code{values}.
|
||||
@deftp {Scheme Variable} <let> src names vars vals exp
|
||||
@deftpx {External Representation} (let @var{names} @var{vars} @var{vals} @var{exp})
|
||||
Lexical binding, like Scheme's @code{let}. @var{names} are the
|
||||
original binding names, @var{vars} are gensyms corresponding to the
|
||||
@var{names}, and @var{vals} are Tree-IL expressions for the values.
|
||||
@var{exp} is a single Tree-IL expression.
|
||||
@end deftp
|
||||
@deftp {Scheme Variable} <ghil-values*> env loc . values
|
||||
@var{values} are as in the Scheme expression, @code{(apply values .
|
||||
@var{vals})}.
|
||||
@end deftp
|
||||
@deftp {Scheme Variable} <ghil-reified-env> env loc
|
||||
Produces, at run-time, a reification of the environment at compile
|
||||
time. Used in the implementation of Scheme's
|
||||
@code{compile-time-environment}.
|
||||
@deftp {Scheme Variable} <letrec> src names vars vals exp
|
||||
@deftpx {External Representation} (letrec @var{names} @var{vars} @var{vals} @var{exp})
|
||||
A version of @code{<let>} that creates recursive bindings, like
|
||||
Scheme's @code{letrec}.
|
||||
@end deftp
|
||||
|
||||
GHIL implements a compiler to GLIL that recursively traverses GHIL
|
||||
expressions, writing out GLIL expressions into a linear list. The
|
||||
compiler also keeps some state as to whether the current expression is
|
||||
in tail context, and whether its value will be used in future
|
||||
computations. This state allows the compiler not to emit code for
|
||||
constant expressions that will not be used (e.g. docstrings), and to
|
||||
perform tail calls when in tail position.
|
||||
@c FIXME -- need to revive this one
|
||||
@c @deftp {Scheme Variable} <ghil-mv-bind> src vars rest producer . body
|
||||
@c Like Scheme's @code{receive} -- binds the values returned by
|
||||
@c applying @code{producer}, which should be a thunk, to the
|
||||
@c @code{lambda}-like bindings described by @var{vars} and @var{rest}.
|
||||
@c @end deftp
|
||||
|
||||
Just as the Scheme to GHIL compiler introduced new hidden state---the
|
||||
environment---the GHIL to GLIL compiler introduces more state, the
|
||||
stack. While not represented explicitly, the stack is present in the
|
||||
compilation of each GHIL expression: compiling a GHIL expression
|
||||
should leave the run-time value stack in the same state. For example,
|
||||
if the intermediate value stack has two elements before evaluating an
|
||||
@code{if} expression, it should have two elements after that
|
||||
expression.
|
||||
Tree-IL implements a compiler to GLIL that recursively traverses
|
||||
Tree-IL expressions, writing out GLIL expressions into a linear list.
|
||||
The compiler also keeps some state as to whether the current
|
||||
expression is in tail context, and whether its value will be used in
|
||||
future computations. This state allows the compiler not to emit code
|
||||
for constant expressions that will not be used (e.g. docstrings), and
|
||||
to perform tail calls when in tail position.
|
||||
|
||||
In the future, there will be a pass at the beginning of the
|
||||
Tree-IL->GLIL compilation step to perform inlining, copy propagation,
|
||||
dead code elimination, and constant folding.
|
||||
|
||||
Interested readers are encouraged to read the implementation in
|
||||
@code{(language ghil compile-glil)} for more details.
|
||||
@code{(language tree-il compile-glil)} for more details.
|
||||
|
||||
@node GLIL
|
||||
@subsection GLIL
|
||||
|
||||
Guile Low Intermediate Language (GLIL) is a structured intermediate
|
||||
language whose expressions closely mirror the functionality of Guile's
|
||||
VM instruction set.
|
||||
language whose expressions more closely approximate Guile's VM
|
||||
instruction set.
|
||||
|
||||
Its expression types are defined in @code{(language glil)}, and as
|
||||
with GHIL, some of its fields parse as rest arguments.
|
||||
|
@ -499,8 +420,8 @@ A unit of code that at run-time will correspond to a compiled
|
|||
procedure. @var{nargs} @var{nrest} @var{nlocs}, and @var{nexts}
|
||||
collectively define the program's arity; see @ref{Compiled
|
||||
Procedures}, for more information. @var{meta} should be an alist of
|
||||
properties, as in @code{<ghil-lambda>}. @var{body} is a list of GLIL
|
||||
expressions.
|
||||
properties, as in Tree IL's @code{<lambda>}. @var{body} is a list of
|
||||
GLIL expressions.
|
||||
@end deftp
|
||||
@deftp {Scheme Variable} <glil-bind> . vars
|
||||
An advisory expression that notes a liveness extent for a set of
|
||||
|
@ -534,24 +455,23 @@ offset within a VM program.
|
|||
@end deftp
|
||||
@deftp {Scheme Variable} <glil-source> loc
|
||||
Records source information for the preceding expression. @var{loc}
|
||||
should be a vector, @code{#(@var{line} @var{column} @var{filename})}.
|
||||
should be an association list of containing @code{line} @code{column},
|
||||
and @code{filename} keys, e.g. as returned by
|
||||
@code{source-properties}.
|
||||
@end deftp
|
||||
@deftp {Scheme Variable} <glil-void>
|
||||
Pushes the unspecified value on the stack.
|
||||
@end deftp
|
||||
@deftp {Scheme Variable} <glil-const> obj
|
||||
Pushes a constant value onto the stack. @var{obj} must be a number,
|
||||
string, symbol, keyword, boolean, character, or a pair or vector or
|
||||
list thereof, or the empty list.
|
||||
@end deftp
|
||||
@deftp {Scheme Variable} <glil-argument> op index
|
||||
Accesses an argument on the stack. If @var{op} is @code{ref}, the
|
||||
argument is pushed onto the stack; if it is @code{set}, the argument
|
||||
is set from the top value on the stack, which is popped off.
|
||||
string, symbol, keyword, boolean, character, the empty list, or a pair
|
||||
or vector of constants.
|
||||
@end deftp
|
||||
@deftp {Scheme Variable} <glil-local> op index
|
||||
Like @code{<glil-argument>}, but for local variables. @xref{Stack
|
||||
Layout}, for more information.
|
||||
Accesses a lexically bound variable from the stack. If @var{op} is
|
||||
@code{ref}, the value is pushed onto the stack; if it is @code{set},
|
||||
the variable is set from the top value on the stack, which is popped
|
||||
off. @xref{Stack Layout}, for more information.
|
||||
@end deftp
|
||||
@deftp {Scheme Variable} <glil-external> op depth index
|
||||
Accesses a heap-allocated variable, addressed by @var{depth}, the nth
|
||||
|
@ -563,8 +483,8 @@ Accesses a toplevel variable. @var{op} may be @code{ref}, @code{set},
|
|||
or @code{define}.
|
||||
@end deftp
|
||||
@deftp {Scheme Variable} <glil-module> op mod name public?
|
||||
Accesses a variable within a specific module. See
|
||||
@code{ghil-var-at-module!}, for more information.
|
||||
Accesses a variable within a specific module. See Tree-IL's
|
||||
@code{<module-ref>}, for more information.
|
||||
@end deftp
|
||||
@deftp {Scheme Variable} <glil-label> label
|
||||
Creates a new label. @var{label} can be any Scheme value, and should
|
||||
|
@ -607,23 +527,143 @@ Just as in all of Guile's compilers, an environment is passed to the
|
|||
GLIL-to-object code compiler, and one is returned as well, along with
|
||||
the object code.
|
||||
|
||||
@node Object Code
|
||||
@subsection Object Code
|
||||
@node Assembly
|
||||
@subsection Assembly
|
||||
|
||||
Object code is the serialization of the raw instruction stream of a
|
||||
program, ready for interpretation by the VM. Procedures related to
|
||||
object code are defined in the @code{(system vm objcode)} module.
|
||||
Assembly is an S-expression-based, human-readable representation of
|
||||
the actual bytecodes that will be emitted for the VM. As such, it is a
|
||||
useful intermediate language both for compilation and for
|
||||
decompilation.
|
||||
|
||||
Besides the fact that it is not a record-based language, assembly
|
||||
differs from GLIL in four main ways:
|
||||
|
||||
@itemize
|
||||
@item Labels have been resolved to byte offsets in the program.
|
||||
@item Constants inside procedures have either been expressed as inline
|
||||
instructions, and possibly cached in object arrays.
|
||||
@item Procedures with metadata (source location information, liveness
|
||||
extents, procedure names, generic properties, etc) have had their
|
||||
metadata serialized out to thunks.
|
||||
@item All expressions correspond directly to VM instructions -- i.e.,
|
||||
there is no @code{<glil-local>} which can be a ref or a set.
|
||||
@end itemize
|
||||
|
||||
Assembly is isomorphic to the bytecode that it compiles to. You can
|
||||
compile to bytecode, then decompile back to assembly, and you have the
|
||||
same assembly code.
|
||||
|
||||
The general form of assembly instructions is the following:
|
||||
|
||||
@lisp
|
||||
(@var{inst} @var{arg} ...)
|
||||
@end lisp
|
||||
|
||||
The @var{inst} names a VM instruction, and its @var{arg}s will be
|
||||
embedded in the instruction stream. The easiest way to see assembly is
|
||||
to play around with it at the REPL, as can be seen in this annotated
|
||||
example:
|
||||
|
||||
@example
|
||||
scheme@@(guile-user)> (compile '(lambda (x) (+ x x)) #:to 'assembly)
|
||||
(load-program 0 0 0 0
|
||||
() ; Labels
|
||||
60 ; Length
|
||||
#f ; Metadata
|
||||
(make-false) ; object table for the returned lambda
|
||||
(nop)
|
||||
(nop) ; Alignment. Since assembly has already resolved its labels
|
||||
(nop) ; to offsets, and programs must be 8-byte aligned since their
|
||||
(nop) ; object code is mmap'd directly to structures, assembly
|
||||
(nop) ; has to have the alignment embedded in it.
|
||||
(nop)
|
||||
(load-program 1 0 0 0
|
||||
()
|
||||
6
|
||||
; This is the metadata thunk for the returned procedure.
|
||||
(load-program 0 0 0 0 () 21 #f
|
||||
(load-symbol "x") ; Name and liveness extent for @code{x}.
|
||||
(make-false)
|
||||
(make-int8:0) ; Some instruction+arg combinations
|
||||
(make-int8:0) ; have abbreviations.
|
||||
(make-int8 6)
|
||||
(list 0 5)
|
||||
(list 0 1)
|
||||
(make-eol)
|
||||
(list 0 2)
|
||||
(return))
|
||||
; And here, the actual code.
|
||||
(local-ref 0)
|
||||
(local-ref 0)
|
||||
(add)
|
||||
(return))
|
||||
; Return our new procedure.
|
||||
(return))
|
||||
@end example
|
||||
|
||||
Of course you can switch the REPL to assembly and enter in assembly
|
||||
S-expressions directly, like with other languages, though it is more
|
||||
difficult, given that the length fields have to be correct.
|
||||
|
||||
@node Bytecode and Objcode
|
||||
@subsection Bytecode and Objcode
|
||||
|
||||
Finally, the raw bytes. There are actually two different ``languages''
|
||||
here, corresponding to two different ways to represent the bytes.
|
||||
|
||||
``Bytecode'' represents code as uniform byte vectors, useful for
|
||||
structuring and destructuring code on the Scheme level. Bytecode is
|
||||
the next step down from assembly:
|
||||
|
||||
@example
|
||||
scheme@@(guile-user)> (compile '(+ 32 10) #:to 'assembly)
|
||||
@result{} (load-program 0 0 0 0 () 6 #f
|
||||
(make-int8 32) (make-int8 10) (add) (return))
|
||||
scheme@@(guile-user)> (compile '(+ 32 10) #:to 'bytecode)
|
||||
@result{} #u8(0 0 0 0 6 0 0 0 0 0 0 0 10 32 10 10 100 48)
|
||||
@end example
|
||||
|
||||
``Objcode'' is bytecode, but mapped directly to a C structure,
|
||||
@code{struct scm_objcode}:
|
||||
|
||||
@example
|
||||
struct scm_objcode @{
|
||||
scm_t_uint8 nargs;
|
||||
scm_t_uint8 nrest;
|
||||
scm_t_uint8 nlocs;
|
||||
scm_t_uint8 nexts;
|
||||
scm_t_uint32 len;
|
||||
scm_t_uint32 metalen;
|
||||
scm_t_uint8 base[0];
|
||||
@};
|
||||
@end example
|
||||
|
||||
As one might imagine, objcode imposes a minimum length on the
|
||||
bytecode. Also, the multibyte fields are in native endianness, which
|
||||
makes objcode (and bytecode) system-dependent. Indeed, in the short
|
||||
example above, all but the last 5 bytes were the program's header.
|
||||
|
||||
Objcode also has a couple of important efficiency hacks. First,
|
||||
objcode may be mapped directly from disk, allowing compiled code to be
|
||||
loaded quickly, often from the system's disk cache, and shared among
|
||||
multiple processes. Secondly, objcode may be embedded in other
|
||||
objcode, allowing procedures to have the text of other procedures
|
||||
inlined into their bodies, without the need for separate allocation of
|
||||
the code. Of course, the objcode object itself does need to be
|
||||
allocated.
|
||||
|
||||
Procedures related to objcode are defined in the @code{(system vm
|
||||
objcode)} module.
|
||||
|
||||
@deffn {Scheme Procedure} objcode? obj
|
||||
@deffnx {C Function} scm_objcode_p (obj)
|
||||
Returns @code{#f} iff @var{obj} is object code, @code{#f} otherwise.
|
||||
@end deffn
|
||||
|
||||
@deffn {Scheme Procedure} bytecode->objcode bytecode nlocs nexts
|
||||
@deffnx {C Function} scm_bytecode_to_objcode (bytecode, nlocs, nexts)
|
||||
@deffn {Scheme Procedure} bytecode->objcode bytecode
|
||||
@deffnx {C Function} scm_bytecode_to_objcode (bytecode,)
|
||||
Makes a bytecode object from @var{bytecode}, which should be a
|
||||
@code{u8vector}. @var{nlocs} and @var{nexts} denote the number of
|
||||
stack and heap variables to reserve when this objcode is executed.
|
||||
@code{u8vector}.
|
||||
@end deffn
|
||||
|
||||
@deffn {Scheme Variable} load-objcode file
|
||||
|
@ -631,21 +671,28 @@ stack and heap variables to reserve when this objcode is executed.
|
|||
Load object code from a file named @var{file}. The file will be mapped
|
||||
into memory via @code{mmap}, so this is a very fast operation.
|
||||
|
||||
On disk, object code has an eight-byte cookie prepended to it, so that
|
||||
we will not execute arbitrary garbage. In addition, two more bytes are
|
||||
reserved for @var{nlocs} and @var{nexts}.
|
||||
On disk, object code has an eight-byte cookie prepended to it, to
|
||||
prevent accidental loading of arbitrary garbage.
|
||||
@end deffn
|
||||
|
||||
@deffn {Scheme Variable} write-objcode objcode file
|
||||
@deffnx {C Function} scm_write_objcode (objcode)
|
||||
Write object code out to a file, prepending the eight-byte cookie.
|
||||
@end deffn
|
||||
|
||||
@deffn {Scheme Variable} objcode->u8vector objcode
|
||||
@deffnx {C Function} scm_objcode_to_u8vector (objcode)
|
||||
Copy object code out to a @code{u8vector} for analysis by Scheme. The
|
||||
ten-byte header is included.
|
||||
Copy object code out to a @code{u8vector} for analysis by Scheme.
|
||||
@end deffn
|
||||
|
||||
@deffn {Scheme Variable} objcode->program objcode [external='()]
|
||||
@deffnx {C Function} scm_objcode_to_program (objcode, external)
|
||||
The following procedure is actually in @code{(system vm program)}, but
|
||||
we'll mention it here:
|
||||
|
||||
@deffn {Scheme Variable} make-program objcode objtable [external='()]
|
||||
@deffnx {C Function} scm_make_program (objcode, objtable, external)
|
||||
Load up object code into a Scheme program. The resulting program will
|
||||
be a thunk that captures closure variables from @var{external}.
|
||||
have @var{objtable} as its object table, which should be a vector or
|
||||
@code{#f}, and will capture the closure variables from @var{external}.
|
||||
@end deffn
|
||||
|
||||
Object code from a file may be disassembled at the REPL via the
|
||||
|
@ -689,7 +736,7 @@ fruit, running programs of interest under a system-level profiler and
|
|||
determining which improvements would give the most bang for the buck.
|
||||
There are many well-known efficiency hacks in the literature: Dybvig's
|
||||
letrec optimization, individual boxing of heap-allocated values (and
|
||||
then store the boxes on the stack directory), optimized case-lambda
|
||||
then store the boxes on the stack directly), optimized case-lambda
|
||||
expressions, stack underflow and overflow handlers, etc. Highly
|
||||
recommended papers: Dybvig's HOCS, Ghuloum's compiler paper.
|
||||
|
||||
|
|
164
doc/ref/vm.texi
164
doc/ref/vm.texi
|
@ -111,7 +111,7 @@ The registers that a VM has are as follows:
|
|||
In other architectures, the instruction pointer is sometimes called
|
||||
the ``program counter'' (pc). This set of registers is pretty typical
|
||||
for stack machines; their exact meanings in the context of Guile's VM
|
||||
is described in the next section.
|
||||
are described in the next section.
|
||||
|
||||
A virtual machine executes by loading a compiled procedure, and
|
||||
executing the object code associated with that procedure. Of course,
|
||||
|
@ -119,14 +119,17 @@ that procedure may call other procedures, tail-call others, ad
|
|||
infinitum---indeed, within a guile whose modules have all been
|
||||
compiled to object code, one might never leave the virtual machine.
|
||||
|
||||
@c wingo: I wish the following were true, but currently we just use
|
||||
@c the one engine. This kind of thing is possible tho.
|
||||
@c wingo: The following is true, but I don't know in what context to
|
||||
@c describe it. A documentation FIXME.
|
||||
|
||||
@c A VM may have one of three engines: reckless, regular, or debugging.
|
||||
@c Reckless engine is fastest but dangerous. Regular engine is normally
|
||||
@c fail-safe and reasonably fast. Debugging engine is safest and
|
||||
@c functional but very slow.
|
||||
|
||||
@c (Actually we have just a regular and a debugging engine; normally
|
||||
@c we use the latter, it's almost as fast as the ``regular'' engine.)
|
||||
|
||||
@node Stack Layout
|
||||
@subsection Stack Layout
|
||||
|
||||
|
@ -174,7 +177,7 @@ The structure of the fixed part of an application frame is as follows:
|
|||
In the above drawing, the stack grows upward. The intermediate values
|
||||
stored in the application of this frame are stored above
|
||||
@code{SCM_FRAME_UPPER_ADDRESS (fp)}. @code{bp} refers to the
|
||||
@code{struct scm_program*} data associated with the program at
|
||||
@code{struct scm_objcode} data associated with the program at
|
||||
@code{fp - 1}. @code{nargs} and @code{nlocs} are properties of the
|
||||
compiled procedure, which will be discussed later.
|
||||
|
||||
|
@ -226,7 +229,7 @@ programs are implemented, @xref{VM Programs}.
|
|||
@node Variables and the VM
|
||||
@subsection Variables and the VM
|
||||
|
||||
Let's think about the following Scheme code as an example:
|
||||
Consider the following Scheme code as an example:
|
||||
|
||||
@example
|
||||
(define (foo a)
|
||||
|
@ -236,22 +239,15 @@ Let's think about the following Scheme code as an example:
|
|||
Within the lambda expression, "foo" is a top-level variable, "a" is a
|
||||
lexically captured variable, and "b" is a local variable.
|
||||
|
||||
That is to say: @code{b} may safely be allocated on the stack, as
|
||||
there is no enclosed procedure that references it, nor is it ever
|
||||
mutated.
|
||||
@code{b} may safely be allocated on the stack, as there is no enclosed
|
||||
procedure that references it, nor is it ever mutated.
|
||||
|
||||
@code{a}, on the other hand, is referenced by an enclosed procedure,
|
||||
that of the lambda. Thus it must be allocated on the heap, as it may
|
||||
(and will) outlive the dynamic extent of the invocation of @code{foo}.
|
||||
|
||||
@code{foo} is a toplevel variable, as mandated by Scheme's semantics:
|
||||
|
||||
@example
|
||||
(define proc (foo 'bar)) ; assuming prev. definition of @code{foo}
|
||||
(define foo 42) ; redefinition
|
||||
(proc 'baz)
|
||||
@result{} (42 bar baz)
|
||||
@end example
|
||||
@code{foo} is a top-level variable, because it names the procedure
|
||||
@code{foo}, which is here defined at the top-level.
|
||||
|
||||
Note that variables that are mutated (via @code{set!}) must be
|
||||
allocated on the heap, even if they are local variables. This is
|
||||
|
@ -276,6 +272,7 @@ You can pick apart these pieces with the accessors in @code{(system vm
|
|||
program)}. @xref{Compiled Procedures}, for a full API reference.
|
||||
|
||||
@cindex object table
|
||||
@cindex object array
|
||||
The object array of a compiled procedure, also known as the
|
||||
@dfn{object table}, holds all Scheme objects whose values are known
|
||||
not to change across invocations of the procedure: constant strings,
|
||||
|
@ -293,31 +290,27 @@ instruction, which uses the object vector, and are almost as fast as
|
|||
local variable references.
|
||||
|
||||
We can see how these concepts tie together by disassembling the
|
||||
@code{foo} function to see what is going on:
|
||||
@code{foo} function we defined earlier to see what is going on:
|
||||
|
||||
@smallexample
|
||||
scheme@@(guile-user)> (define (foo a) (lambda (b) (list foo a b)))
|
||||
scheme@@(guile-user)> ,x foo
|
||||
Disassembly of #<program foo (a)>:
|
||||
|
||||
Bytecode:
|
||||
|
||||
0 (local-ref 0) ;; `a' (arg)
|
||||
2 (external-set 0) ;; `a' (arg)
|
||||
4 (object-ref 0) ;; #<program #(0 28 #f) (b)>
|
||||
6 (make-closure) at (unknown file):0:16
|
||||
4 (object-ref 1) ;; #<program b70d2910 at <unknown port>:0:16 (b)>
|
||||
6 (make-closure)
|
||||
7 (return)
|
||||
|
||||
----------------------------------------
|
||||
Disassembly of #<program #(0 28 #f) (b)>:
|
||||
Disassembly of #<program b70d2910 at <unknown port>:0:16 (b)>:
|
||||
|
||||
Bytecode:
|
||||
|
||||
0 (toplevel-ref 0) ;; `list'
|
||||
2 (toplevel-ref 1) ;; `foo'
|
||||
4 (external-ref 0) ;; (closure variable)
|
||||
6 (local-ref 0) ;; `b' (arg)
|
||||
8 (goto/args 3) at (unknown file):0:28
|
||||
0 (toplevel-ref 1) ;; `foo'
|
||||
2 (external-ref 0) ;; (closure variable)
|
||||
4 (local-ref 0) ;; `b' (arg)
|
||||
6 (list 0 3) ;; 3 elements at (unknown file):0:28
|
||||
9 (return)
|
||||
@end smallexample
|
||||
|
||||
At @code{ip} 0 and 2, we do the copy from argument to heap for
|
||||
|
@ -336,8 +329,9 @@ Control Instructions}, for more details.
|
|||
Then we see a reference to an external variable, corresponding to
|
||||
@code{a}. The disassembler doesn't have enough information to give a
|
||||
name to that variable, so it just marks it as being a ``closure
|
||||
variable''. Finally we see the reference to @code{b}, then a tail call
|
||||
(@code{goto/args}) with three arguments.
|
||||
variable''. Finally we see the reference to @code{b}, then the
|
||||
@code{list} opcode, an inline implementation of the @code{list} scheme
|
||||
routine.
|
||||
|
||||
@node Instruction Set
|
||||
@subsection Instruction Set
|
||||
|
@ -365,7 +359,8 @@ their own test-and-branch instructions:
|
|||
@end example
|
||||
|
||||
In addition, some Scheme primitives have their own inline
|
||||
implementations, e.g. @code{cons}.
|
||||
implementations, e.g. @code{cons}, and @code{list}, as we saw in the
|
||||
previous section.
|
||||
|
||||
So Guile's instruction set is a @emph{complete} instruction set, in
|
||||
that it provides the instructions that are suited to the problem, and
|
||||
|
@ -421,12 +416,6 @@ efficient in the future via addressing by frame and index. Currently,
|
|||
external variables are all consed onto a list, which results in O(N)
|
||||
lookup time.
|
||||
|
||||
@deffn Instruction externals
|
||||
Pushes the current list of external variables onto the stack. This
|
||||
instruction is used in the implementation of
|
||||
@code{compile-time-environment}. @xref{The Scheme Compiler}.
|
||||
@end deffn
|
||||
|
||||
@deffn Instruction toplevel-ref index
|
||||
Push the value of the toplevel binding whose location is stored in at
|
||||
position @var{index} in the object table.
|
||||
|
@ -440,11 +429,11 @@ created.
|
|||
Alternately, the lookup may be performed relative to a particular
|
||||
module, determined at compile-time (e.g. via @code{@@} or
|
||||
@code{@@@@}). In that case, the cell in the object table holds a list:
|
||||
@code{(@var{modname} @var{sym} @var{interface?})}. The symbol
|
||||
@var{sym} will be looked up in the module named @var{modname} (a list
|
||||
of symbols). The lookup will be performed against the module's public
|
||||
interface, unless @var{interface?} is @code{#f}, which it is for
|
||||
example when compiling @code{@@@@}.
|
||||
@code{(@var{modname} @var{sym} @var{public?})}. The symbol @var{sym}
|
||||
will be looked up in the module named @var{modname} (a list of
|
||||
symbols). The lookup will be performed against the module's public
|
||||
interface, unless @var{public?} is @code{#f}, which it is for example
|
||||
when compiling @code{@@@@}.
|
||||
|
||||
In any case, if the symbol is unbound, an error is signalled.
|
||||
Otherwise the initial form is replaced with the looked-up variable, an
|
||||
|
@ -550,8 +539,9 @@ may be encoded in 1, 2, or 4 bytes.
|
|||
|
||||
@deffn Instruction load-integer length
|
||||
@deffnx Instruction load-unsigned-integer length
|
||||
Load a 32-bit integer (respectively unsigned integer) from the
|
||||
instruction stream.
|
||||
Load a 32-bit integer or unsigned integer from the instruction stream.
|
||||
The bytes of the integer are read in order of decreasing significance
|
||||
(i.e., big-endian).
|
||||
@end deffn
|
||||
@deffn Instruction load-number length
|
||||
Load an arbitrary number from the instruction stream. The number is
|
||||
|
@ -573,43 +563,23 @@ the current toplevel environment, creating the binding if necessary.
|
|||
Push the variable corresponding to the binding.
|
||||
@end deffn
|
||||
|
||||
@deffn Instruction load-program length
|
||||
@deffn Instruction load-program
|
||||
Load bytecode from the instruction stream, and push a compiled
|
||||
procedure. This instruction pops the following values from the stack:
|
||||
procedure.
|
||||
|
||||
@itemize
|
||||
@item Optionally, a thunk, which when called should return metadata
|
||||
associated with this program---for example its name, the names of its
|
||||
arguments, its documentation string, debugging information, etc.
|
||||
This instruction pops one value from the stack: the program's object
|
||||
table, as a vector, or @code{#f} in the case that the program has no
|
||||
object table. A program that does not reference toplevel bindings and
|
||||
does not use @code{object-ref} does not need an object table.
|
||||
|
||||
Normally, this thunk its itself a compiled procedure (with no
|
||||
metadata). Metadata is represented this way so that the initial load
|
||||
of a procedure is fast: the VM just mmap's the thunk and goes. The
|
||||
symbols and pairs associated with the metadata are only created if the
|
||||
user asks for them.
|
||||
|
||||
For information on the format of the thunk's return value,
|
||||
@xref{Compiled Procedures}.
|
||||
@item Optionally, the program's object table, as a vector.
|
||||
|
||||
A program that does not reference toplevel bindings and does not use
|
||||
@code{object-ref} does not need an object table.
|
||||
@item Finally, either one immediate integer or four immediate integers
|
||||
representing the arity of the program.
|
||||
|
||||
In the four-fixnum case, the values are respectively the number of
|
||||
arguments taken by the function (@var{nargs}), the number of @dfn{rest
|
||||
arguments} (@var{nrest}, 0 or 1), the number of local variables
|
||||
(@var{nlocs}) and the number of external variables (@var{nexts})
|
||||
(@pxref{Environment Control Instructions}).
|
||||
|
||||
The common single-fixnum case represents all of these values within a
|
||||
16-bit bitmask.
|
||||
@end itemize
|
||||
This instruction is unlike the rest of the loading instructions,
|
||||
because instead of parsing its data, it directly maps the instruction
|
||||
stream onto a C structure, @code{struct scm_objcode}. @xref{Bytecode
|
||||
and Objcode}, for more information.
|
||||
|
||||
The resulting compiled procedure will not have any ``external''
|
||||
variables captured, so it will be loaded only once but may be used
|
||||
many times to create closures.
|
||||
variables captured, so it may be loaded only once but used many times
|
||||
to create closures.
|
||||
@end deffn
|
||||
|
||||
Finally, while this instruction is not strictly a ``loading''
|
||||
|
@ -620,7 +590,10 @@ here:
|
|||
Pop the program object from the stack, capture the current set of
|
||||
``external'' variables, and assign those external variables to a copy
|
||||
of the program. Push the new program object, which shares state with
|
||||
the original program. Also captures the current module.
|
||||
the original program.
|
||||
|
||||
At the time of this writing, the space overhead of closures is 4 words
|
||||
per closure.
|
||||
@end deffn
|
||||
|
||||
@node Procedural Instructions
|
||||
|
@ -640,22 +613,24 @@ set to the returned value.
|
|||
|
||||
@deffn Instruction call nargs
|
||||
Call the procedure located at @code{sp[-nargs]} with the @var{nargs}
|
||||
arguments located from @code{sp[0]} to @code{sp[-nargs + 1]}.
|
||||
arguments located from @code{sp[-nargs + 1]} to @code{sp[0]}.
|
||||
|
||||
For compiled procedures, this instruction sets up a new stack frame,
|
||||
as described in @ref{Stack Layout}, and then dispatches to the first
|
||||
instruction in the called procedure, relying on the called procedure
|
||||
to return one value to the newly-created continuation. Because the new
|
||||
frame pointer will point to sp[-nargs + 1], the arguments don't have
|
||||
to be shuffled around -- they are already in place.
|
||||
|
||||
For non-compiled procedures (continuations, primitives, and
|
||||
interpreted procedures), @code{call} will pop the procedure and
|
||||
arguments off the stack, and push the result of calling
|
||||
@code{scm_apply}.
|
||||
|
||||
For compiled procedures, this instruction sets up a new stack frame,
|
||||
as described in @ref{Stack Layout}, and then dispatches to the first
|
||||
instruction in the called procedure, relying on the called procedure
|
||||
to return one value to the newly-created continuation.
|
||||
@end deffn
|
||||
|
||||
@deffn Instruction goto/args nargs
|
||||
Like @code{call}, but reusing the current continuation. This
|
||||
instruction implements tail calling as required by RnRS.
|
||||
instruction implements tail calls as required by RnRS.
|
||||
|
||||
For compiled procedures, that means that @code{goto/args} reuses the
|
||||
current frame instead of building a new one. The @code{goto/*}
|
||||
|
@ -726,14 +701,14 @@ values. This is an optimization for the common @code{(apply values
|
|||
|
||||
@deffn Instruction truncate-values nbinds nrest
|
||||
Used in multiple-value continuations, this instruction takes the
|
||||
values that are on the stack (including the number-of-value marker)
|
||||
values that are on the stack (including the number-of-values marker)
|
||||
and truncates them for a binding construct.
|
||||
|
||||
For example, a call to @code{(receive (x y . z) (foo) ...)} would,
|
||||
logically speaking, pop off the values returned from @code{(foo)} and
|
||||
push them as three values, corresponding to @code{x}, @code{y}, and
|
||||
@code{z}. In that case, @var{nbinds} would be 3, and @var{nrest} would
|
||||
be 1 (to indicate that one of the bindings was a rest arguments).
|
||||
be 1 (to indicate that one of the bindings was a rest argument).
|
||||
|
||||
Signals an error if there is an insufficient number of values.
|
||||
@end deffn
|
||||
|
@ -779,12 +754,14 @@ Push @var{value}, an 8-bit character, onto the stack.
|
|||
@deffn Instruction list n
|
||||
Pops off the top @var{n} values off of the stack, consing them up into
|
||||
a list, then pushes that list on the stack. What was the topmost value
|
||||
will be the last element in the list.
|
||||
will be the last element in the list. @var{n} is a two-byte value,
|
||||
most significant byte first.
|
||||
@end deffn
|
||||
|
||||
@deffn Instruction vector n
|
||||
Create and fill a vector with the top @var{n} values from the stack,
|
||||
popping off those values and pushing on the resulting vector.
|
||||
popping off those values and pushing on the resulting vector. @var{n}
|
||||
is a two-byte value, like in @code{vector}.
|
||||
@end deffn
|
||||
|
||||
@deffn Instruction mark
|
||||
|
@ -850,9 +827,8 @@ Pushes ``the unspecified value'' onto the stack.
|
|||
@subsubsection Inlined Scheme Instructions
|
||||
|
||||
The Scheme compiler can recognize the application of standard Scheme
|
||||
procedures, or unbound variables that look like they are bound to
|
||||
standard Scheme procedures. It tries to inline these small operations
|
||||
to avoid the overhead of creating new stack frames.
|
||||
procedures. It tries to inline these small operations to avoid the
|
||||
overhead of creating new stack frames.
|
||||
|
||||
Since most of these operations are historically implemented as C
|
||||
primitives, not inlining them would entail constantly calling out from
|
||||
|
@ -876,12 +852,12 @@ stream.
|
|||
@deffnx Instruction eqv? x y
|
||||
@deffnx Instruction equal? x y
|
||||
@deffnx Instruction pair? x y
|
||||
@deffnx Instruction list? x y
|
||||
@deffnx Instruction list? x
|
||||
@deffnx Instruction set-car! pair x
|
||||
@deffnx Instruction set-cdr! pair x
|
||||
@deffnx Instruction slot-ref struct n
|
||||
@deffnx Instruction slot-set struct n x
|
||||
@deffnx Instruction cons x
|
||||
@deffnx Instruction cons x y
|
||||
@deffnx Instruction car x
|
||||
@deffnx Instruction cdr x
|
||||
Inlined implementations of their Scheme equivalents.
|
||||
|
|
|
@ -169,24 +169,22 @@
|
|||
(define-public (set-readline-read-hook! h)
|
||||
(set! read-hook h))
|
||||
|
||||
(if (provided? 'regex)
|
||||
(begin
|
||||
(define-public apropos-completion-function
|
||||
(let ((completions '()))
|
||||
(lambda (text cont?)
|
||||
(if (not cont?)
|
||||
(set! completions
|
||||
(map symbol->string
|
||||
(apropos-internal
|
||||
(string-append "^" (regexp-quote text))))))
|
||||
(if (null? completions)
|
||||
#f
|
||||
(let ((retval (car completions)))
|
||||
(begin (set! completions (cdr completions))
|
||||
retval))))))
|
||||
(define-public apropos-completion-function
|
||||
(let ((completions '()))
|
||||
(lambda (text cont?)
|
||||
(if (not cont?)
|
||||
(set! completions
|
||||
(map symbol->string
|
||||
(apropos-internal
|
||||
(string-append "^" (regexp-quote text))))))
|
||||
(if (null? completions)
|
||||
#f
|
||||
(let ((retval (car completions)))
|
||||
(begin (set! completions (cdr completions))
|
||||
retval))))))
|
||||
|
||||
(set! *readline-completion-function* apropos-completion-function)
|
||||
))
|
||||
(if (provided? 'regex)
|
||||
(set! *readline-completion-function* apropos-completion-function))
|
||||
|
||||
(define-public (with-readline-completion-function completer thunk)
|
||||
"With @var{completer} as readline completion function, call @var{thunk}."
|
||||
|
|
|
@ -28,6 +28,7 @@ elisp_sources = \
|
|||
elisp/example.el \
|
||||
elisp/interface.scm \
|
||||
elisp/transform.scm \
|
||||
elisp/expand.scm \
|
||||
elisp/variables.scm \
|
||||
\
|
||||
elisp/primitives/buffers.scm \
|
||||
|
|
4
lang/elisp/expand.scm
Normal file
4
lang/elisp/expand.scm
Normal file
|
@ -0,0 +1,4 @@
|
|||
(define-module (lang elisp expand)
|
||||
#:export (expand))
|
||||
|
||||
(define (expand x) x)
|
|
@ -1,4 +1,5 @@
|
|||
(define-module (lang elisp interface)
|
||||
#:use-syntax (lang elisp expand)
|
||||
#:use-module (lang elisp internals evaluation)
|
||||
#:use-module (lang elisp internals fset)
|
||||
#:use-module ((lang elisp internals load) #:select ((load . elisp:load)))
|
||||
|
@ -66,31 +67,39 @@ one of the directories of @code{load-path}."
|
|||
(string->symbol (string-append "imports:"
|
||||
(number->string counter)))))))
|
||||
|
||||
(define-macro (use-elisp-file file-name . imports)
|
||||
"Load Elisp code file @var{file-name} and import its definitions
|
||||
(define use-elisp-file
|
||||
(procedure->memoizing-macro
|
||||
(lambda (exp env)
|
||||
"Load Elisp code file @var{file-name} and import its definitions
|
||||
into the current Scheme module. If any @var{imports} are specified,
|
||||
they are interpreted as selection and renaming specifiers as per
|
||||
@code{use-modules}."
|
||||
(let ((export-module-name (export-module-name)))
|
||||
`(begin
|
||||
(fluid-set! ,elisp-export-module (resolve-module ',export-module-name))
|
||||
(beautify-user-module! (resolve-module ',export-module-name))
|
||||
(load-elisp-file ,file-name)
|
||||
(use-modules (,export-module-name ,@imports))
|
||||
(fluid-set! ,elisp-export-module #f))))
|
||||
(let ((file-name (cadr exp))
|
||||
(env (cddr exp)))
|
||||
(let ((export-module-name (export-module-name)))
|
||||
`(begin
|
||||
(fluid-set! ,elisp-export-module (resolve-module ',export-module-name))
|
||||
(beautify-user-module! (resolve-module ',export-module-name))
|
||||
(load-elisp-file ,file-name)
|
||||
(use-modules (,export-module-name ,@imports))
|
||||
(fluid-set! ,elisp-export-module #f)))))))
|
||||
|
||||
(define-macro (use-elisp-library library . imports)
|
||||
"Load Elisp library @var{library} and import its definitions into
|
||||
(define use-elisp-library
|
||||
(procedure->memoizing-macro
|
||||
(lambda (exp env)
|
||||
"Load Elisp library @var{library} and import its definitions into
|
||||
the current Scheme module. If any @var{imports} are specified, they
|
||||
are interpreted as selection and renaming specifiers as per
|
||||
@code{use-modules}."
|
||||
(let ((export-module-name (export-module-name)))
|
||||
`(begin
|
||||
(fluid-set! ,elisp-export-module (resolve-module ',export-module-name))
|
||||
(beautify-user-module! (resolve-module ',export-module-name))
|
||||
(load-elisp-library ,library)
|
||||
(use-modules (,export-module-name ,@imports))
|
||||
(fluid-set! ,elisp-export-module #f))))
|
||||
(let ((library (cadr exp))
|
||||
(env (cddr exp)))
|
||||
(let ((export-module-name (export-module-name)))
|
||||
`(begin
|
||||
(fluid-set! ,elisp-export-module (resolve-module ',export-module-name))
|
||||
(beautify-user-module! (resolve-module ',export-module-name))
|
||||
(load-elisp-library ,library)
|
||||
(use-modules (,export-module-name ,@imports))
|
||||
(fluid-set! ,elisp-export-module #f)))))))
|
||||
|
||||
(define (export-to-elisp . defs)
|
||||
"Export procedures and variables specified by @var{defs} to Elisp.
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
(define-module (lang elisp internals lambda)
|
||||
#:use-syntax (lang elisp expand)
|
||||
#:use-module (lang elisp internals fset)
|
||||
#:use-module (lang elisp transform)
|
||||
#:export (parse-formals
|
||||
|
|
|
@ -26,7 +26,8 @@
|
|||
|
||||
(fset 'symbol-function fref/error-if-void)
|
||||
|
||||
(fset 'macroexpand macroexpand)
|
||||
;; FIXME -- lost in the syncase conversion
|
||||
;; (fset 'macroexpand macroexpand)
|
||||
|
||||
(fset 'subrp
|
||||
(lambda (obj)
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
(define-module (lang elisp primitives syntax)
|
||||
#:use-syntax (lang elisp expand)
|
||||
#:use-module (lang elisp internals evaluation)
|
||||
#:use-module (lang elisp internals fset)
|
||||
#:use-module (lang elisp internals lambda)
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
(define-module (lang elisp transform)
|
||||
#:use-syntax (lang elisp expand)
|
||||
#:use-module (lang elisp internals trace)
|
||||
#:use-module (lang elisp internals fset)
|
||||
#:use-module (lang elisp internals evaluation)
|
||||
|
@ -26,23 +27,27 @@
|
|||
(define (syntax-error x)
|
||||
(error "Syntax error in expression" x))
|
||||
|
||||
(define-macro (scheme exp . module)
|
||||
(let ((m (if (null? module)
|
||||
the-root-module
|
||||
(save-module-excursion
|
||||
(lambda ()
|
||||
;; In order for `resolve-module' to work as
|
||||
;; expected, the current module must contain the
|
||||
;; `app' variable. This is not true for #:pure
|
||||
;; modules, specifically (lang elisp base). So,
|
||||
;; switch to the root module (guile) before calling
|
||||
;; resolve-module.
|
||||
(set-current-module the-root-module)
|
||||
(resolve-module (car module)))))))
|
||||
(let ((x `(,eval (,quote ,exp) ,m)))
|
||||
;;(write x)
|
||||
;;(newline)
|
||||
x)))
|
||||
(define scheme
|
||||
(procedure->memoizing-macro
|
||||
(lambda (exp env)
|
||||
(let ((exp (cadr exp))
|
||||
(module (cddr exp)))
|
||||
(let ((m (if (null? module)
|
||||
the-root-module
|
||||
(save-module-excursion
|
||||
(lambda ()
|
||||
;; In order for `resolve-module' to work as
|
||||
;; expected, the current module must contain the
|
||||
;; `app' variable. This is not true for #:pure
|
||||
;; modules, specifically (lang elisp base). So,
|
||||
;; switch to the root module (guile) before calling
|
||||
;; resolve-module.
|
||||
(set-current-module the-root-module)
|
||||
(resolve-module (car module)))))))
|
||||
(let ((x `(,eval (,quote ,exp) ,m)))
|
||||
;;(write x)
|
||||
;;(newline)
|
||||
x))))))
|
||||
|
||||
(define (transformer x)
|
||||
(cond ((pair? x)
|
||||
|
|
249
lib/Makefile.am
249
lib/Makefile.am
|
@ -9,9 +9,9 @@
|
|||
# the same distribution terms as the rest of that program.
|
||||
#
|
||||
# Generated by gnulib-tool.
|
||||
# Reproduce by: gnulib-tool --import --dir=. --lib=libgnu --source-base=lib --m4-base=m4 --doc-base=doc --tests-base=tests --aux-dir=build-aux --lgpl --libtool --macro-prefix=gl --no-vc-files alloca-opt autobuild count-one-bits extensions flock fpieee full-read full-write putenv stdlib strcase strftime
|
||||
# Reproduce by: gnulib-tool --import --dir=. --lib=libgnu --source-base=lib --m4-base=m4 --doc-base=doc --tests-base=tests --aux-dir=build-aux --lgpl --libtool --macro-prefix=gl --no-vc-files alloca-opt autobuild byteswap count-one-bits environ extensions flock fpieee full-read full-write iconv_open-utf lib-symbol-visibility libunistring putenv stdlib strcase strftime striconveh string
|
||||
|
||||
AUTOMAKE_OPTIONS = 1.5 gnits
|
||||
AUTOMAKE_OPTIONS = 1.5 gnits subdir-objects
|
||||
|
||||
SUBDIRS =
|
||||
noinst_HEADERS =
|
||||
|
@ -54,6 +54,42 @@ EXTRA_DIST += alloca.in.h
|
|||
|
||||
## end gnulib module alloca-opt
|
||||
|
||||
## begin gnulib module byteswap
|
||||
|
||||
BUILT_SOURCES += $(BYTESWAP_H)
|
||||
|
||||
# We need the following in order to create <byteswap.h> when the system
|
||||
# doesn't have one.
|
||||
byteswap.h: byteswap.in.h
|
||||
{ echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \
|
||||
cat $(srcdir)/byteswap.in.h; \
|
||||
} > $@-t
|
||||
mv -f $@-t $@
|
||||
MOSTLYCLEANFILES += byteswap.h byteswap.h-t
|
||||
|
||||
EXTRA_DIST += byteswap.in.h
|
||||
|
||||
## end gnulib module byteswap
|
||||
|
||||
## begin gnulib module c-ctype
|
||||
|
||||
libgnu_la_SOURCES += c-ctype.h c-ctype.c
|
||||
|
||||
## end gnulib module c-ctype
|
||||
|
||||
## begin gnulib module c-strcase
|
||||
|
||||
libgnu_la_SOURCES += c-strcase.h c-strcasecmp.c c-strncasecmp.c
|
||||
|
||||
## end gnulib module c-strcase
|
||||
|
||||
## begin gnulib module c-strcaseeq
|
||||
|
||||
|
||||
EXTRA_DIST += c-strcaseeq.h
|
||||
|
||||
## end gnulib module c-strcaseeq
|
||||
|
||||
## begin gnulib module configmake
|
||||
|
||||
# Retrieve values of the variables through 'configure' followed by
|
||||
|
@ -143,6 +179,82 @@ libgnu_la_SOURCES += full-write.h full-write.c
|
|||
|
||||
## end gnulib module full-write
|
||||
|
||||
## begin gnulib module gperf
|
||||
|
||||
GPERF = gperf
|
||||
|
||||
## end gnulib module gperf
|
||||
|
||||
## begin gnulib module havelib
|
||||
|
||||
|
||||
EXTRA_DIST += $(top_srcdir)/build-aux/config.rpath
|
||||
|
||||
## end gnulib module havelib
|
||||
|
||||
## begin gnulib module iconv_open
|
||||
|
||||
BUILT_SOURCES += $(ICONV_H)
|
||||
|
||||
# We need the following in order to create <iconv.h> when the system
|
||||
# doesn't have one that works with the given compiler.
|
||||
iconv.h: iconv.in.h
|
||||
rm -f $@-t $@
|
||||
{ echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */' && \
|
||||
sed -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \
|
||||
-e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \
|
||||
-e 's|@''NEXT_ICONV_H''@|$(NEXT_ICONV_H)|g' \
|
||||
-e 's|@''ICONV_CONST''@|$(ICONV_CONST)|g' \
|
||||
-e 's|@''REPLACE_ICONV''@|$(REPLACE_ICONV)|g' \
|
||||
-e 's|@''REPLACE_ICONV_OPEN''@|$(REPLACE_ICONV_OPEN)|g' \
|
||||
-e 's|@''REPLACE_ICONV_UTF''@|$(REPLACE_ICONV_UTF)|g' \
|
||||
< $(srcdir)/iconv.in.h; \
|
||||
} > $@-t
|
||||
mv $@-t $@
|
||||
MOSTLYCLEANFILES += iconv.h iconv.h-t
|
||||
|
||||
iconv_open-aix.h: iconv_open-aix.gperf
|
||||
$(GPERF) -m 10 $(srcdir)/iconv_open-aix.gperf > $(srcdir)/iconv_open-aix.h-t
|
||||
mv $(srcdir)/iconv_open-aix.h-t $(srcdir)/iconv_open-aix.h
|
||||
iconv_open-hpux.h: iconv_open-hpux.gperf
|
||||
$(GPERF) -m 10 $(srcdir)/iconv_open-hpux.gperf > $(srcdir)/iconv_open-hpux.h-t
|
||||
mv $(srcdir)/iconv_open-hpux.h-t $(srcdir)/iconv_open-hpux.h
|
||||
iconv_open-irix.h: iconv_open-irix.gperf
|
||||
$(GPERF) -m 10 $(srcdir)/iconv_open-irix.gperf > $(srcdir)/iconv_open-irix.h-t
|
||||
mv $(srcdir)/iconv_open-irix.h-t $(srcdir)/iconv_open-irix.h
|
||||
iconv_open-osf.h: iconv_open-osf.gperf
|
||||
$(GPERF) -m 10 $(srcdir)/iconv_open-osf.gperf > $(srcdir)/iconv_open-osf.h-t
|
||||
mv $(srcdir)/iconv_open-osf.h-t $(srcdir)/iconv_open-osf.h
|
||||
BUILT_SOURCES += iconv_open-aix.h iconv_open-hpux.h iconv_open-irix.h iconv_open-osf.h
|
||||
MOSTLYCLEANFILES += iconv_open-aix.h-t iconv_open-hpux.h-t iconv_open-irix.h-t iconv_open-osf.h-t
|
||||
MAINTAINERCLEANFILES += iconv_open-aix.h iconv_open-hpux.h iconv_open-irix.h iconv_open-osf.h
|
||||
EXTRA_DIST += iconv_open-aix.h iconv_open-hpux.h iconv_open-irix.h iconv_open-osf.h
|
||||
|
||||
EXTRA_DIST += iconv.in.h iconv_open-aix.gperf iconv_open-hpux.gperf iconv_open-irix.gperf iconv_open-osf.gperf iconv_open.c
|
||||
|
||||
EXTRA_libgnu_la_SOURCES += iconv_open.c
|
||||
|
||||
## end gnulib module iconv_open
|
||||
|
||||
## begin gnulib module iconv_open-utf
|
||||
|
||||
|
||||
EXTRA_DIST += iconv.c iconv_close.c
|
||||
|
||||
EXTRA_libgnu_la_SOURCES += iconv.c iconv_close.c
|
||||
|
||||
## end gnulib module iconv_open-utf
|
||||
|
||||
## begin gnulib module lib-symbol-visibility
|
||||
|
||||
# The value of $(CFLAG_VISIBILITY) needs to be added to the CFLAGS for the
|
||||
# compilation of all sources that make up the library. This line here does it
|
||||
# only for the gnulib part of it. The developer is responsible for adding
|
||||
# $(CFLAG_VISIBILITY) to the Makefile.ams of the other portions of the library.
|
||||
AM_CFLAGS += $(CFLAG_VISIBILITY)
|
||||
|
||||
## end gnulib module lib-symbol-visibility
|
||||
|
||||
## begin gnulib module link-warning
|
||||
|
||||
LINK_WARNING_H=$(top_srcdir)/build-aux/link-warning.h
|
||||
|
@ -432,6 +544,95 @@ EXTRA_libgnu_la_SOURCES += strftime.c
|
|||
|
||||
## end gnulib module strftime
|
||||
|
||||
## begin gnulib module striconveh
|
||||
|
||||
libgnu_la_SOURCES += striconveh.h striconveh.c
|
||||
if GL_COND_LIBTOOL
|
||||
libgnu_la_LDFLAGS += $(LTLIBICONV)
|
||||
endif
|
||||
|
||||
EXTRA_DIST += iconveh.h
|
||||
|
||||
## end gnulib module striconveh
|
||||
|
||||
## begin gnulib module string
|
||||
|
||||
BUILT_SOURCES += string.h
|
||||
|
||||
# We need the following in order to create <string.h> when the system
|
||||
# doesn't have one that works with the given compiler.
|
||||
string.h: string.in.h
|
||||
rm -f $@-t $@
|
||||
{ echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */' && \
|
||||
sed -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \
|
||||
-e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \
|
||||
-e 's|@''NEXT_STRING_H''@|$(NEXT_STRING_H)|g' \
|
||||
-e 's|@''GNULIB_MBSLEN''@|$(GNULIB_MBSLEN)|g' \
|
||||
-e 's|@''GNULIB_MBSNLEN''@|$(GNULIB_MBSNLEN)|g' \
|
||||
-e 's|@''GNULIB_MBSCHR''@|$(GNULIB_MBSCHR)|g' \
|
||||
-e 's|@''GNULIB_MBSRCHR''@|$(GNULIB_MBSRCHR)|g' \
|
||||
-e 's|@''GNULIB_MBSSTR''@|$(GNULIB_MBSSTR)|g' \
|
||||
-e 's|@''GNULIB_MBSCASECMP''@|$(GNULIB_MBSCASECMP)|g' \
|
||||
-e 's|@''GNULIB_MBSNCASECMP''@|$(GNULIB_MBSNCASECMP)|g' \
|
||||
-e 's|@''GNULIB_MBSPCASECMP''@|$(GNULIB_MBSPCASECMP)|g' \
|
||||
-e 's|@''GNULIB_MBSCASESTR''@|$(GNULIB_MBSCASESTR)|g' \
|
||||
-e 's|@''GNULIB_MBSCSPN''@|$(GNULIB_MBSCSPN)|g' \
|
||||
-e 's|@''GNULIB_MBSPBRK''@|$(GNULIB_MBSPBRK)|g' \
|
||||
-e 's|@''GNULIB_MBSSPN''@|$(GNULIB_MBSSPN)|g' \
|
||||
-e 's|@''GNULIB_MBSSEP''@|$(GNULIB_MBSSEP)|g' \
|
||||
-e 's|@''GNULIB_MBSTOK_R''@|$(GNULIB_MBSTOK_R)|g' \
|
||||
-e 's|@''GNULIB_MEMMEM''@|$(GNULIB_MEMMEM)|g' \
|
||||
-e 's|@''GNULIB_MEMPCPY''@|$(GNULIB_MEMPCPY)|g' \
|
||||
-e 's|@''GNULIB_MEMRCHR''@|$(GNULIB_MEMRCHR)|g' \
|
||||
-e 's|@''GNULIB_RAWMEMCHR''@|$(GNULIB_RAWMEMCHR)|g' \
|
||||
-e 's|@''GNULIB_STPCPY''@|$(GNULIB_STPCPY)|g' \
|
||||
-e 's|@''GNULIB_STPNCPY''@|$(GNULIB_STPNCPY)|g' \
|
||||
-e 's|@''GNULIB_STRCHRNUL''@|$(GNULIB_STRCHRNUL)|g' \
|
||||
-e 's|@''GNULIB_STRDUP''@|$(GNULIB_STRDUP)|g' \
|
||||
-e 's|@''GNULIB_STRNDUP''@|$(GNULIB_STRNDUP)|g' \
|
||||
-e 's|@''GNULIB_STRNLEN''@|$(GNULIB_STRNLEN)|g' \
|
||||
-e 's|@''GNULIB_STRPBRK''@|$(GNULIB_STRPBRK)|g' \
|
||||
-e 's|@''GNULIB_STRSEP''@|$(GNULIB_STRSEP)|g' \
|
||||
-e 's|@''GNULIB_STRSTR''@|$(GNULIB_STRSTR)|g' \
|
||||
-e 's|@''GNULIB_STRCASESTR''@|$(GNULIB_STRCASESTR)|g' \
|
||||
-e 's|@''GNULIB_STRTOK_R''@|$(GNULIB_STRTOK_R)|g' \
|
||||
-e 's|@''GNULIB_STRERROR''@|$(GNULIB_STRERROR)|g' \
|
||||
-e 's|@''GNULIB_STRSIGNAL''@|$(GNULIB_STRSIGNAL)|g' \
|
||||
-e 's|@''GNULIB_STRVERSCMP''@|$(GNULIB_STRVERSCMP)|g' \
|
||||
-e 's|@''HAVE_DECL_MEMMEM''@|$(HAVE_DECL_MEMMEM)|g' \
|
||||
-e 's|@''HAVE_MEMPCPY''@|$(HAVE_MEMPCPY)|g' \
|
||||
-e 's|@''HAVE_DECL_MEMRCHR''@|$(HAVE_DECL_MEMRCHR)|g' \
|
||||
-e 's|@''HAVE_RAWMEMCHR''@|$(HAVE_RAWMEMCHR)|g' \
|
||||
-e 's|@''HAVE_STPCPY''@|$(HAVE_STPCPY)|g' \
|
||||
-e 's|@''HAVE_STPNCPY''@|$(HAVE_STPNCPY)|g' \
|
||||
-e 's|@''HAVE_STRCHRNUL''@|$(HAVE_STRCHRNUL)|g' \
|
||||
-e 's|@''HAVE_DECL_STRDUP''@|$(HAVE_DECL_STRDUP)|g' \
|
||||
-e 's|@''HAVE_STRNDUP''@|$(HAVE_STRNDUP)|g' \
|
||||
-e 's|@''HAVE_DECL_STRNDUP''@|$(HAVE_DECL_STRNDUP)|g' \
|
||||
-e 's|@''HAVE_DECL_STRNLEN''@|$(HAVE_DECL_STRNLEN)|g' \
|
||||
-e 's|@''HAVE_STRPBRK''@|$(HAVE_STRPBRK)|g' \
|
||||
-e 's|@''HAVE_STRSEP''@|$(HAVE_STRSEP)|g' \
|
||||
-e 's|@''HAVE_STRCASESTR''@|$(HAVE_STRCASESTR)|g' \
|
||||
-e 's|@''HAVE_DECL_STRTOK_R''@|$(HAVE_DECL_STRTOK_R)|g' \
|
||||
-e 's|@''HAVE_DECL_STRERROR''@|$(HAVE_DECL_STRERROR)|g' \
|
||||
-e 's|@''HAVE_DECL_STRSIGNAL''@|$(HAVE_DECL_STRSIGNAL)|g' \
|
||||
-e 's|@''HAVE_STRVERSCMP''@|$(HAVE_STRVERSCMP)|g' \
|
||||
-e 's|@''REPLACE_MEMMEM''@|$(REPLACE_MEMMEM)|g' \
|
||||
-e 's|@''REPLACE_STRCASESTR''@|$(REPLACE_STRCASESTR)|g' \
|
||||
-e 's|@''REPLACE_STRDUP''@|$(REPLACE_STRDUP)|g' \
|
||||
-e 's|@''REPLACE_STRSTR''@|$(REPLACE_STRSTR)|g' \
|
||||
-e 's|@''REPLACE_STRERROR''@|$(REPLACE_STRERROR)|g' \
|
||||
-e 's|@''REPLACE_STRSIGNAL''@|$(REPLACE_STRSIGNAL)|g' \
|
||||
-e '/definition of GL_LINK_WARNING/r $(LINK_WARNING_H)' \
|
||||
< $(srcdir)/string.in.h; \
|
||||
} > $@-t
|
||||
mv $@-t $@
|
||||
MOSTLYCLEANFILES += string.h string.h-t
|
||||
|
||||
EXTRA_DIST += string.in.h
|
||||
|
||||
## end gnulib module string
|
||||
|
||||
## begin gnulib module strings
|
||||
|
||||
BUILT_SOURCES += strings.h
|
||||
|
@ -588,6 +789,50 @@ EXTRA_DIST += unistd.in.h
|
|||
|
||||
## end gnulib module unistd
|
||||
|
||||
## begin gnulib module unistr/base
|
||||
|
||||
|
||||
EXTRA_DIST += unistr.h
|
||||
|
||||
## end gnulib module unistr/base
|
||||
|
||||
## begin gnulib module unistr/u8-mbtouc
|
||||
|
||||
libgnu_la_SOURCES += unistr/u8-mbtouc.c unistr/u8-mbtouc-aux.c
|
||||
|
||||
## end gnulib module unistr/u8-mbtouc
|
||||
|
||||
## begin gnulib module unistr/u8-mbtouc-unsafe
|
||||
|
||||
libgnu_la_SOURCES += unistr/u8-mbtouc-unsafe.c unistr/u8-mbtouc-unsafe-aux.c
|
||||
|
||||
## end gnulib module unistr/u8-mbtouc-unsafe
|
||||
|
||||
## begin gnulib module unistr/u8-mbtoucr
|
||||
|
||||
libgnu_la_SOURCES += unistr/u8-mbtoucr.c
|
||||
|
||||
## end gnulib module unistr/u8-mbtoucr
|
||||
|
||||
## begin gnulib module unistr/u8-prev
|
||||
|
||||
libgnu_la_SOURCES += unistr/u8-prev.c
|
||||
|
||||
## end gnulib module unistr/u8-prev
|
||||
|
||||
## begin gnulib module unistr/u8-uctomb
|
||||
|
||||
libgnu_la_SOURCES += unistr/u8-uctomb.c unistr/u8-uctomb-aux.c
|
||||
|
||||
## end gnulib module unistr/u8-uctomb
|
||||
|
||||
## begin gnulib module unitypes
|
||||
|
||||
|
||||
EXTRA_DIST += unitypes.h
|
||||
|
||||
## end gnulib module unitypes
|
||||
|
||||
## begin gnulib module verify
|
||||
|
||||
libgnu_la_SOURCES += verify.h
|
||||
|
|
44
lib/byteswap.in.h
Normal file
44
lib/byteswap.in.h
Normal file
|
@ -0,0 +1,44 @@
|
|||
/* byteswap.h - Byte swapping
|
||||
Copyright (C) 2005, 2007 Free Software Foundation, Inc.
|
||||
Written by Oskar Liljeblad <oskar@osk.mine.nu>, 2005.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation; either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef _GL_BYTESWAP_H
|
||||
#define _GL_BYTESWAP_H
|
||||
|
||||
/* Given an unsigned 16-bit argument X, return the value corresponding to
|
||||
X with reversed byte order. */
|
||||
#define bswap_16(x) ((((x) & 0x00FF) << 8) | \
|
||||
(((x) & 0xFF00) >> 8))
|
||||
|
||||
/* Given an unsigned 32-bit argument X, return the value corresponding to
|
||||
X with reversed byte order. */
|
||||
#define bswap_32(x) ((((x) & 0x000000FF) << 24) | \
|
||||
(((x) & 0x0000FF00) << 8) | \
|
||||
(((x) & 0x00FF0000) >> 8) | \
|
||||
(((x) & 0xFF000000) >> 24))
|
||||
|
||||
/* Given an unsigned 64-bit argument X, return the value corresponding to
|
||||
X with reversed byte order. */
|
||||
#define bswap_64(x) ((((x) & 0x00000000000000FFULL) << 56) | \
|
||||
(((x) & 0x000000000000FF00ULL) << 40) | \
|
||||
(((x) & 0x0000000000FF0000ULL) << 24) | \
|
||||
(((x) & 0x00000000FF000000ULL) << 8) | \
|
||||
(((x) & 0x000000FF00000000ULL) >> 8) | \
|
||||
(((x) & 0x0000FF0000000000ULL) >> 24) | \
|
||||
(((x) & 0x00FF000000000000ULL) >> 40) | \
|
||||
(((x) & 0xFF00000000000000ULL) >> 56))
|
||||
|
||||
#endif /* _GL_BYTESWAP_H */
|
396
lib/c-ctype.c
Normal file
396
lib/c-ctype.c
Normal file
|
@ -0,0 +1,396 @@
|
|||
/* Character handling in C locale.
|
||||
|
||||
Copyright 2000-2003, 2006 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program; if not, write to the Free Software Foundation,
|
||||
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
/* Specification. */
|
||||
#define NO_C_CTYPE_MACROS
|
||||
#include "c-ctype.h"
|
||||
|
||||
/* The function isascii is not locale dependent. Its use in EBCDIC is
|
||||
questionable. */
|
||||
bool
|
||||
c_isascii (int c)
|
||||
{
|
||||
return (c >= 0x00 && c <= 0x7f);
|
||||
}
|
||||
|
||||
bool
|
||||
c_isalnum (int c)
|
||||
{
|
||||
#if C_CTYPE_CONSECUTIVE_DIGITS \
|
||||
&& C_CTYPE_CONSECUTIVE_UPPERCASE && C_CTYPE_CONSECUTIVE_LOWERCASE
|
||||
#if C_CTYPE_ASCII
|
||||
return ((c >= '0' && c <= '9')
|
||||
|| ((c & ~0x20) >= 'A' && (c & ~0x20) <= 'Z'));
|
||||
#else
|
||||
return ((c >= '0' && c <= '9')
|
||||
|| (c >= 'A' && c <= 'Z')
|
||||
|| (c >= 'a' && c <= 'z'));
|
||||
#endif
|
||||
#else
|
||||
switch (c)
|
||||
{
|
||||
case '0': case '1': case '2': case '3': case '4': case '5':
|
||||
case '6': case '7': case '8': case '9':
|
||||
case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
|
||||
case 'G': case 'H': case 'I': case 'J': case 'K': case 'L':
|
||||
case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R':
|
||||
case 'S': case 'T': case 'U': case 'V': case 'W': case 'X':
|
||||
case 'Y': case 'Z':
|
||||
case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
|
||||
case 'g': case 'h': case 'i': case 'j': case 'k': case 'l':
|
||||
case 'm': case 'n': case 'o': case 'p': case 'q': case 'r':
|
||||
case 's': case 't': case 'u': case 'v': case 'w': case 'x':
|
||||
case 'y': case 'z':
|
||||
return 1;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
bool
|
||||
c_isalpha (int c)
|
||||
{
|
||||
#if C_CTYPE_CONSECUTIVE_UPPERCASE && C_CTYPE_CONSECUTIVE_LOWERCASE
|
||||
#if C_CTYPE_ASCII
|
||||
return ((c & ~0x20) >= 'A' && (c & ~0x20) <= 'Z');
|
||||
#else
|
||||
return ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z'));
|
||||
#endif
|
||||
#else
|
||||
switch (c)
|
||||
{
|
||||
case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
|
||||
case 'G': case 'H': case 'I': case 'J': case 'K': case 'L':
|
||||
case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R':
|
||||
case 'S': case 'T': case 'U': case 'V': case 'W': case 'X':
|
||||
case 'Y': case 'Z':
|
||||
case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
|
||||
case 'g': case 'h': case 'i': case 'j': case 'k': case 'l':
|
||||
case 'm': case 'n': case 'o': case 'p': case 'q': case 'r':
|
||||
case 's': case 't': case 'u': case 'v': case 'w': case 'x':
|
||||
case 'y': case 'z':
|
||||
return 1;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
bool
|
||||
c_isblank (int c)
|
||||
{
|
||||
return (c == ' ' || c == '\t');
|
||||
}
|
||||
|
||||
bool
|
||||
c_iscntrl (int c)
|
||||
{
|
||||
#if C_CTYPE_ASCII
|
||||
return ((c & ~0x1f) == 0 || c == 0x7f);
|
||||
#else
|
||||
switch (c)
|
||||
{
|
||||
case ' ': case '!': case '"': case '#': case '$': case '%':
|
||||
case '&': case '\'': case '(': case ')': case '*': case '+':
|
||||
case ',': case '-': case '.': case '/':
|
||||
case '0': case '1': case '2': case '3': case '4': case '5':
|
||||
case '6': case '7': case '8': case '9':
|
||||
case ':': case ';': case '<': case '=': case '>': case '?':
|
||||
case '@':
|
||||
case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
|
||||
case 'G': case 'H': case 'I': case 'J': case 'K': case 'L':
|
||||
case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R':
|
||||
case 'S': case 'T': case 'U': case 'V': case 'W': case 'X':
|
||||
case 'Y': case 'Z':
|
||||
case '[': case '\\': case ']': case '^': case '_': case '`':
|
||||
case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
|
||||
case 'g': case 'h': case 'i': case 'j': case 'k': case 'l':
|
||||
case 'm': case 'n': case 'o': case 'p': case 'q': case 'r':
|
||||
case 's': case 't': case 'u': case 'v': case 'w': case 'x':
|
||||
case 'y': case 'z':
|
||||
case '{': case '|': case '}': case '~':
|
||||
return 0;
|
||||
default:
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
bool
|
||||
c_isdigit (int c)
|
||||
{
|
||||
#if C_CTYPE_CONSECUTIVE_DIGITS
|
||||
return (c >= '0' && c <= '9');
|
||||
#else
|
||||
switch (c)
|
||||
{
|
||||
case '0': case '1': case '2': case '3': case '4': case '5':
|
||||
case '6': case '7': case '8': case '9':
|
||||
return 1;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
bool
|
||||
c_islower (int c)
|
||||
{
|
||||
#if C_CTYPE_CONSECUTIVE_LOWERCASE
|
||||
return (c >= 'a' && c <= 'z');
|
||||
#else
|
||||
switch (c)
|
||||
{
|
||||
case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
|
||||
case 'g': case 'h': case 'i': case 'j': case 'k': case 'l':
|
||||
case 'm': case 'n': case 'o': case 'p': case 'q': case 'r':
|
||||
case 's': case 't': case 'u': case 'v': case 'w': case 'x':
|
||||
case 'y': case 'z':
|
||||
return 1;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
bool
|
||||
c_isgraph (int c)
|
||||
{
|
||||
#if C_CTYPE_ASCII
|
||||
return (c >= '!' && c <= '~');
|
||||
#else
|
||||
switch (c)
|
||||
{
|
||||
case '!': case '"': case '#': case '$': case '%': case '&':
|
||||
case '\'': case '(': case ')': case '*': case '+': case ',':
|
||||
case '-': case '.': case '/':
|
||||
case '0': case '1': case '2': case '3': case '4': case '5':
|
||||
case '6': case '7': case '8': case '9':
|
||||
case ':': case ';': case '<': case '=': case '>': case '?':
|
||||
case '@':
|
||||
case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
|
||||
case 'G': case 'H': case 'I': case 'J': case 'K': case 'L':
|
||||
case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R':
|
||||
case 'S': case 'T': case 'U': case 'V': case 'W': case 'X':
|
||||
case 'Y': case 'Z':
|
||||
case '[': case '\\': case ']': case '^': case '_': case '`':
|
||||
case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
|
||||
case 'g': case 'h': case 'i': case 'j': case 'k': case 'l':
|
||||
case 'm': case 'n': case 'o': case 'p': case 'q': case 'r':
|
||||
case 's': case 't': case 'u': case 'v': case 'w': case 'x':
|
||||
case 'y': case 'z':
|
||||
case '{': case '|': case '}': case '~':
|
||||
return 1;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
bool
|
||||
c_isprint (int c)
|
||||
{
|
||||
#if C_CTYPE_ASCII
|
||||
return (c >= ' ' && c <= '~');
|
||||
#else
|
||||
switch (c)
|
||||
{
|
||||
case ' ': case '!': case '"': case '#': case '$': case '%':
|
||||
case '&': case '\'': case '(': case ')': case '*': case '+':
|
||||
case ',': case '-': case '.': case '/':
|
||||
case '0': case '1': case '2': case '3': case '4': case '5':
|
||||
case '6': case '7': case '8': case '9':
|
||||
case ':': case ';': case '<': case '=': case '>': case '?':
|
||||
case '@':
|
||||
case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
|
||||
case 'G': case 'H': case 'I': case 'J': case 'K': case 'L':
|
||||
case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R':
|
||||
case 'S': case 'T': case 'U': case 'V': case 'W': case 'X':
|
||||
case 'Y': case 'Z':
|
||||
case '[': case '\\': case ']': case '^': case '_': case '`':
|
||||
case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
|
||||
case 'g': case 'h': case 'i': case 'j': case 'k': case 'l':
|
||||
case 'm': case 'n': case 'o': case 'p': case 'q': case 'r':
|
||||
case 's': case 't': case 'u': case 'v': case 'w': case 'x':
|
||||
case 'y': case 'z':
|
||||
case '{': case '|': case '}': case '~':
|
||||
return 1;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
bool
|
||||
c_ispunct (int c)
|
||||
{
|
||||
#if C_CTYPE_ASCII
|
||||
return ((c >= '!' && c <= '~')
|
||||
&& !((c >= '0' && c <= '9')
|
||||
|| ((c & ~0x20) >= 'A' && (c & ~0x20) <= 'Z')));
|
||||
#else
|
||||
switch (c)
|
||||
{
|
||||
case '!': case '"': case '#': case '$': case '%': case '&':
|
||||
case '\'': case '(': case ')': case '*': case '+': case ',':
|
||||
case '-': case '.': case '/':
|
||||
case ':': case ';': case '<': case '=': case '>': case '?':
|
||||
case '@':
|
||||
case '[': case '\\': case ']': case '^': case '_': case '`':
|
||||
case '{': case '|': case '}': case '~':
|
||||
return 1;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
bool
|
||||
c_isspace (int c)
|
||||
{
|
||||
return (c == ' ' || c == '\t'
|
||||
|| c == '\n' || c == '\v' || c == '\f' || c == '\r');
|
||||
}
|
||||
|
||||
bool
|
||||
c_isupper (int c)
|
||||
{
|
||||
#if C_CTYPE_CONSECUTIVE_UPPERCASE
|
||||
return (c >= 'A' && c <= 'Z');
|
||||
#else
|
||||
switch (c)
|
||||
{
|
||||
case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
|
||||
case 'G': case 'H': case 'I': case 'J': case 'K': case 'L':
|
||||
case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R':
|
||||
case 'S': case 'T': case 'U': case 'V': case 'W': case 'X':
|
||||
case 'Y': case 'Z':
|
||||
return 1;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
bool
|
||||
c_isxdigit (int c)
|
||||
{
|
||||
#if C_CTYPE_CONSECUTIVE_DIGITS \
|
||||
&& C_CTYPE_CONSECUTIVE_UPPERCASE && C_CTYPE_CONSECUTIVE_LOWERCASE
|
||||
#if C_CTYPE_ASCII
|
||||
return ((c >= '0' && c <= '9')
|
||||
|| ((c & ~0x20) >= 'A' && (c & ~0x20) <= 'F'));
|
||||
#else
|
||||
return ((c >= '0' && c <= '9')
|
||||
|| (c >= 'A' && c <= 'F')
|
||||
|| (c >= 'a' && c <= 'f'));
|
||||
#endif
|
||||
#else
|
||||
switch (c)
|
||||
{
|
||||
case '0': case '1': case '2': case '3': case '4': case '5':
|
||||
case '6': case '7': case '8': case '9':
|
||||
case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
|
||||
case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
|
||||
return 1;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
int
|
||||
c_tolower (int c)
|
||||
{
|
||||
#if C_CTYPE_CONSECUTIVE_UPPERCASE && C_CTYPE_CONSECUTIVE_LOWERCASE
|
||||
return (c >= 'A' && c <= 'Z' ? c - 'A' + 'a' : c);
|
||||
#else
|
||||
switch (c)
|
||||
{
|
||||
case 'A': return 'a';
|
||||
case 'B': return 'b';
|
||||
case 'C': return 'c';
|
||||
case 'D': return 'd';
|
||||
case 'E': return 'e';
|
||||
case 'F': return 'f';
|
||||
case 'G': return 'g';
|
||||
case 'H': return 'h';
|
||||
case 'I': return 'i';
|
||||
case 'J': return 'j';
|
||||
case 'K': return 'k';
|
||||
case 'L': return 'l';
|
||||
case 'M': return 'm';
|
||||
case 'N': return 'n';
|
||||
case 'O': return 'o';
|
||||
case 'P': return 'p';
|
||||
case 'Q': return 'q';
|
||||
case 'R': return 'r';
|
||||
case 'S': return 's';
|
||||
case 'T': return 't';
|
||||
case 'U': return 'u';
|
||||
case 'V': return 'v';
|
||||
case 'W': return 'w';
|
||||
case 'X': return 'x';
|
||||
case 'Y': return 'y';
|
||||
case 'Z': return 'z';
|
||||
default: return c;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
int
|
||||
c_toupper (int c)
|
||||
{
|
||||
#if C_CTYPE_CONSECUTIVE_UPPERCASE && C_CTYPE_CONSECUTIVE_LOWERCASE
|
||||
return (c >= 'a' && c <= 'z' ? c - 'a' + 'A' : c);
|
||||
#else
|
||||
switch (c)
|
||||
{
|
||||
case 'a': return 'A';
|
||||
case 'b': return 'B';
|
||||
case 'c': return 'C';
|
||||
case 'd': return 'D';
|
||||
case 'e': return 'E';
|
||||
case 'f': return 'F';
|
||||
case 'g': return 'G';
|
||||
case 'h': return 'H';
|
||||
case 'i': return 'I';
|
||||
case 'j': return 'J';
|
||||
case 'k': return 'K';
|
||||
case 'l': return 'L';
|
||||
case 'm': return 'M';
|
||||
case 'n': return 'N';
|
||||
case 'o': return 'O';
|
||||
case 'p': return 'P';
|
||||
case 'q': return 'Q';
|
||||
case 'r': return 'R';
|
||||
case 's': return 'S';
|
||||
case 't': return 'T';
|
||||
case 'u': return 'U';
|
||||
case 'v': return 'V';
|
||||
case 'w': return 'W';
|
||||
case 'x': return 'X';
|
||||
case 'y': return 'Y';
|
||||
case 'z': return 'Z';
|
||||
default: return c;
|
||||
}
|
||||
#endif
|
||||
}
|
295
lib/c-ctype.h
Normal file
295
lib/c-ctype.h
Normal file
|
@ -0,0 +1,295 @@
|
|||
/* Character handling in C locale.
|
||||
|
||||
These functions work like the corresponding functions in <ctype.h>,
|
||||
except that they have the C (POSIX) locale hardwired, whereas the
|
||||
<ctype.h> functions' behaviour depends on the current locale set via
|
||||
setlocale.
|
||||
|
||||
Copyright (C) 2000-2003, 2006, 2008 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program; if not, write to the Free Software Foundation,
|
||||
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
|
||||
|
||||
#ifndef C_CTYPE_H
|
||||
#define C_CTYPE_H
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/* The functions defined in this file assume the "C" locale and a character
|
||||
set without diacritics (ASCII-US or EBCDIC-US or something like that).
|
||||
Even if the "C" locale on a particular system is an extension of the ASCII
|
||||
character set (like on BeOS, where it is UTF-8, or on AmigaOS, where it
|
||||
is ISO-8859-1), the functions in this file recognize only the ASCII
|
||||
characters. */
|
||||
|
||||
|
||||
/* Check whether the ASCII optimizations apply. */
|
||||
|
||||
/* ANSI C89 (and ISO C99 5.2.1.3 too) already guarantees that
|
||||
'0', '1', ..., '9' have consecutive integer values. */
|
||||
#define C_CTYPE_CONSECUTIVE_DIGITS 1
|
||||
|
||||
#if ('A' <= 'Z') \
|
||||
&& ('A' + 1 == 'B') && ('B' + 1 == 'C') && ('C' + 1 == 'D') \
|
||||
&& ('D' + 1 == 'E') && ('E' + 1 == 'F') && ('F' + 1 == 'G') \
|
||||
&& ('G' + 1 == 'H') && ('H' + 1 == 'I') && ('I' + 1 == 'J') \
|
||||
&& ('J' + 1 == 'K') && ('K' + 1 == 'L') && ('L' + 1 == 'M') \
|
||||
&& ('M' + 1 == 'N') && ('N' + 1 == 'O') && ('O' + 1 == 'P') \
|
||||
&& ('P' + 1 == 'Q') && ('Q' + 1 == 'R') && ('R' + 1 == 'S') \
|
||||
&& ('S' + 1 == 'T') && ('T' + 1 == 'U') && ('U' + 1 == 'V') \
|
||||
&& ('V' + 1 == 'W') && ('W' + 1 == 'X') && ('X' + 1 == 'Y') \
|
||||
&& ('Y' + 1 == 'Z')
|
||||
#define C_CTYPE_CONSECUTIVE_UPPERCASE 1
|
||||
#endif
|
||||
|
||||
#if ('a' <= 'z') \
|
||||
&& ('a' + 1 == 'b') && ('b' + 1 == 'c') && ('c' + 1 == 'd') \
|
||||
&& ('d' + 1 == 'e') && ('e' + 1 == 'f') && ('f' + 1 == 'g') \
|
||||
&& ('g' + 1 == 'h') && ('h' + 1 == 'i') && ('i' + 1 == 'j') \
|
||||
&& ('j' + 1 == 'k') && ('k' + 1 == 'l') && ('l' + 1 == 'm') \
|
||||
&& ('m' + 1 == 'n') && ('n' + 1 == 'o') && ('o' + 1 == 'p') \
|
||||
&& ('p' + 1 == 'q') && ('q' + 1 == 'r') && ('r' + 1 == 's') \
|
||||
&& ('s' + 1 == 't') && ('t' + 1 == 'u') && ('u' + 1 == 'v') \
|
||||
&& ('v' + 1 == 'w') && ('w' + 1 == 'x') && ('x' + 1 == 'y') \
|
||||
&& ('y' + 1 == 'z')
|
||||
#define C_CTYPE_CONSECUTIVE_LOWERCASE 1
|
||||
#endif
|
||||
|
||||
#if (' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \
|
||||
&& ('%' == 37) && ('&' == 38) && ('\'' == 39) && ('(' == 40) \
|
||||
&& (')' == 41) && ('*' == 42) && ('+' == 43) && (',' == 44) \
|
||||
&& ('-' == 45) && ('.' == 46) && ('/' == 47) && ('0' == 48) \
|
||||
&& ('1' == 49) && ('2' == 50) && ('3' == 51) && ('4' == 52) \
|
||||
&& ('5' == 53) && ('6' == 54) && ('7' == 55) && ('8' == 56) \
|
||||
&& ('9' == 57) && (':' == 58) && (';' == 59) && ('<' == 60) \
|
||||
&& ('=' == 61) && ('>' == 62) && ('?' == 63) && ('A' == 65) \
|
||||
&& ('B' == 66) && ('C' == 67) && ('D' == 68) && ('E' == 69) \
|
||||
&& ('F' == 70) && ('G' == 71) && ('H' == 72) && ('I' == 73) \
|
||||
&& ('J' == 74) && ('K' == 75) && ('L' == 76) && ('M' == 77) \
|
||||
&& ('N' == 78) && ('O' == 79) && ('P' == 80) && ('Q' == 81) \
|
||||
&& ('R' == 82) && ('S' == 83) && ('T' == 84) && ('U' == 85) \
|
||||
&& ('V' == 86) && ('W' == 87) && ('X' == 88) && ('Y' == 89) \
|
||||
&& ('Z' == 90) && ('[' == 91) && ('\\' == 92) && (']' == 93) \
|
||||
&& ('^' == 94) && ('_' == 95) && ('a' == 97) && ('b' == 98) \
|
||||
&& ('c' == 99) && ('d' == 100) && ('e' == 101) && ('f' == 102) \
|
||||
&& ('g' == 103) && ('h' == 104) && ('i' == 105) && ('j' == 106) \
|
||||
&& ('k' == 107) && ('l' == 108) && ('m' == 109) && ('n' == 110) \
|
||||
&& ('o' == 111) && ('p' == 112) && ('q' == 113) && ('r' == 114) \
|
||||
&& ('s' == 115) && ('t' == 116) && ('u' == 117) && ('v' == 118) \
|
||||
&& ('w' == 119) && ('x' == 120) && ('y' == 121) && ('z' == 122) \
|
||||
&& ('{' == 123) && ('|' == 124) && ('}' == 125) && ('~' == 126)
|
||||
/* The character set is ASCII or one of its variants or extensions, not EBCDIC.
|
||||
Testing the value of '\n' and '\r' is not relevant. */
|
||||
#define C_CTYPE_ASCII 1
|
||||
#endif
|
||||
|
||||
|
||||
/* Function declarations. */
|
||||
|
||||
/* Unlike the functions in <ctype.h>, which require an argument in the range
|
||||
of the 'unsigned char' type, the functions here operate on values that are
|
||||
in the 'unsigned char' range or in the 'char' range. In other words,
|
||||
when you have a 'char' value, you need to cast it before using it as
|
||||
argument to a <ctype.h> function:
|
||||
|
||||
const char *s = ...;
|
||||
if (isalpha ((unsigned char) *s)) ...
|
||||
|
||||
but you don't need to cast it for the functions defined in this file:
|
||||
|
||||
const char *s = ...;
|
||||
if (c_isalpha (*s)) ...
|
||||
*/
|
||||
|
||||
extern bool c_isascii (int c); /* not locale dependent */
|
||||
|
||||
extern bool c_isalnum (int c);
|
||||
extern bool c_isalpha (int c);
|
||||
extern bool c_isblank (int c);
|
||||
extern bool c_iscntrl (int c);
|
||||
extern bool c_isdigit (int c);
|
||||
extern bool c_islower (int c);
|
||||
extern bool c_isgraph (int c);
|
||||
extern bool c_isprint (int c);
|
||||
extern bool c_ispunct (int c);
|
||||
extern bool c_isspace (int c);
|
||||
extern bool c_isupper (int c);
|
||||
extern bool c_isxdigit (int c);
|
||||
|
||||
extern int c_tolower (int c);
|
||||
extern int c_toupper (int c);
|
||||
|
||||
|
||||
#if defined __GNUC__ && defined __OPTIMIZE__ && !defined __OPTIMIZE_SIZE__ && !defined NO_C_CTYPE_MACROS
|
||||
|
||||
/* ASCII optimizations. */
|
||||
|
||||
#undef c_isascii
|
||||
#define c_isascii(c) \
|
||||
({ int __c = (c); \
|
||||
(__c >= 0x00 && __c <= 0x7f); \
|
||||
})
|
||||
|
||||
#if C_CTYPE_CONSECUTIVE_DIGITS \
|
||||
&& C_CTYPE_CONSECUTIVE_UPPERCASE && C_CTYPE_CONSECUTIVE_LOWERCASE
|
||||
#if C_CTYPE_ASCII
|
||||
#undef c_isalnum
|
||||
#define c_isalnum(c) \
|
||||
({ int __c = (c); \
|
||||
((__c >= '0' && __c <= '9') \
|
||||
|| ((__c & ~0x20) >= 'A' && (__c & ~0x20) <= 'Z')); \
|
||||
})
|
||||
#else
|
||||
#undef c_isalnum
|
||||
#define c_isalnum(c) \
|
||||
({ int __c = (c); \
|
||||
((__c >= '0' && __c <= '9') \
|
||||
|| (__c >= 'A' && __c <= 'Z') \
|
||||
|| (__c >= 'a' && __c <= 'z')); \
|
||||
})
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if C_CTYPE_CONSECUTIVE_UPPERCASE && C_CTYPE_CONSECUTIVE_LOWERCASE
|
||||
#if C_CTYPE_ASCII
|
||||
#undef c_isalpha
|
||||
#define c_isalpha(c) \
|
||||
({ int __c = (c); \
|
||||
((__c & ~0x20) >= 'A' && (__c & ~0x20) <= 'Z'); \
|
||||
})
|
||||
#else
|
||||
#undef c_isalpha
|
||||
#define c_isalpha(c) \
|
||||
({ int __c = (c); \
|
||||
((__c >= 'A' && __c <= 'Z') || (__c >= 'a' && __c <= 'z')); \
|
||||
})
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#undef c_isblank
|
||||
#define c_isblank(c) \
|
||||
({ int __c = (c); \
|
||||
(__c == ' ' || __c == '\t'); \
|
||||
})
|
||||
|
||||
#if C_CTYPE_ASCII
|
||||
#undef c_iscntrl
|
||||
#define c_iscntrl(c) \
|
||||
({ int __c = (c); \
|
||||
((__c & ~0x1f) == 0 || __c == 0x7f); \
|
||||
})
|
||||
#endif
|
||||
|
||||
#if C_CTYPE_CONSECUTIVE_DIGITS
|
||||
#undef c_isdigit
|
||||
#define c_isdigit(c) \
|
||||
({ int __c = (c); \
|
||||
(__c >= '0' && __c <= '9'); \
|
||||
})
|
||||
#endif
|
||||
|
||||
#if C_CTYPE_CONSECUTIVE_LOWERCASE
|
||||
#undef c_islower
|
||||
#define c_islower(c) \
|
||||
({ int __c = (c); \
|
||||
(__c >= 'a' && __c <= 'z'); \
|
||||
})
|
||||
#endif
|
||||
|
||||
#if C_CTYPE_ASCII
|
||||
#undef c_isgraph
|
||||
#define c_isgraph(c) \
|
||||
({ int __c = (c); \
|
||||
(__c >= '!' && __c <= '~'); \
|
||||
})
|
||||
#endif
|
||||
|
||||
#if C_CTYPE_ASCII
|
||||
#undef c_isprint
|
||||
#define c_isprint(c) \
|
||||
({ int __c = (c); \
|
||||
(__c >= ' ' && __c <= '~'); \
|
||||
})
|
||||
#endif
|
||||
|
||||
#if C_CTYPE_ASCII
|
||||
#undef c_ispunct
|
||||
#define c_ispunct(c) \
|
||||
({ int _c = (c); \
|
||||
(c_isgraph (_c) && ! c_isalnum (_c)); \
|
||||
})
|
||||
#endif
|
||||
|
||||
#undef c_isspace
|
||||
#define c_isspace(c) \
|
||||
({ int __c = (c); \
|
||||
(__c == ' ' || __c == '\t' \
|
||||
|| __c == '\n' || __c == '\v' || __c == '\f' || __c == '\r'); \
|
||||
})
|
||||
|
||||
#if C_CTYPE_CONSECUTIVE_UPPERCASE
|
||||
#undef c_isupper
|
||||
#define c_isupper(c) \
|
||||
({ int __c = (c); \
|
||||
(__c >= 'A' && __c <= 'Z'); \
|
||||
})
|
||||
#endif
|
||||
|
||||
#if C_CTYPE_CONSECUTIVE_DIGITS \
|
||||
&& C_CTYPE_CONSECUTIVE_UPPERCASE && C_CTYPE_CONSECUTIVE_LOWERCASE
|
||||
#if C_CTYPE_ASCII
|
||||
#undef c_isxdigit
|
||||
#define c_isxdigit(c) \
|
||||
({ int __c = (c); \
|
||||
((__c >= '0' && __c <= '9') \
|
||||
|| ((__c & ~0x20) >= 'A' && (__c & ~0x20) <= 'F')); \
|
||||
})
|
||||
#else
|
||||
#undef c_isxdigit
|
||||
#define c_isxdigit(c) \
|
||||
({ int __c = (c); \
|
||||
((__c >= '0' && __c <= '9') \
|
||||
|| (__c >= 'A' && __c <= 'F') \
|
||||
|| (__c >= 'a' && __c <= 'f')); \
|
||||
})
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if C_CTYPE_CONSECUTIVE_UPPERCASE && C_CTYPE_CONSECUTIVE_LOWERCASE
|
||||
#undef c_tolower
|
||||
#define c_tolower(c) \
|
||||
({ int __c = (c); \
|
||||
(__c >= 'A' && __c <= 'Z' ? __c - 'A' + 'a' : __c); \
|
||||
})
|
||||
#undef c_toupper
|
||||
#define c_toupper(c) \
|
||||
({ int __c = (c); \
|
||||
(__c >= 'a' && __c <= 'z' ? __c - 'a' + 'A' : __c); \
|
||||
})
|
||||
#endif
|
||||
|
||||
#endif /* optimizing for speed */
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* C_CTYPE_H */
|
55
lib/c-strcase.h
Normal file
55
lib/c-strcase.h
Normal file
|
@ -0,0 +1,55 @@
|
|||
/* Case-insensitive string comparison functions in C locale.
|
||||
Copyright (C) 1995-1996, 2001, 2003, 2005 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program; if not, write to the Free Software Foundation,
|
||||
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
|
||||
|
||||
#ifndef C_STRCASE_H
|
||||
#define C_STRCASE_H
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
|
||||
/* The functions defined in this file assume the "C" locale and a character
|
||||
set without diacritics (ASCII-US or EBCDIC-US or something like that).
|
||||
Even if the "C" locale on a particular system is an extension of the ASCII
|
||||
character set (like on BeOS, where it is UTF-8, or on AmigaOS, where it
|
||||
is ISO-8859-1), the functions in this file recognize only the ASCII
|
||||
characters. More precisely, one of the string arguments must be an ASCII
|
||||
string; the other one can also contain non-ASCII characters (but then
|
||||
the comparison result will be nonzero). */
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/* Compare strings S1 and S2, ignoring case, returning less than, equal to or
|
||||
greater than zero if S1 is lexicographically less than, equal to or greater
|
||||
than S2. */
|
||||
extern int c_strcasecmp (const char *s1, const char *s2);
|
||||
|
||||
/* Compare no more than N characters of strings S1 and S2, ignoring case,
|
||||
returning less than, equal to or greater than zero if S1 is
|
||||
lexicographically less than, equal to or greater than S2. */
|
||||
extern int c_strncasecmp (const char *s1, const char *s2, size_t n);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* C_STRCASE_H */
|
57
lib/c-strcasecmp.c
Normal file
57
lib/c-strcasecmp.c
Normal file
|
@ -0,0 +1,57 @@
|
|||
/* c-strcasecmp.c -- case insensitive string comparator in C locale
|
||||
Copyright (C) 1998-1999, 2005-2006 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program; if not, write to the Free Software Foundation,
|
||||
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
/* Specification. */
|
||||
#include "c-strcase.h"
|
||||
|
||||
#include <limits.h>
|
||||
|
||||
#include "c-ctype.h"
|
||||
|
||||
int
|
||||
c_strcasecmp (const char *s1, const char *s2)
|
||||
{
|
||||
register const unsigned char *p1 = (const unsigned char *) s1;
|
||||
register const unsigned char *p2 = (const unsigned char *) s2;
|
||||
unsigned char c1, c2;
|
||||
|
||||
if (p1 == p2)
|
||||
return 0;
|
||||
|
||||
do
|
||||
{
|
||||
c1 = c_tolower (*p1);
|
||||
c2 = c_tolower (*p2);
|
||||
|
||||
if (c1 == '\0')
|
||||
break;
|
||||
|
||||
++p1;
|
||||
++p2;
|
||||
}
|
||||
while (c1 == c2);
|
||||
|
||||
if (UCHAR_MAX <= INT_MAX)
|
||||
return c1 - c2;
|
||||
else
|
||||
/* On machines where 'char' and 'int' are types of the same size, the
|
||||
difference of two 'unsigned char' values - including the sign bit -
|
||||
doesn't fit in an 'int'. */
|
||||
return (c1 > c2 ? 1 : c1 < c2 ? -1 : 0);
|
||||
}
|
184
lib/c-strcaseeq.h
Normal file
184
lib/c-strcaseeq.h
Normal file
|
@ -0,0 +1,184 @@
|
|||
/* Optimized case-insensitive string comparison in C locale.
|
||||
Copyright (C) 2001-2002, 2007 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU Lesser General Public License as published
|
||||
by the Free Software Foundation; either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
/* Written by Bruno Haible <bruno@clisp.org>. */
|
||||
|
||||
#include "c-strcase.h"
|
||||
#include "c-ctype.h"
|
||||
|
||||
/* STRCASEEQ allows to optimize string comparison with a small literal string.
|
||||
STRCASEEQ (s, "UTF-8", 'U','T','F','-','8',0,0,0,0)
|
||||
is semantically equivalent to
|
||||
c_strcasecmp (s, "UTF-8") == 0
|
||||
just faster. */
|
||||
|
||||
/* Help GCC to generate good code for string comparisons with
|
||||
immediate strings. */
|
||||
#if defined (__GNUC__) && defined (__OPTIMIZE__)
|
||||
|
||||
/* Case insensitive comparison of ASCII characters. */
|
||||
# if C_CTYPE_ASCII
|
||||
# define CASEEQ(other,upper) \
|
||||
(c_isupper (upper) ? ((other) & ~0x20) == (upper) : (other) == (upper))
|
||||
# elif C_CTYPE_CONSECUTIVE_UPPERCASE && C_CTYPE_CONSECUTIVE_LOWERCASE
|
||||
# define CASEEQ(other,upper) \
|
||||
(c_isupper (upper) ? (other) == (upper) || (other) == (upper) - 'A' + 'a' : (other) == (upper))
|
||||
# else
|
||||
# define CASEEQ(other,upper) \
|
||||
(c_toupper (other) == (upper))
|
||||
# endif
|
||||
|
||||
static inline int
|
||||
strcaseeq9 (const char *s1, const char *s2)
|
||||
{
|
||||
return c_strcasecmp (s1 + 9, s2 + 9) == 0;
|
||||
}
|
||||
|
||||
static inline int
|
||||
strcaseeq8 (const char *s1, const char *s2, char s28)
|
||||
{
|
||||
if (CASEEQ (s1[8], s28))
|
||||
{
|
||||
if (s28 == 0)
|
||||
return 1;
|
||||
else
|
||||
return strcaseeq9 (s1, s2);
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int
|
||||
strcaseeq7 (const char *s1, const char *s2, char s27, char s28)
|
||||
{
|
||||
if (CASEEQ (s1[7], s27))
|
||||
{
|
||||
if (s27 == 0)
|
||||
return 1;
|
||||
else
|
||||
return strcaseeq8 (s1, s2, s28);
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int
|
||||
strcaseeq6 (const char *s1, const char *s2, char s26, char s27, char s28)
|
||||
{
|
||||
if (CASEEQ (s1[6], s26))
|
||||
{
|
||||
if (s26 == 0)
|
||||
return 1;
|
||||
else
|
||||
return strcaseeq7 (s1, s2, s27, s28);
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int
|
||||
strcaseeq5 (const char *s1, const char *s2, char s25, char s26, char s27, char s28)
|
||||
{
|
||||
if (CASEEQ (s1[5], s25))
|
||||
{
|
||||
if (s25 == 0)
|
||||
return 1;
|
||||
else
|
||||
return strcaseeq6 (s1, s2, s26, s27, s28);
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int
|
||||
strcaseeq4 (const char *s1, const char *s2, char s24, char s25, char s26, char s27, char s28)
|
||||
{
|
||||
if (CASEEQ (s1[4], s24))
|
||||
{
|
||||
if (s24 == 0)
|
||||
return 1;
|
||||
else
|
||||
return strcaseeq5 (s1, s2, s25, s26, s27, s28);
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int
|
||||
strcaseeq3 (const char *s1, const char *s2, char s23, char s24, char s25, char s26, char s27, char s28)
|
||||
{
|
||||
if (CASEEQ (s1[3], s23))
|
||||
{
|
||||
if (s23 == 0)
|
||||
return 1;
|
||||
else
|
||||
return strcaseeq4 (s1, s2, s24, s25, s26, s27, s28);
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int
|
||||
strcaseeq2 (const char *s1, const char *s2, char s22, char s23, char s24, char s25, char s26, char s27, char s28)
|
||||
{
|
||||
if (CASEEQ (s1[2], s22))
|
||||
{
|
||||
if (s22 == 0)
|
||||
return 1;
|
||||
else
|
||||
return strcaseeq3 (s1, s2, s23, s24, s25, s26, s27, s28);
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int
|
||||
strcaseeq1 (const char *s1, const char *s2, char s21, char s22, char s23, char s24, char s25, char s26, char s27, char s28)
|
||||
{
|
||||
if (CASEEQ (s1[1], s21))
|
||||
{
|
||||
if (s21 == 0)
|
||||
return 1;
|
||||
else
|
||||
return strcaseeq2 (s1, s2, s22, s23, s24, s25, s26, s27, s28);
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int
|
||||
strcaseeq0 (const char *s1, const char *s2, char s20, char s21, char s22, char s23, char s24, char s25, char s26, char s27, char s28)
|
||||
{
|
||||
if (CASEEQ (s1[0], s20))
|
||||
{
|
||||
if (s20 == 0)
|
||||
return 1;
|
||||
else
|
||||
return strcaseeq1 (s1, s2, s21, s22, s23, s24, s25, s26, s27, s28);
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define STRCASEEQ(s1,s2,s20,s21,s22,s23,s24,s25,s26,s27,s28) \
|
||||
strcaseeq0 (s1, s2, s20, s21, s22, s23, s24, s25, s26, s27, s28)
|
||||
|
||||
#else
|
||||
|
||||
#define STRCASEEQ(s1,s2,s20,s21,s22,s23,s24,s25,s26,s27,s28) \
|
||||
(c_strcasecmp (s1, s2) == 0)
|
||||
|
||||
#endif
|
57
lib/c-strncasecmp.c
Normal file
57
lib/c-strncasecmp.c
Normal file
|
@ -0,0 +1,57 @@
|
|||
/* c-strncasecmp.c -- case insensitive string comparator in C locale
|
||||
Copyright (C) 1998-1999, 2005-2006 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program; if not, write to the Free Software Foundation,
|
||||
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
/* Specification. */
|
||||
#include "c-strcase.h"
|
||||
|
||||
#include <limits.h>
|
||||
|
||||
#include "c-ctype.h"
|
||||
|
||||
int
|
||||
c_strncasecmp (const char *s1, const char *s2, size_t n)
|
||||
{
|
||||
register const unsigned char *p1 = (const unsigned char *) s1;
|
||||
register const unsigned char *p2 = (const unsigned char *) s2;
|
||||
unsigned char c1, c2;
|
||||
|
||||
if (p1 == p2 || n == 0)
|
||||
return 0;
|
||||
|
||||
do
|
||||
{
|
||||
c1 = c_tolower (*p1);
|
||||
c2 = c_tolower (*p2);
|
||||
|
||||
if (--n == 0 || c1 == '\0')
|
||||
break;
|
||||
|
||||
++p1;
|
||||
++p2;
|
||||
}
|
||||
while (c1 == c2);
|
||||
|
||||
if (UCHAR_MAX <= INT_MAX)
|
||||
return c1 - c2;
|
||||
else
|
||||
/* On machines where 'char' and 'int' are types of the same size, the
|
||||
difference of two 'unsigned char' values - including the sign bit -
|
||||
doesn't fit in an 'int'. */
|
||||
return (c1 > c2 ? 1 : c1 < c2 ? -1 : 0);
|
||||
}
|
450
lib/iconv.c
Normal file
450
lib/iconv.c
Normal file
|
@ -0,0 +1,450 @@
|
|||
/* Character set conversion.
|
||||
Copyright (C) 1999-2001, 2007 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License along
|
||||
with this program; if not, write to the Free Software Foundation,
|
||||
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
/* Specification. */
|
||||
#include <iconv.h>
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#if REPLACE_ICONV_UTF
|
||||
# include <errno.h>
|
||||
# include <stdint.h>
|
||||
# include <stdlib.h>
|
||||
# include "unistr.h"
|
||||
# ifndef uintptr_t
|
||||
# define uintptr_t unsigned long
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if REPLACE_ICONV_UTF
|
||||
|
||||
/* UTF-{16,32}{BE,LE} converters taken from GNU libiconv 1.11. */
|
||||
|
||||
/* Return code if invalid. (xxx_mbtowc) */
|
||||
# define RET_ILSEQ -1
|
||||
/* Return code if no bytes were read. (xxx_mbtowc) */
|
||||
# define RET_TOOFEW -2
|
||||
|
||||
/* Return code if invalid. (xxx_wctomb) */
|
||||
# define RET_ILUNI -1
|
||||
/* Return code if output buffer is too small. (xxx_wctomb, xxx_reset) */
|
||||
# define RET_TOOSMALL -2
|
||||
|
||||
/*
|
||||
* UTF-16BE
|
||||
*/
|
||||
|
||||
/* Specification: RFC 2781 */
|
||||
|
||||
static int
|
||||
utf16be_mbtowc (ucs4_t *pwc, const unsigned char *s, size_t n)
|
||||
{
|
||||
if (n >= 2)
|
||||
{
|
||||
ucs4_t wc = (s[0] << 8) + s[1];
|
||||
if (wc >= 0xd800 && wc < 0xdc00)
|
||||
{
|
||||
if (n >= 4)
|
||||
{
|
||||
ucs4_t wc2 = (s[2] << 8) + s[3];
|
||||
if (!(wc2 >= 0xdc00 && wc2 < 0xe000))
|
||||
return RET_ILSEQ;
|
||||
*pwc = 0x10000 + ((wc - 0xd800) << 10) + (wc2 - 0xdc00);
|
||||
return 4;
|
||||
}
|
||||
}
|
||||
else if (wc >= 0xdc00 && wc < 0xe000)
|
||||
{
|
||||
return RET_ILSEQ;
|
||||
}
|
||||
else
|
||||
{
|
||||
*pwc = wc;
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
return RET_TOOFEW;
|
||||
}
|
||||
|
||||
static int
|
||||
utf16be_wctomb (unsigned char *r, ucs4_t wc, size_t n)
|
||||
{
|
||||
if (!(wc >= 0xd800 && wc < 0xe000))
|
||||
{
|
||||
if (wc < 0x10000)
|
||||
{
|
||||
if (n >= 2)
|
||||
{
|
||||
r[0] = (unsigned char) (wc >> 8);
|
||||
r[1] = (unsigned char) wc;
|
||||
return 2;
|
||||
}
|
||||
else
|
||||
return RET_TOOSMALL;
|
||||
}
|
||||
else if (wc < 0x110000)
|
||||
{
|
||||
if (n >= 4)
|
||||
{
|
||||
ucs4_t wc1 = 0xd800 + ((wc - 0x10000) >> 10);
|
||||
ucs4_t wc2 = 0xdc00 + ((wc - 0x10000) & 0x3ff);
|
||||
r[0] = (unsigned char) (wc1 >> 8);
|
||||
r[1] = (unsigned char) wc1;
|
||||
r[2] = (unsigned char) (wc2 >> 8);
|
||||
r[3] = (unsigned char) wc2;
|
||||
return 4;
|
||||
}
|
||||
else
|
||||
return RET_TOOSMALL;
|
||||
}
|
||||
}
|
||||
return RET_ILUNI;
|
||||
}
|
||||
|
||||
/*
|
||||
* UTF-16LE
|
||||
*/
|
||||
|
||||
/* Specification: RFC 2781 */
|
||||
|
||||
static int
|
||||
utf16le_mbtowc (ucs4_t *pwc, const unsigned char *s, size_t n)
|
||||
{
|
||||
if (n >= 2)
|
||||
{
|
||||
ucs4_t wc = s[0] + (s[1] << 8);
|
||||
if (wc >= 0xd800 && wc < 0xdc00)
|
||||
{
|
||||
if (n >= 4)
|
||||
{
|
||||
ucs4_t wc2 = s[2] + (s[3] << 8);
|
||||
if (!(wc2 >= 0xdc00 && wc2 < 0xe000))
|
||||
return RET_ILSEQ;
|
||||
*pwc = 0x10000 + ((wc - 0xd800) << 10) + (wc2 - 0xdc00);
|
||||
return 4;
|
||||
}
|
||||
}
|
||||
else if (wc >= 0xdc00 && wc < 0xe000)
|
||||
{
|
||||
return RET_ILSEQ;
|
||||
}
|
||||
else
|
||||
{
|
||||
*pwc = wc;
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
return RET_TOOFEW;
|
||||
}
|
||||
|
||||
static int
|
||||
utf16le_wctomb (unsigned char *r, ucs4_t wc, size_t n)
|
||||
{
|
||||
if (!(wc >= 0xd800 && wc < 0xe000))
|
||||
{
|
||||
if (wc < 0x10000)
|
||||
{
|
||||
if (n >= 2)
|
||||
{
|
||||
r[0] = (unsigned char) wc;
|
||||
r[1] = (unsigned char) (wc >> 8);
|
||||
return 2;
|
||||
}
|
||||
else
|
||||
return RET_TOOSMALL;
|
||||
}
|
||||
else if (wc < 0x110000)
|
||||
{
|
||||
if (n >= 4)
|
||||
{
|
||||
ucs4_t wc1 = 0xd800 + ((wc - 0x10000) >> 10);
|
||||
ucs4_t wc2 = 0xdc00 + ((wc - 0x10000) & 0x3ff);
|
||||
r[0] = (unsigned char) wc1;
|
||||
r[1] = (unsigned char) (wc1 >> 8);
|
||||
r[2] = (unsigned char) wc2;
|
||||
r[3] = (unsigned char) (wc2 >> 8);
|
||||
return 4;
|
||||
}
|
||||
else
|
||||
return RET_TOOSMALL;
|
||||
}
|
||||
}
|
||||
return RET_ILUNI;
|
||||
}
|
||||
|
||||
/*
|
||||
* UTF-32BE
|
||||
*/
|
||||
|
||||
/* Specification: Unicode 3.1 Standard Annex #19 */
|
||||
|
||||
static int
|
||||
utf32be_mbtowc (ucs4_t *pwc, const unsigned char *s, size_t n)
|
||||
{
|
||||
if (n >= 4)
|
||||
{
|
||||
ucs4_t wc = (s[0] << 24) + (s[1] << 16) + (s[2] << 8) + s[3];
|
||||
if (wc < 0x110000 && !(wc >= 0xd800 && wc < 0xe000))
|
||||
{
|
||||
*pwc = wc;
|
||||
return 4;
|
||||
}
|
||||
else
|
||||
return RET_ILSEQ;
|
||||
}
|
||||
return RET_TOOFEW;
|
||||
}
|
||||
|
||||
static int
|
||||
utf32be_wctomb (unsigned char *r, ucs4_t wc, size_t n)
|
||||
{
|
||||
if (wc < 0x110000 && !(wc >= 0xd800 && wc < 0xe000))
|
||||
{
|
||||
if (n >= 4)
|
||||
{
|
||||
r[0] = 0;
|
||||
r[1] = (unsigned char) (wc >> 16);
|
||||
r[2] = (unsigned char) (wc >> 8);
|
||||
r[3] = (unsigned char) wc;
|
||||
return 4;
|
||||
}
|
||||
else
|
||||
return RET_TOOSMALL;
|
||||
}
|
||||
return RET_ILUNI;
|
||||
}
|
||||
|
||||
/*
|
||||
* UTF-32LE
|
||||
*/
|
||||
|
||||
/* Specification: Unicode 3.1 Standard Annex #19 */
|
||||
|
||||
static int
|
||||
utf32le_mbtowc (ucs4_t *pwc, const unsigned char *s, size_t n)
|
||||
{
|
||||
if (n >= 4)
|
||||
{
|
||||
ucs4_t wc = s[0] + (s[1] << 8) + (s[2] << 16) + (s[3] << 24);
|
||||
if (wc < 0x110000 && !(wc >= 0xd800 && wc < 0xe000))
|
||||
{
|
||||
*pwc = wc;
|
||||
return 4;
|
||||
}
|
||||
else
|
||||
return RET_ILSEQ;
|
||||
}
|
||||
return RET_TOOFEW;
|
||||
}
|
||||
|
||||
static int
|
||||
utf32le_wctomb (unsigned char *r, ucs4_t wc, size_t n)
|
||||
{
|
||||
if (wc < 0x110000 && !(wc >= 0xd800 && wc < 0xe000))
|
||||
{
|
||||
if (n >= 4)
|
||||
{
|
||||
r[0] = (unsigned char) wc;
|
||||
r[1] = (unsigned char) (wc >> 8);
|
||||
r[2] = (unsigned char) (wc >> 16);
|
||||
r[3] = 0;
|
||||
return 4;
|
||||
}
|
||||
else
|
||||
return RET_TOOSMALL;
|
||||
}
|
||||
return RET_ILUNI;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
size_t
|
||||
rpl_iconv (iconv_t cd,
|
||||
ICONV_CONST char **inbuf, size_t *inbytesleft,
|
||||
char **outbuf, size_t *outbytesleft)
|
||||
#undef iconv
|
||||
{
|
||||
#if REPLACE_ICONV_UTF
|
||||
switch ((uintptr_t) cd)
|
||||
{
|
||||
{
|
||||
int (*xxx_wctomb) (unsigned char *, ucs4_t, size_t);
|
||||
|
||||
case (uintptr_t) _ICONV_UTF8_UTF16BE:
|
||||
xxx_wctomb = utf16be_wctomb;
|
||||
goto loop_from_utf8;
|
||||
case (uintptr_t) _ICONV_UTF8_UTF16LE:
|
||||
xxx_wctomb = utf16le_wctomb;
|
||||
goto loop_from_utf8;
|
||||
case (uintptr_t) _ICONV_UTF8_UTF32BE:
|
||||
xxx_wctomb = utf32be_wctomb;
|
||||
goto loop_from_utf8;
|
||||
case (uintptr_t) _ICONV_UTF8_UTF32LE:
|
||||
xxx_wctomb = utf32le_wctomb;
|
||||
goto loop_from_utf8;
|
||||
|
||||
loop_from_utf8:
|
||||
if (inbuf == NULL || *inbuf == NULL)
|
||||
return 0;
|
||||
{
|
||||
ICONV_CONST char *inptr = *inbuf;
|
||||
size_t inleft = *inbytesleft;
|
||||
char *outptr = *outbuf;
|
||||
size_t outleft = *outbytesleft;
|
||||
size_t res = 0;
|
||||
while (inleft > 0)
|
||||
{
|
||||
ucs4_t uc;
|
||||
int m = u8_mbtoucr (&uc, (const uint8_t *) inptr, inleft);
|
||||
if (m <= 0)
|
||||
{
|
||||
if (m == -1)
|
||||
{
|
||||
errno = EILSEQ;
|
||||
res = (size_t)(-1);
|
||||
break;
|
||||
}
|
||||
if (m == -2)
|
||||
{
|
||||
errno = EINVAL;
|
||||
res = (size_t)(-1);
|
||||
break;
|
||||
}
|
||||
abort ();
|
||||
}
|
||||
else
|
||||
{
|
||||
int n = xxx_wctomb ((uint8_t *) outptr, uc, outleft);
|
||||
if (n < 0)
|
||||
{
|
||||
if (n == RET_ILUNI)
|
||||
{
|
||||
errno = EILSEQ;
|
||||
res = (size_t)(-1);
|
||||
break;
|
||||
}
|
||||
if (n == RET_TOOSMALL)
|
||||
{
|
||||
errno = E2BIG;
|
||||
res = (size_t)(-1);
|
||||
break;
|
||||
}
|
||||
abort ();
|
||||
}
|
||||
else
|
||||
{
|
||||
inptr += m;
|
||||
inleft -= m;
|
||||
outptr += n;
|
||||
outleft -= n;
|
||||
}
|
||||
}
|
||||
}
|
||||
*inbuf = inptr;
|
||||
*inbytesleft = inleft;
|
||||
*outbuf = outptr;
|
||||
*outbytesleft = outleft;
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
int (*xxx_mbtowc) (ucs4_t *, const unsigned char *, size_t);
|
||||
|
||||
case (uintptr_t) _ICONV_UTF16BE_UTF8:
|
||||
xxx_mbtowc = utf16be_mbtowc;
|
||||
goto loop_to_utf8;
|
||||
case (uintptr_t) _ICONV_UTF16LE_UTF8:
|
||||
xxx_mbtowc = utf16le_mbtowc;
|
||||
goto loop_to_utf8;
|
||||
case (uintptr_t) _ICONV_UTF32BE_UTF8:
|
||||
xxx_mbtowc = utf32be_mbtowc;
|
||||
goto loop_to_utf8;
|
||||
case (uintptr_t) _ICONV_UTF32LE_UTF8:
|
||||
xxx_mbtowc = utf32le_mbtowc;
|
||||
goto loop_to_utf8;
|
||||
|
||||
loop_to_utf8:
|
||||
if (inbuf == NULL || *inbuf == NULL)
|
||||
return 0;
|
||||
{
|
||||
ICONV_CONST char *inptr = *inbuf;
|
||||
size_t inleft = *inbytesleft;
|
||||
char *outptr = *outbuf;
|
||||
size_t outleft = *outbytesleft;
|
||||
size_t res = 0;
|
||||
while (inleft > 0)
|
||||
{
|
||||
ucs4_t uc;
|
||||
int m = xxx_mbtowc (&uc, (const uint8_t *) inptr, inleft);
|
||||
if (m <= 0)
|
||||
{
|
||||
if (m == RET_ILSEQ)
|
||||
{
|
||||
errno = EILSEQ;
|
||||
res = (size_t)(-1);
|
||||
break;
|
||||
}
|
||||
if (m == RET_TOOFEW)
|
||||
{
|
||||
errno = EINVAL;
|
||||
res = (size_t)(-1);
|
||||
break;
|
||||
}
|
||||
abort ();
|
||||
}
|
||||
else
|
||||
{
|
||||
int n = u8_uctomb ((uint8_t *) outptr, uc, outleft);
|
||||
if (n < 0)
|
||||
{
|
||||
if (n == -1)
|
||||
{
|
||||
errno = EILSEQ;
|
||||
res = (size_t)(-1);
|
||||
break;
|
||||
}
|
||||
if (n == -2)
|
||||
{
|
||||
errno = E2BIG;
|
||||
res = (size_t)(-1);
|
||||
break;
|
||||
}
|
||||
abort ();
|
||||
}
|
||||
else
|
||||
{
|
||||
inptr += m;
|
||||
inleft -= m;
|
||||
outptr += n;
|
||||
outleft -= n;
|
||||
}
|
||||
}
|
||||
}
|
||||
*inbuf = inptr;
|
||||
*inbytesleft = inleft;
|
||||
*outbuf = outptr;
|
||||
*outbytesleft = outleft;
|
||||
return res;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return iconv (cd, inbuf, inbytesleft, outbuf, outbytesleft);
|
||||
}
|
71
lib/iconv.in.h
Normal file
71
lib/iconv.in.h
Normal file
|
@ -0,0 +1,71 @@
|
|||
/* A GNU-like <iconv.h>.
|
||||
|
||||
Copyright (C) 2007-2008 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program; if not, write to the Free Software Foundation,
|
||||
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
|
||||
|
||||
#ifndef _GL_ICONV_H
|
||||
|
||||
#if __GNUC__ >= 3
|
||||
@PRAGMA_SYSTEM_HEADER@
|
||||
#endif
|
||||
|
||||
/* The include_next requires a split double-inclusion guard. */
|
||||
#@INCLUDE_NEXT@ @NEXT_ICONV_H@
|
||||
|
||||
#ifndef _GL_ICONV_H
|
||||
#define _GL_ICONV_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
#if @REPLACE_ICONV_OPEN@
|
||||
/* An iconv_open wrapper that supports the IANA standardized encoding names
|
||||
("ISO-8859-1" etc.) as far as possible. */
|
||||
# define iconv_open rpl_iconv_open
|
||||
extern iconv_t iconv_open (const char *tocode, const char *fromcode);
|
||||
#endif
|
||||
|
||||
#if @REPLACE_ICONV_UTF@
|
||||
/* Special constants for supporting UTF-{16,32}{BE,LE} encodings.
|
||||
Not public. */
|
||||
# define _ICONV_UTF8_UTF16BE (iconv_t)(-161)
|
||||
# define _ICONV_UTF8_UTF16LE (iconv_t)(-162)
|
||||
# define _ICONV_UTF8_UTF32BE (iconv_t)(-163)
|
||||
# define _ICONV_UTF8_UTF32LE (iconv_t)(-164)
|
||||
# define _ICONV_UTF16BE_UTF8 (iconv_t)(-165)
|
||||
# define _ICONV_UTF16LE_UTF8 (iconv_t)(-166)
|
||||
# define _ICONV_UTF32BE_UTF8 (iconv_t)(-167)
|
||||
# define _ICONV_UTF32LE_UTF8 (iconv_t)(-168)
|
||||
#endif
|
||||
|
||||
#if @REPLACE_ICONV@
|
||||
# define iconv rpl_iconv
|
||||
extern size_t iconv (iconv_t cd,
|
||||
@ICONV_CONST@ char **inbuf, size_t *inbytesleft,
|
||||
char **outbuf, size_t *outbytesleft);
|
||||
# define iconv_close rpl_iconv_close
|
||||
extern int iconv_close (iconv_t cd);
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _GL_ICONV_H */
|
||||
#endif /* _GL_ICONV_H */
|
47
lib/iconv_close.c
Normal file
47
lib/iconv_close.c
Normal file
|
@ -0,0 +1,47 @@
|
|||
/* Character set conversion.
|
||||
Copyright (C) 2007 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License along
|
||||
with this program; if not, write to the Free Software Foundation,
|
||||
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
/* Specification. */
|
||||
#include <iconv.h>
|
||||
|
||||
#include <stdint.h>
|
||||
#ifndef uintptr_t
|
||||
# define uintptr_t unsigned long
|
||||
#endif
|
||||
|
||||
int
|
||||
rpl_iconv_close (iconv_t cd)
|
||||
#undef iconv_close
|
||||
{
|
||||
#if REPLACE_ICONV_UTF
|
||||
switch ((uintptr_t) cd)
|
||||
{
|
||||
case (uintptr_t) _ICONV_UTF8_UTF16BE:
|
||||
case (uintptr_t) _ICONV_UTF8_UTF16LE:
|
||||
case (uintptr_t) _ICONV_UTF8_UTF32BE:
|
||||
case (uintptr_t) _ICONV_UTF8_UTF32LE:
|
||||
case (uintptr_t) _ICONV_UTF16BE_UTF8:
|
||||
case (uintptr_t) _ICONV_UTF16LE_UTF8:
|
||||
case (uintptr_t) _ICONV_UTF32BE_UTF8:
|
||||
case (uintptr_t) _ICONV_UTF32LE_UTF8:
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
return iconv_close (cd);
|
||||
}
|
44
lib/iconv_open-aix.gperf
Normal file
44
lib/iconv_open-aix.gperf
Normal file
|
@ -0,0 +1,44 @@
|
|||
struct mapping { int standard_name; const char vendor_name[10 + 1]; };
|
||||
%struct-type
|
||||
%language=ANSI-C
|
||||
%define slot-name standard_name
|
||||
%define hash-function-name mapping_hash
|
||||
%define lookup-function-name mapping_lookup
|
||||
%readonly-tables
|
||||
%global-table
|
||||
%define word-array-name mappings
|
||||
%pic
|
||||
%%
|
||||
# On AIX 5.1, look in /usr/lib/nls/loc/uconvTable.
|
||||
ISO-8859-1, "ISO8859-1"
|
||||
ISO-8859-2, "ISO8859-2"
|
||||
ISO-8859-3, "ISO8859-3"
|
||||
ISO-8859-4, "ISO8859-4"
|
||||
ISO-8859-5, "ISO8859-5"
|
||||
ISO-8859-6, "ISO8859-6"
|
||||
ISO-8859-7, "ISO8859-7"
|
||||
ISO-8859-8, "ISO8859-8"
|
||||
ISO-8859-9, "ISO8859-9"
|
||||
ISO-8859-15, "ISO8859-15"
|
||||
CP437, "IBM-437"
|
||||
CP850, "IBM-850"
|
||||
CP852, "IBM-852"
|
||||
CP856, "IBM-856"
|
||||
CP857, "IBM-857"
|
||||
CP861, "IBM-861"
|
||||
CP865, "IBM-865"
|
||||
CP869, "IBM-869"
|
||||
ISO-8859-13, "IBM-921"
|
||||
CP922, "IBM-922"
|
||||
CP932, "IBM-932"
|
||||
CP943, "IBM-943"
|
||||
CP1046, "IBM-1046"
|
||||
CP1124, "IBM-1124"
|
||||
CP1125, "IBM-1125"
|
||||
CP1129, "IBM-1129"
|
||||
CP1252, "IBM-1252"
|
||||
GB2312, "IBM-eucCN"
|
||||
EUC-JP, "IBM-eucJP"
|
||||
EUC-KR, "IBM-eucKR"
|
||||
EUC-TW, "IBM-eucTW"
|
||||
BIG5, "big5"
|
56
lib/iconv_open-hpux.gperf
Normal file
56
lib/iconv_open-hpux.gperf
Normal file
|
@ -0,0 +1,56 @@
|
|||
struct mapping { int standard_name; const char vendor_name[9 + 1]; };
|
||||
%struct-type
|
||||
%language=ANSI-C
|
||||
%define slot-name standard_name
|
||||
%define hash-function-name mapping_hash
|
||||
%define lookup-function-name mapping_lookup
|
||||
%readonly-tables
|
||||
%global-table
|
||||
%define word-array-name mappings
|
||||
%pic
|
||||
%%
|
||||
# On HP-UX 11.11, look in /usr/lib/nls/iconv.
|
||||
ISO-8859-1, "iso88591"
|
||||
ISO-8859-2, "iso88592"
|
||||
ISO-8859-5, "iso88595"
|
||||
ISO-8859-6, "iso88596"
|
||||
ISO-8859-7, "iso88597"
|
||||
ISO-8859-8, "iso88598"
|
||||
ISO-8859-9, "iso88599"
|
||||
ISO-8859-15, "iso885915"
|
||||
CP437, "cp437"
|
||||
CP775, "cp775"
|
||||
CP850, "cp850"
|
||||
CP852, "cp852"
|
||||
CP855, "cp855"
|
||||
CP857, "cp857"
|
||||
CP861, "cp861"
|
||||
CP862, "cp862"
|
||||
CP864, "cp864"
|
||||
CP865, "cp865"
|
||||
CP866, "cp866"
|
||||
CP869, "cp869"
|
||||
CP874, "cp874"
|
||||
CP1250, "cp1250"
|
||||
CP1251, "cp1251"
|
||||
CP1252, "cp1252"
|
||||
CP1253, "cp1253"
|
||||
CP1254, "cp1254"
|
||||
CP1255, "cp1255"
|
||||
CP1256, "cp1256"
|
||||
CP1257, "cp1257"
|
||||
CP1258, "cp1258"
|
||||
HP-ROMAN8, "roman8"
|
||||
HP-ARABIC8, "arabic8"
|
||||
HP-GREEK8, "greek8"
|
||||
HP-HEBREW8, "hebrew8"
|
||||
HP-TURKISH8, "turkish8"
|
||||
HP-KANA8, "kana8"
|
||||
TIS-620, "tis620"
|
||||
GB2312, "hp15CN"
|
||||
EUC-JP, "eucJP"
|
||||
EUC-KR, "eucKR"
|
||||
EUC-TW, "eucTW"
|
||||
BIG5, "big5"
|
||||
SHIFT_JIS, "sjis"
|
||||
UTF-8, "utf8"
|
31
lib/iconv_open-irix.gperf
Normal file
31
lib/iconv_open-irix.gperf
Normal file
|
@ -0,0 +1,31 @@
|
|||
struct mapping { int standard_name; const char vendor_name[10 + 1]; };
|
||||
%struct-type
|
||||
%language=ANSI-C
|
||||
%define slot-name standard_name
|
||||
%define hash-function-name mapping_hash
|
||||
%define lookup-function-name mapping_lookup
|
||||
%readonly-tables
|
||||
%global-table
|
||||
%define word-array-name mappings
|
||||
%pic
|
||||
%%
|
||||
# On IRIX 6.5, look in /usr/lib/iconv and /usr/lib/international/encodings.
|
||||
ISO-8859-1, "ISO8859-1"
|
||||
ISO-8859-2, "ISO8859-2"
|
||||
ISO-8859-3, "ISO8859-3"
|
||||
ISO-8859-4, "ISO8859-4"
|
||||
ISO-8859-5, "ISO8859-5"
|
||||
ISO-8859-6, "ISO8859-6"
|
||||
ISO-8859-7, "ISO8859-7"
|
||||
ISO-8859-8, "ISO8859-8"
|
||||
ISO-8859-9, "ISO8859-9"
|
||||
ISO-8859-15, "ISO8859-15"
|
||||
KOI8-R, "KOI8"
|
||||
CP855, "DOS855"
|
||||
CP1251, "WIN1251"
|
||||
GB2312, "eucCN"
|
||||
EUC-JP, "eucJP"
|
||||
EUC-KR, "eucKR"
|
||||
EUC-TW, "eucTW"
|
||||
SHIFT_JIS, "sjis"
|
||||
TIS-620, "TIS620"
|
50
lib/iconv_open-osf.gperf
Normal file
50
lib/iconv_open-osf.gperf
Normal file
|
@ -0,0 +1,50 @@
|
|||
struct mapping { int standard_name; const char vendor_name[10 + 1]; };
|
||||
%struct-type
|
||||
%language=ANSI-C
|
||||
%define slot-name standard_name
|
||||
%define hash-function-name mapping_hash
|
||||
%define lookup-function-name mapping_lookup
|
||||
%readonly-tables
|
||||
%global-table
|
||||
%define word-array-name mappings
|
||||
%pic
|
||||
%%
|
||||
# On OSF/1 5.1, look in /usr/lib/nls/loc/iconv.
|
||||
ISO-8859-1, "ISO8859-1"
|
||||
ISO-8859-2, "ISO8859-2"
|
||||
ISO-8859-3, "ISO8859-3"
|
||||
ISO-8859-4, "ISO8859-4"
|
||||
ISO-8859-5, "ISO8859-5"
|
||||
ISO-8859-6, "ISO8859-6"
|
||||
ISO-8859-7, "ISO8859-7"
|
||||
ISO-8859-8, "ISO8859-8"
|
||||
ISO-8859-9, "ISO8859-9"
|
||||
ISO-8859-15, "ISO8859-15"
|
||||
CP437, "cp437"
|
||||
CP775, "cp775"
|
||||
CP850, "cp850"
|
||||
CP852, "cp852"
|
||||
CP855, "cp855"
|
||||
CP857, "cp857"
|
||||
CP861, "cp861"
|
||||
CP862, "cp862"
|
||||
CP865, "cp865"
|
||||
CP866, "cp866"
|
||||
CP869, "cp869"
|
||||
CP874, "cp874"
|
||||
CP949, "KSC5601"
|
||||
CP1250, "cp1250"
|
||||
CP1251, "cp1251"
|
||||
CP1252, "cp1252"
|
||||
CP1253, "cp1253"
|
||||
CP1254, "cp1254"
|
||||
CP1255, "cp1255"
|
||||
CP1256, "cp1256"
|
||||
CP1257, "cp1257"
|
||||
CP1258, "cp1258"
|
||||
EUC-JP, "eucJP"
|
||||
EUC-KR, "eucKR"
|
||||
EUC-TW, "eucTW"
|
||||
BIG5, "big5"
|
||||
SHIFT_JIS, "SJIS"
|
||||
TIS-620, "TACTIS"
|
172
lib/iconv_open.c
Normal file
172
lib/iconv_open.c
Normal file
|
@ -0,0 +1,172 @@
|
|||
/* Character set conversion.
|
||||
Copyright (C) 2007 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License along
|
||||
with this program; if not, write to the Free Software Foundation,
|
||||
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
/* Specification. */
|
||||
#include <iconv.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include "c-ctype.h"
|
||||
#include "c-strcase.h"
|
||||
|
||||
#define SIZEOF(a) (sizeof(a) / sizeof(a[0]))
|
||||
|
||||
/* Namespace cleanliness. */
|
||||
#define mapping_lookup rpl_iconv_open_mapping_lookup
|
||||
|
||||
/* The macro ICONV_FLAVOR is defined to one of these or undefined. */
|
||||
|
||||
#define ICONV_FLAVOR_AIX "iconv_open-aix.h"
|
||||
#define ICONV_FLAVOR_HPUX "iconv_open-hpux.h"
|
||||
#define ICONV_FLAVOR_IRIX "iconv_open-irix.h"
|
||||
#define ICONV_FLAVOR_OSF "iconv_open-osf.h"
|
||||
|
||||
#ifdef ICONV_FLAVOR
|
||||
# include ICONV_FLAVOR
|
||||
#endif
|
||||
|
||||
iconv_t
|
||||
rpl_iconv_open (const char *tocode, const char *fromcode)
|
||||
#undef iconv_open
|
||||
{
|
||||
char fromcode_upper[32];
|
||||
char tocode_upper[32];
|
||||
char *fromcode_upper_end;
|
||||
char *tocode_upper_end;
|
||||
|
||||
#if REPLACE_ICONV_UTF
|
||||
/* Special handling of conversion between UTF-8 and UTF-{16,32}{BE,LE}.
|
||||
Do this here, before calling the real iconv_open(), because OSF/1 5.1
|
||||
iconv() to these encoding inserts a BOM, which is wrong.
|
||||
We do not need to handle conversion between arbitrary encodings and
|
||||
UTF-{16,32}{BE,LE}, because the 'striconveh' module implements two-step
|
||||
conversion throough UTF-8.
|
||||
The _ICONV_* constants are chosen to be disjoint from any iconv_t
|
||||
returned by the system's iconv_open() functions. Recall that iconv_t
|
||||
is a scalar type. */
|
||||
if (c_toupper (fromcode[0]) == 'U'
|
||||
&& c_toupper (fromcode[1]) == 'T'
|
||||
&& c_toupper (fromcode[2]) == 'F'
|
||||
&& fromcode[3] == '-')
|
||||
{
|
||||
if (c_toupper (tocode[0]) == 'U'
|
||||
&& c_toupper (tocode[1]) == 'T'
|
||||
&& c_toupper (tocode[2]) == 'F'
|
||||
&& tocode[3] == '-')
|
||||
{
|
||||
if (strcmp (fromcode + 4, "8") == 0)
|
||||
{
|
||||
if (c_strcasecmp (tocode + 4, "16BE") == 0)
|
||||
return _ICONV_UTF8_UTF16BE;
|
||||
if (c_strcasecmp (tocode + 4, "16LE") == 0)
|
||||
return _ICONV_UTF8_UTF16LE;
|
||||
if (c_strcasecmp (tocode + 4, "32BE") == 0)
|
||||
return _ICONV_UTF8_UTF32BE;
|
||||
if (c_strcasecmp (tocode + 4, "32LE") == 0)
|
||||
return _ICONV_UTF8_UTF32LE;
|
||||
}
|
||||
else if (strcmp (tocode + 4, "8") == 0)
|
||||
{
|
||||
if (c_strcasecmp (fromcode + 4, "16BE") == 0)
|
||||
return _ICONV_UTF16BE_UTF8;
|
||||
if (c_strcasecmp (fromcode + 4, "16LE") == 0)
|
||||
return _ICONV_UTF16LE_UTF8;
|
||||
if (c_strcasecmp (fromcode + 4, "32BE") == 0)
|
||||
return _ICONV_UTF32BE_UTF8;
|
||||
if (c_strcasecmp (fromcode + 4, "32LE") == 0)
|
||||
return _ICONV_UTF32LE_UTF8;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Do *not* add special support for 8-bit encodings like ASCII or ISO-8859-1
|
||||
here. This would lead to programs that work in some locales (such as the
|
||||
"C" or "en_US" locales) but do not work in East Asian locales. It is
|
||||
better if programmers make their programs depend on GNU libiconv (except
|
||||
on glibc systems), e.g. by using the AM_ICONV macro and documenting the
|
||||
dependency in an INSTALL or DEPENDENCIES file. */
|
||||
|
||||
/* Try with the original names first.
|
||||
This covers the case when fromcode or tocode is a lowercase encoding name
|
||||
that is understood by the system's iconv_open but not listed in our
|
||||
mappings table. */
|
||||
{
|
||||
iconv_t cd = iconv_open (tocode, fromcode);
|
||||
if (cd != (iconv_t)(-1))
|
||||
return cd;
|
||||
}
|
||||
|
||||
/* Convert the encodings to upper case, because
|
||||
1. in the arguments of iconv_open() on AIX, HP-UX, and OSF/1 the case
|
||||
matters,
|
||||
2. it makes searching in the table faster. */
|
||||
{
|
||||
const char *p = fromcode;
|
||||
char *q = fromcode_upper;
|
||||
while ((*q = c_toupper (*p)) != '\0')
|
||||
{
|
||||
p++;
|
||||
q++;
|
||||
if (q == &fromcode_upper[SIZEOF (fromcode_upper)])
|
||||
{
|
||||
errno = EINVAL;
|
||||
return (iconv_t)(-1);
|
||||
}
|
||||
}
|
||||
fromcode_upper_end = q;
|
||||
}
|
||||
|
||||
{
|
||||
const char *p = tocode;
|
||||
char *q = tocode_upper;
|
||||
while ((*q = c_toupper (*p)) != '\0')
|
||||
{
|
||||
p++;
|
||||
q++;
|
||||
if (q == &tocode_upper[SIZEOF (tocode_upper)])
|
||||
{
|
||||
errno = EINVAL;
|
||||
return (iconv_t)(-1);
|
||||
}
|
||||
}
|
||||
tocode_upper_end = q;
|
||||
}
|
||||
|
||||
#ifdef ICONV_FLAVOR
|
||||
/* Apply the mappings. */
|
||||
{
|
||||
const struct mapping *m =
|
||||
mapping_lookup (fromcode_upper, fromcode_upper_end - fromcode_upper);
|
||||
|
||||
fromcode = (m != NULL ? m->vendor_name : fromcode_upper);
|
||||
}
|
||||
{
|
||||
const struct mapping *m =
|
||||
mapping_lookup (tocode_upper, tocode_upper_end - tocode_upper);
|
||||
|
||||
tocode = (m != NULL ? m->vendor_name : tocode_upper);
|
||||
}
|
||||
#else
|
||||
fromcode = fromcode_upper;
|
||||
tocode = tocode_upper;
|
||||
#endif
|
||||
|
||||
return iconv_open (tocode, fromcode);
|
||||
}
|
41
lib/iconveh.h
Normal file
41
lib/iconveh.h
Normal file
|
@ -0,0 +1,41 @@
|
|||
/* Character set conversion handler type.
|
||||
Copyright (C) 2001-2007, 2009 Free Software Foundation, Inc.
|
||||
Written by Bruno Haible.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation; either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef _ICONVEH_H
|
||||
#define _ICONVEH_H
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/* Handling of unconvertible characters. */
|
||||
enum iconv_ilseq_handler
|
||||
{
|
||||
iconveh_error, /* return and set errno = EILSEQ */
|
||||
iconveh_question_mark, /* use one '?' per unconvertible character */
|
||||
iconveh_escape_sequence /* use escape sequence \uxxxx or \Uxxxxxxxx */
|
||||
};
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* _ICONVEH_H */
|
1251
lib/striconveh.c
Normal file
1251
lib/striconveh.c
Normal file
File diff suppressed because it is too large
Load diff
120
lib/striconveh.h
Normal file
120
lib/striconveh.h
Normal file
|
@ -0,0 +1,120 @@
|
|||
/* Character set conversion with error handling.
|
||||
Copyright (C) 2001-2007, 2009 Free Software Foundation, Inc.
|
||||
Written by Bruno Haible and Simon Josefsson.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation; either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef _STRICONVEH_H
|
||||
#define _STRICONVEH_H
|
||||
|
||||
#include <stddef.h>
|
||||
#if HAVE_ICONV
|
||||
#include <iconv.h>
|
||||
#endif
|
||||
|
||||
#include "iconveh.h"
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
#if HAVE_ICONV
|
||||
|
||||
/* Convert an entire string from one encoding to another, using iconv.
|
||||
The original string is at [SRC,...,SRC+SRCLEN-1].
|
||||
CD is the conversion descriptor from FROMCODE to TOCODE, or (iconv_t)(-1) if
|
||||
the system does not support a direct conversion from FROMCODE to TOCODE.
|
||||
CD1 is the conversion descriptor from FROM_CODESET to UTF-8 (or
|
||||
(iconv_t)(-1) if FROM_CODESET is UTF-8).
|
||||
CD2 is the conversion descriptor from UTF-8 to TO_CODESET (or (iconv_t)(-1)
|
||||
if TO_CODESET is UTF-8).
|
||||
If OFFSETS is not NULL, it should point to an array of SRCLEN integers; this
|
||||
array is filled with offsets into the result, i.e. the character starting
|
||||
at SRC[i] corresponds to the character starting at (*RESULTP)[OFFSETS[i]],
|
||||
and other offsets are set to (size_t)(-1).
|
||||
*RESULTP and *LENGTH should initially be a scratch buffer and its size,
|
||||
or *RESULTP can initially be NULL.
|
||||
May erase the contents of the memory at *RESULTP.
|
||||
Return value: 0 if successful, otherwise -1 and errno set.
|
||||
If successful: The resulting string is stored in *RESULTP and its length
|
||||
in *LENGTHP. *RESULTP is set to a freshly allocated memory block, or is
|
||||
unchanged if no dynamic memory allocation was necessary. */
|
||||
extern int
|
||||
mem_cd_iconveh (const char *src, size_t srclen,
|
||||
iconv_t cd, iconv_t cd1, iconv_t cd2,
|
||||
enum iconv_ilseq_handler handler,
|
||||
size_t *offsets,
|
||||
char **resultp, size_t *lengthp);
|
||||
|
||||
/* Convert an entire string from one encoding to another, using iconv.
|
||||
The original string is the NUL-terminated string starting at SRC.
|
||||
CD is the conversion descriptor from FROMCODE to TOCODE, or (iconv_t)(-1) if
|
||||
the system does not support a direct conversion from FROMCODE to TOCODE.
|
||||
Both the "from" and the "to" encoding must use a single NUL byte at the end
|
||||
of the string (i.e. not UCS-2, UCS-4, UTF-16, UTF-32).
|
||||
CD1 is the conversion descriptor from FROM_CODESET to UTF-8 (or
|
||||
(iconv_t)(-1) if FROM_CODESET is UTF-8).
|
||||
CD2 is the conversion descriptor from UTF-8 to TO_CODESET (or (iconv_t)(-1)
|
||||
if TO_CODESET is UTF-8).
|
||||
Allocate a malloced memory block for the result.
|
||||
Return value: the freshly allocated resulting NUL-terminated string if
|
||||
successful, otherwise NULL and errno set. */
|
||||
extern char *
|
||||
str_cd_iconveh (const char *src,
|
||||
iconv_t cd, iconv_t cd1, iconv_t cd2,
|
||||
enum iconv_ilseq_handler handler);
|
||||
|
||||
#endif
|
||||
|
||||
/* Convert an entire string from one encoding to another, using iconv.
|
||||
The original string is at [SRC,...,SRC+SRCLEN-1].
|
||||
If OFFSETS is not NULL, it should point to an array of SRCLEN integers; this
|
||||
array is filled with offsets into the result, i.e. the character starting
|
||||
at SRC[i] corresponds to the character starting at (*RESULTP)[OFFSETS[i]],
|
||||
and other offsets are set to (size_t)(-1).
|
||||
*RESULTP and *LENGTH should initially be a scratch buffer and its size,
|
||||
or *RESULTP can initially be NULL.
|
||||
May erase the contents of the memory at *RESULTP.
|
||||
Return value: 0 if successful, otherwise -1 and errno set.
|
||||
If successful: The resulting string is stored in *RESULTP and its length
|
||||
in *LENGTHP. *RESULTP is set to a freshly allocated memory block, or is
|
||||
unchanged if no dynamic memory allocation was necessary. */
|
||||
extern int
|
||||
mem_iconveh (const char *src, size_t srclen,
|
||||
const char *from_codeset, const char *to_codeset,
|
||||
enum iconv_ilseq_handler handler,
|
||||
size_t *offsets,
|
||||
char **resultp, size_t *lengthp);
|
||||
|
||||
/* Convert an entire string from one encoding to another, using iconv.
|
||||
The original string is the NUL-terminated string starting at SRC.
|
||||
Both the "from" and the "to" encoding must use a single NUL byte at the
|
||||
end of the string (i.e. not UCS-2, UCS-4, UTF-16, UTF-32).
|
||||
Allocate a malloced memory block for the result.
|
||||
Return value: the freshly allocated resulting NUL-terminated string if
|
||||
successful, otherwise NULL and errno set. */
|
||||
extern char *
|
||||
str_iconveh (const char *src,
|
||||
const char *from_codeset, const char *to_codeset,
|
||||
enum iconv_ilseq_handler handler);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* _STRICONVEH_H */
|
605
lib/string.in.h
Normal file
605
lib/string.in.h
Normal file
|
@ -0,0 +1,605 @@
|
|||
/* A GNU-like <string.h>.
|
||||
|
||||
Copyright (C) 1995-1996, 2001-2008 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program; if not, write to the Free Software Foundation,
|
||||
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
|
||||
|
||||
#ifndef _GL_STRING_H
|
||||
|
||||
#if __GNUC__ >= 3
|
||||
@PRAGMA_SYSTEM_HEADER@
|
||||
#endif
|
||||
|
||||
/* The include_next requires a split double-inclusion guard. */
|
||||
#@INCLUDE_NEXT@ @NEXT_STRING_H@
|
||||
|
||||
#ifndef _GL_STRING_H
|
||||
#define _GL_STRING_H
|
||||
|
||||
|
||||
#ifndef __attribute__
|
||||
/* This feature is available in gcc versions 2.5 and later. */
|
||||
# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 5)
|
||||
# define __attribute__(Spec) /* empty */
|
||||
# endif
|
||||
/* The attribute __pure__ was added in gcc 2.96. */
|
||||
# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 96)
|
||||
# define __pure__ /* empty */
|
||||
# endif
|
||||
#endif
|
||||
|
||||
|
||||
/* The definition of GL_LINK_WARNING is copied here. */
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/* Return the first occurrence of NEEDLE in HAYSTACK. */
|
||||
#if @GNULIB_MEMMEM@
|
||||
# if @REPLACE_MEMMEM@
|
||||
# define memmem rpl_memmem
|
||||
# endif
|
||||
# if ! @HAVE_DECL_MEMMEM@ || @REPLACE_MEMMEM@
|
||||
extern void *memmem (void const *__haystack, size_t __haystack_len,
|
||||
void const *__needle, size_t __needle_len)
|
||||
__attribute__ ((__pure__));
|
||||
# endif
|
||||
#elif defined GNULIB_POSIXCHECK
|
||||
# undef memmem
|
||||
# define memmem(a,al,b,bl) \
|
||||
(GL_LINK_WARNING ("memmem is unportable and often quadratic - " \
|
||||
"use gnulib module memmem-simple for portability, " \
|
||||
"and module memmem for speed" ), \
|
||||
memmem (a, al, b, bl))
|
||||
#endif
|
||||
|
||||
/* Copy N bytes of SRC to DEST, return pointer to bytes after the
|
||||
last written byte. */
|
||||
#if @GNULIB_MEMPCPY@
|
||||
# if ! @HAVE_MEMPCPY@
|
||||
extern void *mempcpy (void *restrict __dest, void const *restrict __src,
|
||||
size_t __n);
|
||||
# endif
|
||||
#elif defined GNULIB_POSIXCHECK
|
||||
# undef mempcpy
|
||||
# define mempcpy(a,b,n) \
|
||||
(GL_LINK_WARNING ("mempcpy is unportable - " \
|
||||
"use gnulib module mempcpy for portability"), \
|
||||
mempcpy (a, b, n))
|
||||
#endif
|
||||
|
||||
/* Search backwards through a block for a byte (specified as an int). */
|
||||
#if @GNULIB_MEMRCHR@
|
||||
# if ! @HAVE_DECL_MEMRCHR@
|
||||
extern void *memrchr (void const *, int, size_t)
|
||||
__attribute__ ((__pure__));
|
||||
# endif
|
||||
#elif defined GNULIB_POSIXCHECK
|
||||
# undef memrchr
|
||||
# define memrchr(a,b,c) \
|
||||
(GL_LINK_WARNING ("memrchr is unportable - " \
|
||||
"use gnulib module memrchr for portability"), \
|
||||
memrchr (a, b, c))
|
||||
#endif
|
||||
|
||||
/* Find the first occurrence of C in S. More efficient than
|
||||
memchr(S,C,N), at the expense of undefined behavior if C does not
|
||||
occur within N bytes. */
|
||||
#if @GNULIB_RAWMEMCHR@
|
||||
# if ! @HAVE_RAWMEMCHR@
|
||||
extern void *rawmemchr (void const *__s, int __c_in)
|
||||
__attribute__ ((__pure__));
|
||||
# endif
|
||||
#elif defined GNULIB_POSIXCHECK
|
||||
# undef rawmemchr
|
||||
# define rawmemchr(a,b) \
|
||||
(GL_LINK_WARNING ("rawmemchr is unportable - " \
|
||||
"use gnulib module rawmemchr for portability"), \
|
||||
rawmemchr (a, b))
|
||||
#endif
|
||||
|
||||
/* Copy SRC to DST, returning the address of the terminating '\0' in DST. */
|
||||
#if @GNULIB_STPCPY@
|
||||
# if ! @HAVE_STPCPY@
|
||||
extern char *stpcpy (char *restrict __dst, char const *restrict __src);
|
||||
# endif
|
||||
#elif defined GNULIB_POSIXCHECK
|
||||
# undef stpcpy
|
||||
# define stpcpy(a,b) \
|
||||
(GL_LINK_WARNING ("stpcpy is unportable - " \
|
||||
"use gnulib module stpcpy for portability"), \
|
||||
stpcpy (a, b))
|
||||
#endif
|
||||
|
||||
/* Copy no more than N bytes of SRC to DST, returning a pointer past the
|
||||
last non-NUL byte written into DST. */
|
||||
#if @GNULIB_STPNCPY@
|
||||
# if ! @HAVE_STPNCPY@
|
||||
# define stpncpy gnu_stpncpy
|
||||
extern char *stpncpy (char *restrict __dst, char const *restrict __src,
|
||||
size_t __n);
|
||||
# endif
|
||||
#elif defined GNULIB_POSIXCHECK
|
||||
# undef stpncpy
|
||||
# define stpncpy(a,b,n) \
|
||||
(GL_LINK_WARNING ("stpncpy is unportable - " \
|
||||
"use gnulib module stpncpy for portability"), \
|
||||
stpncpy (a, b, n))
|
||||
#endif
|
||||
|
||||
#if defined GNULIB_POSIXCHECK
|
||||
/* strchr() does not work with multibyte strings if the locale encoding is
|
||||
GB18030 and the character to be searched is a digit. */
|
||||
# undef strchr
|
||||
# define strchr(s,c) \
|
||||
(GL_LINK_WARNING ("strchr cannot work correctly on character strings " \
|
||||
"in some multibyte locales - " \
|
||||
"use mbschr if you care about internationalization"), \
|
||||
strchr (s, c))
|
||||
#endif
|
||||
|
||||
/* Find the first occurrence of C in S or the final NUL byte. */
|
||||
#if @GNULIB_STRCHRNUL@
|
||||
# if ! @HAVE_STRCHRNUL@
|
||||
extern char *strchrnul (char const *__s, int __c_in)
|
||||
__attribute__ ((__pure__));
|
||||
# endif
|
||||
#elif defined GNULIB_POSIXCHECK
|
||||
# undef strchrnul
|
||||
# define strchrnul(a,b) \
|
||||
(GL_LINK_WARNING ("strchrnul is unportable - " \
|
||||
"use gnulib module strchrnul for portability"), \
|
||||
strchrnul (a, b))
|
||||
#endif
|
||||
|
||||
/* Duplicate S, returning an identical malloc'd string. */
|
||||
#if @GNULIB_STRDUP@
|
||||
# if @REPLACE_STRDUP@
|
||||
# undef strdup
|
||||
# define strdup rpl_strdup
|
||||
# endif
|
||||
# if !(@HAVE_DECL_STRDUP@ || defined strdup) || @REPLACE_STRDUP@
|
||||
extern char *strdup (char const *__s);
|
||||
# endif
|
||||
#elif defined GNULIB_POSIXCHECK
|
||||
# undef strdup
|
||||
# define strdup(a) \
|
||||
(GL_LINK_WARNING ("strdup is unportable - " \
|
||||
"use gnulib module strdup for portability"), \
|
||||
strdup (a))
|
||||
#endif
|
||||
|
||||
/* Return a newly allocated copy of at most N bytes of STRING. */
|
||||
#if @GNULIB_STRNDUP@
|
||||
# if ! @HAVE_STRNDUP@
|
||||
# undef strndup
|
||||
# define strndup rpl_strndup
|
||||
# endif
|
||||
# if ! @HAVE_STRNDUP@ || ! @HAVE_DECL_STRNDUP@
|
||||
extern char *strndup (char const *__string, size_t __n);
|
||||
# endif
|
||||
#elif defined GNULIB_POSIXCHECK
|
||||
# undef strndup
|
||||
# define strndup(a,n) \
|
||||
(GL_LINK_WARNING ("strndup is unportable - " \
|
||||
"use gnulib module strndup for portability"), \
|
||||
strndup (a, n))
|
||||
#endif
|
||||
|
||||
/* Find the length (number of bytes) of STRING, but scan at most
|
||||
MAXLEN bytes. If no '\0' terminator is found in that many bytes,
|
||||
return MAXLEN. */
|
||||
#if @GNULIB_STRNLEN@
|
||||
# if ! @HAVE_DECL_STRNLEN@
|
||||
extern size_t strnlen (char const *__string, size_t __maxlen)
|
||||
__attribute__ ((__pure__));
|
||||
# endif
|
||||
#elif defined GNULIB_POSIXCHECK
|
||||
# undef strnlen
|
||||
# define strnlen(a,n) \
|
||||
(GL_LINK_WARNING ("strnlen is unportable - " \
|
||||
"use gnulib module strnlen for portability"), \
|
||||
strnlen (a, n))
|
||||
#endif
|
||||
|
||||
#if defined GNULIB_POSIXCHECK
|
||||
/* strcspn() assumes the second argument is a list of single-byte characters.
|
||||
Even in this simple case, it does not work with multibyte strings if the
|
||||
locale encoding is GB18030 and one of the characters to be searched is a
|
||||
digit. */
|
||||
# undef strcspn
|
||||
# define strcspn(s,a) \
|
||||
(GL_LINK_WARNING ("strcspn cannot work correctly on character strings " \
|
||||
"in multibyte locales - " \
|
||||
"use mbscspn if you care about internationalization"), \
|
||||
strcspn (s, a))
|
||||
#endif
|
||||
|
||||
/* Find the first occurrence in S of any character in ACCEPT. */
|
||||
#if @GNULIB_STRPBRK@
|
||||
# if ! @HAVE_STRPBRK@
|
||||
extern char *strpbrk (char const *__s, char const *__accept)
|
||||
__attribute__ ((__pure__));
|
||||
# endif
|
||||
# if defined GNULIB_POSIXCHECK
|
||||
/* strpbrk() assumes the second argument is a list of single-byte characters.
|
||||
Even in this simple case, it does not work with multibyte strings if the
|
||||
locale encoding is GB18030 and one of the characters to be searched is a
|
||||
digit. */
|
||||
# undef strpbrk
|
||||
# define strpbrk(s,a) \
|
||||
(GL_LINK_WARNING ("strpbrk cannot work correctly on character strings " \
|
||||
"in multibyte locales - " \
|
||||
"use mbspbrk if you care about internationalization"), \
|
||||
strpbrk (s, a))
|
||||
# endif
|
||||
#elif defined GNULIB_POSIXCHECK
|
||||
# undef strpbrk
|
||||
# define strpbrk(s,a) \
|
||||
(GL_LINK_WARNING ("strpbrk is unportable - " \
|
||||
"use gnulib module strpbrk for portability"), \
|
||||
strpbrk (s, a))
|
||||
#endif
|
||||
|
||||
#if defined GNULIB_POSIXCHECK
|
||||
/* strspn() assumes the second argument is a list of single-byte characters.
|
||||
Even in this simple case, it cannot work with multibyte strings. */
|
||||
# undef strspn
|
||||
# define strspn(s,a) \
|
||||
(GL_LINK_WARNING ("strspn cannot work correctly on character strings " \
|
||||
"in multibyte locales - " \
|
||||
"use mbsspn if you care about internationalization"), \
|
||||
strspn (s, a))
|
||||
#endif
|
||||
|
||||
#if defined GNULIB_POSIXCHECK
|
||||
/* strrchr() does not work with multibyte strings if the locale encoding is
|
||||
GB18030 and the character to be searched is a digit. */
|
||||
# undef strrchr
|
||||
# define strrchr(s,c) \
|
||||
(GL_LINK_WARNING ("strrchr cannot work correctly on character strings " \
|
||||
"in some multibyte locales - " \
|
||||
"use mbsrchr if you care about internationalization"), \
|
||||
strrchr (s, c))
|
||||
#endif
|
||||
|
||||
/* Search the next delimiter (char listed in DELIM) starting at *STRINGP.
|
||||
If one is found, overwrite it with a NUL, and advance *STRINGP
|
||||
to point to the next char after it. Otherwise, set *STRINGP to NULL.
|
||||
If *STRINGP was already NULL, nothing happens.
|
||||
Return the old value of *STRINGP.
|
||||
|
||||
This is a variant of strtok() that is multithread-safe and supports
|
||||
empty fields.
|
||||
|
||||
Caveat: It modifies the original string.
|
||||
Caveat: These functions cannot be used on constant strings.
|
||||
Caveat: The identity of the delimiting character is lost.
|
||||
Caveat: It doesn't work with multibyte strings unless all of the delimiter
|
||||
characters are ASCII characters < 0x30.
|
||||
|
||||
See also strtok_r(). */
|
||||
#if @GNULIB_STRSEP@
|
||||
# if ! @HAVE_STRSEP@
|
||||
extern char *strsep (char **restrict __stringp, char const *restrict __delim);
|
||||
# endif
|
||||
# if defined GNULIB_POSIXCHECK
|
||||
# undef strsep
|
||||
# define strsep(s,d) \
|
||||
(GL_LINK_WARNING ("strsep cannot work correctly on character strings " \
|
||||
"in multibyte locales - " \
|
||||
"use mbssep if you care about internationalization"), \
|
||||
strsep (s, d))
|
||||
# endif
|
||||
#elif defined GNULIB_POSIXCHECK
|
||||
# undef strsep
|
||||
# define strsep(s,d) \
|
||||
(GL_LINK_WARNING ("strsep is unportable - " \
|
||||
"use gnulib module strsep for portability"), \
|
||||
strsep (s, d))
|
||||
#endif
|
||||
|
||||
#if @GNULIB_STRSTR@
|
||||
# if @REPLACE_STRSTR@
|
||||
# define strstr rpl_strstr
|
||||
char *strstr (const char *haystack, const char *needle)
|
||||
__attribute__ ((__pure__));
|
||||
# endif
|
||||
#elif defined GNULIB_POSIXCHECK
|
||||
/* strstr() does not work with multibyte strings if the locale encoding is
|
||||
different from UTF-8:
|
||||
POSIX says that it operates on "strings", and "string" in POSIX is defined
|
||||
as a sequence of bytes, not of characters. */
|
||||
# undef strstr
|
||||
# define strstr(a,b) \
|
||||
(GL_LINK_WARNING ("strstr is quadratic on many systems, and cannot " \
|
||||
"work correctly on character strings in most " \
|
||||
"multibyte locales - " \
|
||||
"use mbsstr if you care about internationalization, " \
|
||||
"or use strstr if you care about speed"), \
|
||||
strstr (a, b))
|
||||
#endif
|
||||
|
||||
/* Find the first occurrence of NEEDLE in HAYSTACK, using case-insensitive
|
||||
comparison. */
|
||||
#if @GNULIB_STRCASESTR@
|
||||
# if @REPLACE_STRCASESTR@
|
||||
# define strcasestr rpl_strcasestr
|
||||
# endif
|
||||
# if ! @HAVE_STRCASESTR@ || @REPLACE_STRCASESTR@
|
||||
extern char *strcasestr (const char *haystack, const char *needle)
|
||||
__attribute__ ((__pure__));
|
||||
# endif
|
||||
#elif defined GNULIB_POSIXCHECK
|
||||
/* strcasestr() does not work with multibyte strings:
|
||||
It is a glibc extension, and glibc implements it only for unibyte
|
||||
locales. */
|
||||
# undef strcasestr
|
||||
# define strcasestr(a,b) \
|
||||
(GL_LINK_WARNING ("strcasestr does work correctly on character strings " \
|
||||
"in multibyte locales - " \
|
||||
"use mbscasestr if you care about " \
|
||||
"internationalization, or use c-strcasestr if you want " \
|
||||
"a locale independent function"), \
|
||||
strcasestr (a, b))
|
||||
#endif
|
||||
|
||||
/* Parse S into tokens separated by characters in DELIM.
|
||||
If S is NULL, the saved pointer in SAVE_PTR is used as
|
||||
the next starting point. For example:
|
||||
char s[] = "-abc-=-def";
|
||||
char *sp;
|
||||
x = strtok_r(s, "-", &sp); // x = "abc", sp = "=-def"
|
||||
x = strtok_r(NULL, "-=", &sp); // x = "def", sp = NULL
|
||||
x = strtok_r(NULL, "=", &sp); // x = NULL
|
||||
// s = "abc\0-def\0"
|
||||
|
||||
This is a variant of strtok() that is multithread-safe.
|
||||
|
||||
For the POSIX documentation for this function, see:
|
||||
http://www.opengroup.org/susv3xsh/strtok.html
|
||||
|
||||
Caveat: It modifies the original string.
|
||||
Caveat: These functions cannot be used on constant strings.
|
||||
Caveat: The identity of the delimiting character is lost.
|
||||
Caveat: It doesn't work with multibyte strings unless all of the delimiter
|
||||
characters are ASCII characters < 0x30.
|
||||
|
||||
See also strsep(). */
|
||||
#if @GNULIB_STRTOK_R@
|
||||
# if ! @HAVE_DECL_STRTOK_R@
|
||||
extern char *strtok_r (char *restrict s, char const *restrict delim,
|
||||
char **restrict save_ptr);
|
||||
# endif
|
||||
# if defined GNULIB_POSIXCHECK
|
||||
# undef strtok_r
|
||||
# define strtok_r(s,d,p) \
|
||||
(GL_LINK_WARNING ("strtok_r cannot work correctly on character strings " \
|
||||
"in multibyte locales - " \
|
||||
"use mbstok_r if you care about internationalization"), \
|
||||
strtok_r (s, d, p))
|
||||
# endif
|
||||
#elif defined GNULIB_POSIXCHECK
|
||||
# undef strtok_r
|
||||
# define strtok_r(s,d,p) \
|
||||
(GL_LINK_WARNING ("strtok_r is unportable - " \
|
||||
"use gnulib module strtok_r for portability"), \
|
||||
strtok_r (s, d, p))
|
||||
#endif
|
||||
|
||||
|
||||
/* The following functions are not specified by POSIX. They are gnulib
|
||||
extensions. */
|
||||
|
||||
#if @GNULIB_MBSLEN@
|
||||
/* Return the number of multibyte characters in the character string STRING.
|
||||
This considers multibyte characters, unlike strlen, which counts bytes. */
|
||||
extern size_t mbslen (const char *string);
|
||||
#endif
|
||||
|
||||
#if @GNULIB_MBSNLEN@
|
||||
/* Return the number of multibyte characters in the character string starting
|
||||
at STRING and ending at STRING + LEN. */
|
||||
extern size_t mbsnlen (const char *string, size_t len);
|
||||
#endif
|
||||
|
||||
#if @GNULIB_MBSCHR@
|
||||
/* Locate the first single-byte character C in the character string STRING,
|
||||
and return a pointer to it. Return NULL if C is not found in STRING.
|
||||
Unlike strchr(), this function works correctly in multibyte locales with
|
||||
encodings such as GB18030. */
|
||||
# define mbschr rpl_mbschr /* avoid collision with HP-UX function */
|
||||
extern char * mbschr (const char *string, int c);
|
||||
#endif
|
||||
|
||||
#if @GNULIB_MBSRCHR@
|
||||
/* Locate the last single-byte character C in the character string STRING,
|
||||
and return a pointer to it. Return NULL if C is not found in STRING.
|
||||
Unlike strrchr(), this function works correctly in multibyte locales with
|
||||
encodings such as GB18030. */
|
||||
# define mbsrchr rpl_mbsrchr /* avoid collision with HP-UX function */
|
||||
extern char * mbsrchr (const char *string, int c);
|
||||
#endif
|
||||
|
||||
#if @GNULIB_MBSSTR@
|
||||
/* Find the first occurrence of the character string NEEDLE in the character
|
||||
string HAYSTACK. Return NULL if NEEDLE is not found in HAYSTACK.
|
||||
Unlike strstr(), this function works correctly in multibyte locales with
|
||||
encodings different from UTF-8. */
|
||||
extern char * mbsstr (const char *haystack, const char *needle);
|
||||
#endif
|
||||
|
||||
#if @GNULIB_MBSCASECMP@
|
||||
/* Compare the character strings S1 and S2, ignoring case, returning less than,
|
||||
equal to or greater than zero if S1 is lexicographically less than, equal to
|
||||
or greater than S2.
|
||||
Note: This function may, in multibyte locales, return 0 for strings of
|
||||
different lengths!
|
||||
Unlike strcasecmp(), this function works correctly in multibyte locales. */
|
||||
extern int mbscasecmp (const char *s1, const char *s2);
|
||||
#endif
|
||||
|
||||
#if @GNULIB_MBSNCASECMP@
|
||||
/* Compare the initial segment of the character string S1 consisting of at most
|
||||
N characters with the initial segment of the character string S2 consisting
|
||||
of at most N characters, ignoring case, returning less than, equal to or
|
||||
greater than zero if the initial segment of S1 is lexicographically less
|
||||
than, equal to or greater than the initial segment of S2.
|
||||
Note: This function may, in multibyte locales, return 0 for initial segments
|
||||
of different lengths!
|
||||
Unlike strncasecmp(), this function works correctly in multibyte locales.
|
||||
But beware that N is not a byte count but a character count! */
|
||||
extern int mbsncasecmp (const char *s1, const char *s2, size_t n);
|
||||
#endif
|
||||
|
||||
#if @GNULIB_MBSPCASECMP@
|
||||
/* Compare the initial segment of the character string STRING consisting of
|
||||
at most mbslen (PREFIX) characters with the character string PREFIX,
|
||||
ignoring case, returning less than, equal to or greater than zero if this
|
||||
initial segment is lexicographically less than, equal to or greater than
|
||||
PREFIX.
|
||||
Note: This function may, in multibyte locales, return 0 if STRING is of
|
||||
smaller length than PREFIX!
|
||||
Unlike strncasecmp(), this function works correctly in multibyte
|
||||
locales. */
|
||||
extern char * mbspcasecmp (const char *string, const char *prefix);
|
||||
#endif
|
||||
|
||||
#if @GNULIB_MBSCASESTR@
|
||||
/* Find the first occurrence of the character string NEEDLE in the character
|
||||
string HAYSTACK, using case-insensitive comparison.
|
||||
Note: This function may, in multibyte locales, return success even if
|
||||
strlen (haystack) < strlen (needle) !
|
||||
Unlike strcasestr(), this function works correctly in multibyte locales. */
|
||||
extern char * mbscasestr (const char *haystack, const char *needle);
|
||||
#endif
|
||||
|
||||
#if @GNULIB_MBSCSPN@
|
||||
/* Find the first occurrence in the character string STRING of any character
|
||||
in the character string ACCEPT. Return the number of bytes from the
|
||||
beginning of the string to this occurrence, or to the end of the string
|
||||
if none exists.
|
||||
Unlike strcspn(), this function works correctly in multibyte locales. */
|
||||
extern size_t mbscspn (const char *string, const char *accept);
|
||||
#endif
|
||||
|
||||
#if @GNULIB_MBSPBRK@
|
||||
/* Find the first occurrence in the character string STRING of any character
|
||||
in the character string ACCEPT. Return the pointer to it, or NULL if none
|
||||
exists.
|
||||
Unlike strpbrk(), this function works correctly in multibyte locales. */
|
||||
# define mbspbrk rpl_mbspbrk /* avoid collision with HP-UX function */
|
||||
extern char * mbspbrk (const char *string, const char *accept);
|
||||
#endif
|
||||
|
||||
#if @GNULIB_MBSSPN@
|
||||
/* Find the first occurrence in the character string STRING of any character
|
||||
not in the character string REJECT. Return the number of bytes from the
|
||||
beginning of the string to this occurrence, or to the end of the string
|
||||
if none exists.
|
||||
Unlike strspn(), this function works correctly in multibyte locales. */
|
||||
extern size_t mbsspn (const char *string, const char *reject);
|
||||
#endif
|
||||
|
||||
#if @GNULIB_MBSSEP@
|
||||
/* Search the next delimiter (multibyte character listed in the character
|
||||
string DELIM) starting at the character string *STRINGP.
|
||||
If one is found, overwrite it with a NUL, and advance *STRINGP to point
|
||||
to the next multibyte character after it. Otherwise, set *STRINGP to NULL.
|
||||
If *STRINGP was already NULL, nothing happens.
|
||||
Return the old value of *STRINGP.
|
||||
|
||||
This is a variant of mbstok_r() that supports empty fields.
|
||||
|
||||
Caveat: It modifies the original string.
|
||||
Caveat: These functions cannot be used on constant strings.
|
||||
Caveat: The identity of the delimiting character is lost.
|
||||
|
||||
See also mbstok_r(). */
|
||||
extern char * mbssep (char **stringp, const char *delim);
|
||||
#endif
|
||||
|
||||
#if @GNULIB_MBSTOK_R@
|
||||
/* Parse the character string STRING into tokens separated by characters in
|
||||
the character string DELIM.
|
||||
If STRING is NULL, the saved pointer in SAVE_PTR is used as
|
||||
the next starting point. For example:
|
||||
char s[] = "-abc-=-def";
|
||||
char *sp;
|
||||
x = mbstok_r(s, "-", &sp); // x = "abc", sp = "=-def"
|
||||
x = mbstok_r(NULL, "-=", &sp); // x = "def", sp = NULL
|
||||
x = mbstok_r(NULL, "=", &sp); // x = NULL
|
||||
// s = "abc\0-def\0"
|
||||
|
||||
Caveat: It modifies the original string.
|
||||
Caveat: These functions cannot be used on constant strings.
|
||||
Caveat: The identity of the delimiting character is lost.
|
||||
|
||||
See also mbssep(). */
|
||||
extern char * mbstok_r (char *string, const char *delim, char **save_ptr);
|
||||
#endif
|
||||
|
||||
/* Map any int, typically from errno, into an error message. */
|
||||
#if @GNULIB_STRERROR@
|
||||
# if @REPLACE_STRERROR@
|
||||
# undef strerror
|
||||
# define strerror rpl_strerror
|
||||
extern char *strerror (int);
|
||||
# endif
|
||||
#elif defined GNULIB_POSIXCHECK
|
||||
# undef strerror
|
||||
# define strerror(e) \
|
||||
(GL_LINK_WARNING ("strerror is unportable - " \
|
||||
"use gnulib module strerror to guarantee non-NULL result"), \
|
||||
strerror (e))
|
||||
#endif
|
||||
|
||||
#if @GNULIB_STRSIGNAL@
|
||||
# if @REPLACE_STRSIGNAL@
|
||||
# define strsignal rpl_strsignal
|
||||
# endif
|
||||
# if ! @HAVE_DECL_STRSIGNAL@ || @REPLACE_STRSIGNAL@
|
||||
extern char *strsignal (int __sig);
|
||||
# endif
|
||||
#elif defined GNULIB_POSIXCHECK
|
||||
# undef strsignal
|
||||
# define strsignal(a) \
|
||||
(GL_LINK_WARNING ("strsignal is unportable - " \
|
||||
"use gnulib module strsignal for portability"), \
|
||||
strsignal (a))
|
||||
#endif
|
||||
|
||||
#if @GNULIB_STRVERSCMP@
|
||||
# if !@HAVE_STRVERSCMP@
|
||||
extern int strverscmp (const char *, const char *);
|
||||
# endif
|
||||
#elif defined GNULIB_POSIXCHECK
|
||||
# undef strverscmp
|
||||
# define strverscmp(a, b) \
|
||||
(GL_LINK_WARNING ("strverscmp is unportable - " \
|
||||
"use gnulib module strverscmp for portability"), \
|
||||
strverscmp (a, b))
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _GL_STRING_H */
|
||||
#endif /* _GL_STRING_H */
|
681
lib/unistr.h
Normal file
681
lib/unistr.h
Normal file
|
@ -0,0 +1,681 @@
|
|||
/* Elementary Unicode string functions.
|
||||
Copyright (C) 2001-2002, 2005-2009 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU Lesser General Public License as published
|
||||
by the Free Software Foundation; either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef _UNISTR_H
|
||||
#define _UNISTR_H
|
||||
|
||||
#include "unitypes.h"
|
||||
|
||||
/* Get bool. */
|
||||
#include <stdbool.h>
|
||||
|
||||
/* Get size_t. */
|
||||
#include <stddef.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/* Conventions:
|
||||
|
||||
All functions prefixed with u8_ operate on UTF-8 encoded strings.
|
||||
Their unit is an uint8_t (1 byte).
|
||||
|
||||
All functions prefixed with u16_ operate on UTF-16 encoded strings.
|
||||
Their unit is an uint16_t (a 2-byte word).
|
||||
|
||||
All functions prefixed with u32_ operate on UCS-4 encoded strings.
|
||||
Their unit is an uint32_t (a 4-byte word).
|
||||
|
||||
All argument pairs (s, n) denote a Unicode string s[0..n-1] with exactly
|
||||
n units.
|
||||
|
||||
All arguments starting with "str" and the arguments of functions starting
|
||||
with u8_str/u16_str/u32_str denote a NUL terminated string, i.e. a string
|
||||
which terminates at the first NUL unit. This termination unit is
|
||||
considered part of the string for all memory allocation purposes, but
|
||||
is not considered part of the string for all other logical purposes.
|
||||
|
||||
Functions returning a string result take a (resultbuf, lengthp) argument
|
||||
pair. If resultbuf is not NULL and the result fits into *lengthp units,
|
||||
it is put in resultbuf, and resultbuf is returned. Otherwise, a freshly
|
||||
allocated string is returned. In both cases, *lengthp is set to the
|
||||
length (number of units) of the returned string. In case of error,
|
||||
NULL is returned and errno is set. */
|
||||
|
||||
|
||||
/* Elementary string checks. */
|
||||
|
||||
/* Check whether an UTF-8 string is well-formed.
|
||||
Return NULL if valid, or a pointer to the first invalid unit otherwise. */
|
||||
extern const uint8_t *
|
||||
u8_check (const uint8_t *s, size_t n);
|
||||
|
||||
/* Check whether an UTF-16 string is well-formed.
|
||||
Return NULL if valid, or a pointer to the first invalid unit otherwise. */
|
||||
extern const uint16_t *
|
||||
u16_check (const uint16_t *s, size_t n);
|
||||
|
||||
/* Check whether an UCS-4 string is well-formed.
|
||||
Return NULL if valid, or a pointer to the first invalid unit otherwise. */
|
||||
extern const uint32_t *
|
||||
u32_check (const uint32_t *s, size_t n);
|
||||
|
||||
|
||||
/* Elementary string conversions. */
|
||||
|
||||
/* Convert an UTF-8 string to an UTF-16 string. */
|
||||
extern uint16_t *
|
||||
u8_to_u16 (const uint8_t *s, size_t n, uint16_t *resultbuf,
|
||||
size_t *lengthp);
|
||||
|
||||
/* Convert an UTF-8 string to an UCS-4 string. */
|
||||
extern uint32_t *
|
||||
u8_to_u32 (const uint8_t *s, size_t n, uint32_t *resultbuf,
|
||||
size_t *lengthp);
|
||||
|
||||
/* Convert an UTF-16 string to an UTF-8 string. */
|
||||
extern uint8_t *
|
||||
u16_to_u8 (const uint16_t *s, size_t n, uint8_t *resultbuf,
|
||||
size_t *lengthp);
|
||||
|
||||
/* Convert an UTF-16 string to an UCS-4 string. */
|
||||
extern uint32_t *
|
||||
u16_to_u32 (const uint16_t *s, size_t n, uint32_t *resultbuf,
|
||||
size_t *lengthp);
|
||||
|
||||
/* Convert an UCS-4 string to an UTF-8 string. */
|
||||
extern uint8_t *
|
||||
u32_to_u8 (const uint32_t *s, size_t n, uint8_t *resultbuf,
|
||||
size_t *lengthp);
|
||||
|
||||
/* Convert an UCS-4 string to an UTF-16 string. */
|
||||
extern uint16_t *
|
||||
u32_to_u16 (const uint32_t *s, size_t n, uint16_t *resultbuf,
|
||||
size_t *lengthp);
|
||||
|
||||
|
||||
/* Elementary string functions. */
|
||||
|
||||
/* Return the length (number of units) of the first character in S, which is
|
||||
no longer than N. Return 0 if it is the NUL character. Return -1 upon
|
||||
failure. */
|
||||
/* Similar to mblen(), except that s must not be NULL. */
|
||||
extern int
|
||||
u8_mblen (const uint8_t *s, size_t n);
|
||||
extern int
|
||||
u16_mblen (const uint16_t *s, size_t n);
|
||||
extern int
|
||||
u32_mblen (const uint32_t *s, size_t n);
|
||||
|
||||
/* Return the length (number of units) of the first character in S, putting
|
||||
its 'ucs4_t' representation in *PUC. Upon failure, *PUC is set to 0xfffd,
|
||||
and an appropriate number of units is returned.
|
||||
The number of available units, N, must be > 0. */
|
||||
/* Similar to mbtowc(), except that puc and s must not be NULL, n must be > 0,
|
||||
and the NUL character is not treated specially. */
|
||||
/* The variants with _safe suffix are safe, even if the library is compiled
|
||||
without --enable-safety. */
|
||||
|
||||
#ifdef GNULIB_UNISTR_U8_MBTOUC_UNSAFE
|
||||
# if !HAVE_INLINE
|
||||
extern int
|
||||
u8_mbtouc_unsafe (ucs4_t *puc, const uint8_t *s, size_t n);
|
||||
# else
|
||||
extern int
|
||||
u8_mbtouc_unsafe_aux (ucs4_t *puc, const uint8_t *s, size_t n);
|
||||
static inline int
|
||||
u8_mbtouc_unsafe (ucs4_t *puc, const uint8_t *s, size_t n)
|
||||
{
|
||||
uint8_t c = *s;
|
||||
|
||||
if (c < 0x80)
|
||||
{
|
||||
*puc = c;
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
return u8_mbtouc_unsafe_aux (puc, s, n);
|
||||
}
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef GNULIB_UNISTR_U16_MBTOUC_UNSAFE
|
||||
# if !HAVE_INLINE
|
||||
extern int
|
||||
u16_mbtouc_unsafe (ucs4_t *puc, const uint16_t *s, size_t n);
|
||||
# else
|
||||
extern int
|
||||
u16_mbtouc_unsafe_aux (ucs4_t *puc, const uint16_t *s, size_t n);
|
||||
static inline int
|
||||
u16_mbtouc_unsafe (ucs4_t *puc, const uint16_t *s, size_t n)
|
||||
{
|
||||
uint16_t c = *s;
|
||||
|
||||
if (c < 0xd800 || c >= 0xe000)
|
||||
{
|
||||
*puc = c;
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
return u16_mbtouc_unsafe_aux (puc, s, n);
|
||||
}
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef GNULIB_UNISTR_U32_MBTOUC_UNSAFE
|
||||
# if !HAVE_INLINE
|
||||
extern int
|
||||
u32_mbtouc_unsafe (ucs4_t *puc, const uint32_t *s, size_t n);
|
||||
# else
|
||||
static inline int
|
||||
u32_mbtouc_unsafe (ucs4_t *puc, const uint32_t *s, size_t n _UNUSED_PARAMETER_)
|
||||
{
|
||||
uint32_t c = *s;
|
||||
|
||||
# if CONFIG_UNICODE_SAFETY
|
||||
if (c < 0xd800 || (c >= 0xe000 && c < 0x110000))
|
||||
# endif
|
||||
*puc = c;
|
||||
# if CONFIG_UNICODE_SAFETY
|
||||
else
|
||||
/* invalid multibyte character */
|
||||
*puc = 0xfffd;
|
||||
# endif
|
||||
return 1;
|
||||
}
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef GNULIB_UNISTR_U8_MBTOUC
|
||||
# if !HAVE_INLINE
|
||||
extern int
|
||||
u8_mbtouc (ucs4_t *puc, const uint8_t *s, size_t n);
|
||||
# else
|
||||
extern int
|
||||
u8_mbtouc_aux (ucs4_t *puc, const uint8_t *s, size_t n);
|
||||
static inline int
|
||||
u8_mbtouc (ucs4_t *puc, const uint8_t *s, size_t n)
|
||||
{
|
||||
uint8_t c = *s;
|
||||
|
||||
if (c < 0x80)
|
||||
{
|
||||
*puc = c;
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
return u8_mbtouc_aux (puc, s, n);
|
||||
}
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef GNULIB_UNISTR_U16_MBTOUC
|
||||
# if !HAVE_INLINE
|
||||
extern int
|
||||
u16_mbtouc (ucs4_t *puc, const uint16_t *s, size_t n);
|
||||
# else
|
||||
extern int
|
||||
u16_mbtouc_aux (ucs4_t *puc, const uint16_t *s, size_t n);
|
||||
static inline int
|
||||
u16_mbtouc (ucs4_t *puc, const uint16_t *s, size_t n)
|
||||
{
|
||||
uint16_t c = *s;
|
||||
|
||||
if (c < 0xd800 || c >= 0xe000)
|
||||
{
|
||||
*puc = c;
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
return u16_mbtouc_aux (puc, s, n);
|
||||
}
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef GNULIB_UNISTR_U32_MBTOUC
|
||||
# if !HAVE_INLINE
|
||||
extern int
|
||||
u32_mbtouc (ucs4_t *puc, const uint32_t *s, size_t n);
|
||||
# else
|
||||
static inline int
|
||||
u32_mbtouc (ucs4_t *puc, const uint32_t *s, size_t n _UNUSED_PARAMETER_)
|
||||
{
|
||||
uint32_t c = *s;
|
||||
|
||||
if (c < 0xd800 || (c >= 0xe000 && c < 0x110000))
|
||||
*puc = c;
|
||||
else
|
||||
/* invalid multibyte character */
|
||||
*puc = 0xfffd;
|
||||
return 1;
|
||||
}
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* Return the length (number of units) of the first character in S, putting
|
||||
its 'ucs4_t' representation in *PUC. Upon failure, *PUC is set to 0xfffd,
|
||||
and -1 is returned for an invalid sequence of units, -2 is returned for an
|
||||
incomplete sequence of units.
|
||||
The number of available units, N, must be > 0. */
|
||||
/* Similar to u*_mbtouc(), except that the return value gives more details
|
||||
about the failure, similar to mbrtowc(). */
|
||||
|
||||
#ifdef GNULIB_UNISTR_U8_MBTOUCR
|
||||
extern int
|
||||
u8_mbtoucr (ucs4_t *puc, const uint8_t *s, size_t n);
|
||||
#endif
|
||||
|
||||
#ifdef GNULIB_UNISTR_U16_MBTOUCR
|
||||
extern int
|
||||
u16_mbtoucr (ucs4_t *puc, const uint16_t *s, size_t n);
|
||||
#endif
|
||||
|
||||
#ifdef GNULIB_UNISTR_U32_MBTOUCR
|
||||
extern int
|
||||
u32_mbtoucr (ucs4_t *puc, const uint32_t *s, size_t n);
|
||||
#endif
|
||||
|
||||
/* Put the multibyte character represented by UC in S, returning its
|
||||
length. Return -1 upon failure, -2 if the number of available units, N,
|
||||
is too small. The latter case cannot occur if N >= 6/2/1, respectively. */
|
||||
/* Similar to wctomb(), except that s must not be NULL, and the argument n
|
||||
must be specified. */
|
||||
|
||||
#ifdef GNULIB_UNISTR_U8_UCTOMB
|
||||
/* Auxiliary function, also used by u8_chr, u8_strchr, u8_strrchr. */
|
||||
extern int
|
||||
u8_uctomb_aux (uint8_t *s, ucs4_t uc, int n);
|
||||
# if !HAVE_INLINE
|
||||
extern int
|
||||
u8_uctomb (uint8_t *s, ucs4_t uc, int n);
|
||||
# else
|
||||
static inline int
|
||||
u8_uctomb (uint8_t *s, ucs4_t uc, int n)
|
||||
{
|
||||
if (uc < 0x80 && n > 0)
|
||||
{
|
||||
s[0] = uc;
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
return u8_uctomb_aux (s, uc, n);
|
||||
}
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef GNULIB_UNISTR_U16_UCTOMB
|
||||
/* Auxiliary function, also used by u16_chr, u16_strchr, u16_strrchr. */
|
||||
extern int
|
||||
u16_uctomb_aux (uint16_t *s, ucs4_t uc, int n);
|
||||
# if !HAVE_INLINE
|
||||
extern int
|
||||
u16_uctomb (uint16_t *s, ucs4_t uc, int n);
|
||||
# else
|
||||
static inline int
|
||||
u16_uctomb (uint16_t *s, ucs4_t uc, int n)
|
||||
{
|
||||
if (uc < 0xd800 && n > 0)
|
||||
{
|
||||
s[0] = uc;
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
return u16_uctomb_aux (s, uc, n);
|
||||
}
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef GNULIB_UNISTR_U32_UCTOMB
|
||||
# if !HAVE_INLINE
|
||||
extern int
|
||||
u32_uctomb (uint32_t *s, ucs4_t uc, int n);
|
||||
# else
|
||||
static inline int
|
||||
u32_uctomb (uint32_t *s, ucs4_t uc, int n)
|
||||
{
|
||||
if (uc < 0xd800 || (uc >= 0xe000 && uc < 0x110000))
|
||||
{
|
||||
if (n > 0)
|
||||
{
|
||||
*s = uc;
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
return -2;
|
||||
}
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* Copy N units from SRC to DEST. */
|
||||
/* Similar to memcpy(). */
|
||||
extern uint8_t *
|
||||
u8_cpy (uint8_t *dest, const uint8_t *src, size_t n);
|
||||
extern uint16_t *
|
||||
u16_cpy (uint16_t *dest, const uint16_t *src, size_t n);
|
||||
extern uint32_t *
|
||||
u32_cpy (uint32_t *dest, const uint32_t *src, size_t n);
|
||||
|
||||
/* Copy N units from SRC to DEST, guaranteeing correct behavior for
|
||||
overlapping memory areas. */
|
||||
/* Similar to memmove(). */
|
||||
extern uint8_t *
|
||||
u8_move (uint8_t *dest, const uint8_t *src, size_t n);
|
||||
extern uint16_t *
|
||||
u16_move (uint16_t *dest, const uint16_t *src, size_t n);
|
||||
extern uint32_t *
|
||||
u32_move (uint32_t *dest, const uint32_t *src, size_t n);
|
||||
|
||||
/* Set the first N characters of S to UC. UC should be a character that
|
||||
occupies only 1 unit. */
|
||||
/* Similar to memset(). */
|
||||
extern uint8_t *
|
||||
u8_set (uint8_t *s, ucs4_t uc, size_t n);
|
||||
extern uint16_t *
|
||||
u16_set (uint16_t *s, ucs4_t uc, size_t n);
|
||||
extern uint32_t *
|
||||
u32_set (uint32_t *s, ucs4_t uc, size_t n);
|
||||
|
||||
/* Compare S1 and S2, each of length N. */
|
||||
/* Similar to memcmp(). */
|
||||
extern int
|
||||
u8_cmp (const uint8_t *s1, const uint8_t *s2, size_t n);
|
||||
extern int
|
||||
u16_cmp (const uint16_t *s1, const uint16_t *s2, size_t n);
|
||||
extern int
|
||||
u32_cmp (const uint32_t *s1, const uint32_t *s2, size_t n);
|
||||
|
||||
/* Compare S1 and S2. */
|
||||
/* Similar to the gnulib function memcmp2(). */
|
||||
extern int
|
||||
u8_cmp2 (const uint8_t *s1, size_t n1, const uint8_t *s2, size_t n2);
|
||||
extern int
|
||||
u16_cmp2 (const uint16_t *s1, size_t n1, const uint16_t *s2, size_t n2);
|
||||
extern int
|
||||
u32_cmp2 (const uint32_t *s1, size_t n1, const uint32_t *s2, size_t n2);
|
||||
|
||||
/* Search the string at S for UC. */
|
||||
/* Similar to memchr(). */
|
||||
extern uint8_t *
|
||||
u8_chr (const uint8_t *s, size_t n, ucs4_t uc);
|
||||
extern uint16_t *
|
||||
u16_chr (const uint16_t *s, size_t n, ucs4_t uc);
|
||||
extern uint32_t *
|
||||
u32_chr (const uint32_t *s, size_t n, ucs4_t uc);
|
||||
|
||||
/* Count the number of Unicode characters in the N units from S. */
|
||||
/* Similar to mbsnlen(). */
|
||||
extern size_t
|
||||
u8_mbsnlen (const uint8_t *s, size_t n);
|
||||
extern size_t
|
||||
u16_mbsnlen (const uint16_t *s, size_t n);
|
||||
extern size_t
|
||||
u32_mbsnlen (const uint32_t *s, size_t n);
|
||||
|
||||
/* Elementary string functions with memory allocation. */
|
||||
|
||||
/* Make a freshly allocated copy of S, of length N. */
|
||||
extern uint8_t *
|
||||
u8_cpy_alloc (const uint8_t *s, size_t n);
|
||||
extern uint16_t *
|
||||
u16_cpy_alloc (const uint16_t *s, size_t n);
|
||||
extern uint32_t *
|
||||
u32_cpy_alloc (const uint32_t *s, size_t n);
|
||||
|
||||
/* Elementary string functions on NUL terminated strings. */
|
||||
|
||||
/* Return the length (number of units) of the first character in S.
|
||||
Return 0 if it is the NUL character. Return -1 upon failure. */
|
||||
extern int
|
||||
u8_strmblen (const uint8_t *s);
|
||||
extern int
|
||||
u16_strmblen (const uint16_t *s);
|
||||
extern int
|
||||
u32_strmblen (const uint32_t *s);
|
||||
|
||||
/* Return the length (number of units) of the first character in S, putting
|
||||
its 'ucs4_t' representation in *PUC. Return 0 if it is the NUL
|
||||
character. Return -1 upon failure. */
|
||||
extern int
|
||||
u8_strmbtouc (ucs4_t *puc, const uint8_t *s);
|
||||
extern int
|
||||
u16_strmbtouc (ucs4_t *puc, const uint16_t *s);
|
||||
extern int
|
||||
u32_strmbtouc (ucs4_t *puc, const uint32_t *s);
|
||||
|
||||
/* Forward iteration step. Advances the pointer past the next character,
|
||||
or returns NULL if the end of the string has been reached. Puts the
|
||||
character's 'ucs4_t' representation in *PUC. */
|
||||
extern const uint8_t *
|
||||
u8_next (ucs4_t *puc, const uint8_t *s);
|
||||
extern const uint16_t *
|
||||
u16_next (ucs4_t *puc, const uint16_t *s);
|
||||
extern const uint32_t *
|
||||
u32_next (ucs4_t *puc, const uint32_t *s);
|
||||
|
||||
/* Backward iteration step. Advances the pointer to point to the previous
|
||||
character, or returns NULL if the beginning of the string had been reached.
|
||||
Puts the character's 'ucs4_t' representation in *PUC. */
|
||||
extern const uint8_t *
|
||||
u8_prev (ucs4_t *puc, const uint8_t *s, const uint8_t *start);
|
||||
extern const uint16_t *
|
||||
u16_prev (ucs4_t *puc, const uint16_t *s, const uint16_t *start);
|
||||
extern const uint32_t *
|
||||
u32_prev (ucs4_t *puc, const uint32_t *s, const uint32_t *start);
|
||||
|
||||
/* Return the number of units in S. */
|
||||
/* Similar to strlen(), wcslen(). */
|
||||
extern size_t
|
||||
u8_strlen (const uint8_t *s);
|
||||
extern size_t
|
||||
u16_strlen (const uint16_t *s);
|
||||
extern size_t
|
||||
u32_strlen (const uint32_t *s);
|
||||
|
||||
/* Return the number of units in S, but at most MAXLEN. */
|
||||
/* Similar to strnlen(), wcsnlen(). */
|
||||
extern size_t
|
||||
u8_strnlen (const uint8_t *s, size_t maxlen);
|
||||
extern size_t
|
||||
u16_strnlen (const uint16_t *s, size_t maxlen);
|
||||
extern size_t
|
||||
u32_strnlen (const uint32_t *s, size_t maxlen);
|
||||
|
||||
/* Copy SRC to DEST. */
|
||||
/* Similar to strcpy(), wcscpy(). */
|
||||
extern uint8_t *
|
||||
u8_strcpy (uint8_t *dest, const uint8_t *src);
|
||||
extern uint16_t *
|
||||
u16_strcpy (uint16_t *dest, const uint16_t *src);
|
||||
extern uint32_t *
|
||||
u32_strcpy (uint32_t *dest, const uint32_t *src);
|
||||
|
||||
/* Copy SRC to DEST, returning the address of the terminating NUL in DEST. */
|
||||
/* Similar to stpcpy(). */
|
||||
extern uint8_t *
|
||||
u8_stpcpy (uint8_t *dest, const uint8_t *src);
|
||||
extern uint16_t *
|
||||
u16_stpcpy (uint16_t *dest, const uint16_t *src);
|
||||
extern uint32_t *
|
||||
u32_stpcpy (uint32_t *dest, const uint32_t *src);
|
||||
|
||||
/* Copy no more than N units of SRC to DEST. */
|
||||
/* Similar to strncpy(), wcsncpy(). */
|
||||
extern uint8_t *
|
||||
u8_strncpy (uint8_t *dest, const uint8_t *src, size_t n);
|
||||
extern uint16_t *
|
||||
u16_strncpy (uint16_t *dest, const uint16_t *src, size_t n);
|
||||
extern uint32_t *
|
||||
u32_strncpy (uint32_t *dest, const uint32_t *src, size_t n);
|
||||
|
||||
/* Copy no more than N units of SRC to DEST, returning the address of
|
||||
the last unit written into DEST. */
|
||||
/* Similar to stpncpy(). */
|
||||
extern uint8_t *
|
||||
u8_stpncpy (uint8_t *dest, const uint8_t *src, size_t n);
|
||||
extern uint16_t *
|
||||
u16_stpncpy (uint16_t *dest, const uint16_t *src, size_t n);
|
||||
extern uint32_t *
|
||||
u32_stpncpy (uint32_t *dest, const uint32_t *src, size_t n);
|
||||
|
||||
/* Append SRC onto DEST. */
|
||||
/* Similar to strcat(), wcscat(). */
|
||||
extern uint8_t *
|
||||
u8_strcat (uint8_t *dest, const uint8_t *src);
|
||||
extern uint16_t *
|
||||
u16_strcat (uint16_t *dest, const uint16_t *src);
|
||||
extern uint32_t *
|
||||
u32_strcat (uint32_t *dest, const uint32_t *src);
|
||||
|
||||
/* Append no more than N units of SRC onto DEST. */
|
||||
/* Similar to strncat(), wcsncat(). */
|
||||
extern uint8_t *
|
||||
u8_strncat (uint8_t *dest, const uint8_t *src, size_t n);
|
||||
extern uint16_t *
|
||||
u16_strncat (uint16_t *dest, const uint16_t *src, size_t n);
|
||||
extern uint32_t *
|
||||
u32_strncat (uint32_t *dest, const uint32_t *src, size_t n);
|
||||
|
||||
/* Compare S1 and S2. */
|
||||
/* Similar to strcmp(), wcscmp(). */
|
||||
extern int
|
||||
u8_strcmp (const uint8_t *s1, const uint8_t *s2);
|
||||
extern int
|
||||
u16_strcmp (const uint16_t *s1, const uint16_t *s2);
|
||||
extern int
|
||||
u32_strcmp (const uint32_t *s1, const uint32_t *s2);
|
||||
|
||||
/* Compare S1 and S2 using the collation rules of the current locale.
|
||||
Return -1 if S1 < S2, 0 if S1 = S2, 1 if S1 > S2.
|
||||
Upon failure, set errno and return any value. */
|
||||
/* Similar to strcoll(), wcscoll(). */
|
||||
extern int
|
||||
u8_strcoll (const uint8_t *s1, const uint8_t *s2);
|
||||
extern int
|
||||
u16_strcoll (const uint16_t *s1, const uint16_t *s2);
|
||||
extern int
|
||||
u32_strcoll (const uint32_t *s1, const uint32_t *s2);
|
||||
|
||||
/* Compare no more than N units of S1 and S2. */
|
||||
/* Similar to strncmp(), wcsncmp(). */
|
||||
extern int
|
||||
u8_strncmp (const uint8_t *s1, const uint8_t *s2, size_t n);
|
||||
extern int
|
||||
u16_strncmp (const uint16_t *s1, const uint16_t *s2, size_t n);
|
||||
extern int
|
||||
u32_strncmp (const uint32_t *s1, const uint32_t *s2, size_t n);
|
||||
|
||||
/* Duplicate S, returning an identical malloc'd string. */
|
||||
/* Similar to strdup(), wcsdup(). */
|
||||
extern uint8_t *
|
||||
u8_strdup (const uint8_t *s);
|
||||
extern uint16_t *
|
||||
u16_strdup (const uint16_t *s);
|
||||
extern uint32_t *
|
||||
u32_strdup (const uint32_t *s);
|
||||
|
||||
/* Find the first occurrence of UC in STR. */
|
||||
/* Similar to strchr(), wcschr(). */
|
||||
extern uint8_t *
|
||||
u8_strchr (const uint8_t *str, ucs4_t uc);
|
||||
extern uint16_t *
|
||||
u16_strchr (const uint16_t *str, ucs4_t uc);
|
||||
extern uint32_t *
|
||||
u32_strchr (const uint32_t *str, ucs4_t uc);
|
||||
|
||||
/* Find the last occurrence of UC in STR. */
|
||||
/* Similar to strrchr(), wcsrchr(). */
|
||||
extern uint8_t *
|
||||
u8_strrchr (const uint8_t *str, ucs4_t uc);
|
||||
extern uint16_t *
|
||||
u16_strrchr (const uint16_t *str, ucs4_t uc);
|
||||
extern uint32_t *
|
||||
u32_strrchr (const uint32_t *str, ucs4_t uc);
|
||||
|
||||
/* Return the length of the initial segment of STR which consists entirely
|
||||
of Unicode characters not in REJECT. */
|
||||
/* Similar to strcspn(), wcscspn(). */
|
||||
extern size_t
|
||||
u8_strcspn (const uint8_t *str, const uint8_t *reject);
|
||||
extern size_t
|
||||
u16_strcspn (const uint16_t *str, const uint16_t *reject);
|
||||
extern size_t
|
||||
u32_strcspn (const uint32_t *str, const uint32_t *reject);
|
||||
|
||||
/* Return the length of the initial segment of STR which consists entirely
|
||||
of Unicode characters in ACCEPT. */
|
||||
/* Similar to strspn(), wcsspn(). */
|
||||
extern size_t
|
||||
u8_strspn (const uint8_t *str, const uint8_t *accept);
|
||||
extern size_t
|
||||
u16_strspn (const uint16_t *str, const uint16_t *accept);
|
||||
extern size_t
|
||||
u32_strspn (const uint32_t *str, const uint32_t *accept);
|
||||
|
||||
/* Find the first occurrence in STR of any character in ACCEPT. */
|
||||
/* Similar to strpbrk(), wcspbrk(). */
|
||||
extern uint8_t *
|
||||
u8_strpbrk (const uint8_t *str, const uint8_t *accept);
|
||||
extern uint16_t *
|
||||
u16_strpbrk (const uint16_t *str, const uint16_t *accept);
|
||||
extern uint32_t *
|
||||
u32_strpbrk (const uint32_t *str, const uint32_t *accept);
|
||||
|
||||
/* Find the first occurrence of NEEDLE in HAYSTACK. */
|
||||
/* Similar to strstr(), wcsstr(). */
|
||||
extern uint8_t *
|
||||
u8_strstr (const uint8_t *haystack, const uint8_t *needle);
|
||||
extern uint16_t *
|
||||
u16_strstr (const uint16_t *haystack, const uint16_t *needle);
|
||||
extern uint32_t *
|
||||
u32_strstr (const uint32_t *haystack, const uint32_t *needle);
|
||||
|
||||
/* Test whether STR starts with PREFIX. */
|
||||
extern bool
|
||||
u8_startswith (const uint8_t *str, const uint8_t *prefix);
|
||||
extern bool
|
||||
u16_startswith (const uint16_t *str, const uint16_t *prefix);
|
||||
extern bool
|
||||
u32_startswith (const uint32_t *str, const uint32_t *prefix);
|
||||
|
||||
/* Test whether STR ends with SUFFIX. */
|
||||
extern bool
|
||||
u8_endswith (const uint8_t *str, const uint8_t *suffix);
|
||||
extern bool
|
||||
u16_endswith (const uint16_t *str, const uint16_t *suffix);
|
||||
extern bool
|
||||
u32_endswith (const uint32_t *str, const uint32_t *suffix);
|
||||
|
||||
/* Divide STR into tokens separated by characters in DELIM.
|
||||
This interface is actually more similar to wcstok than to strtok. */
|
||||
/* Similar to strtok_r(), wcstok(). */
|
||||
extern uint8_t *
|
||||
u8_strtok (uint8_t *str, const uint8_t *delim, uint8_t **ptr);
|
||||
extern uint16_t *
|
||||
u16_strtok (uint16_t *str, const uint16_t *delim, uint16_t **ptr);
|
||||
extern uint32_t *
|
||||
u32_strtok (uint32_t *str, const uint32_t *delim, uint32_t **ptr);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _UNISTR_H */
|
158
lib/unistr/u8-mbtouc-aux.c
Normal file
158
lib/unistr/u8-mbtouc-aux.c
Normal file
|
@ -0,0 +1,158 @@
|
|||
/* Conversion UTF-8 to UCS-4.
|
||||
Copyright (C) 2001-2002, 2006-2007, 2009 Free Software Foundation, Inc.
|
||||
Written by Bruno Haible <bruno@clisp.org>, 2001.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU Lesser General Public License as published
|
||||
by the Free Software Foundation; either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
/* Specification. */
|
||||
#include "unistr.h"
|
||||
|
||||
#if defined IN_LIBUNISTRING || HAVE_INLINE
|
||||
|
||||
int
|
||||
u8_mbtouc_aux (ucs4_t *puc, const uint8_t *s, size_t n)
|
||||
{
|
||||
uint8_t c = *s;
|
||||
|
||||
if (c >= 0xc2)
|
||||
{
|
||||
if (c < 0xe0)
|
||||
{
|
||||
if (n >= 2)
|
||||
{
|
||||
if ((s[1] ^ 0x80) < 0x40)
|
||||
{
|
||||
*puc = ((unsigned int) (c & 0x1f) << 6)
|
||||
| (unsigned int) (s[1] ^ 0x80);
|
||||
return 2;
|
||||
}
|
||||
/* invalid multibyte character */
|
||||
}
|
||||
else
|
||||
{
|
||||
/* incomplete multibyte character */
|
||||
*puc = 0xfffd;
|
||||
return n;
|
||||
}
|
||||
}
|
||||
else if (c < 0xf0)
|
||||
{
|
||||
if (n >= 3)
|
||||
{
|
||||
if ((s[1] ^ 0x80) < 0x40 && (s[2] ^ 0x80) < 0x40
|
||||
&& (c >= 0xe1 || s[1] >= 0xa0)
|
||||
&& (c != 0xed || s[1] < 0xa0))
|
||||
{
|
||||
*puc = ((unsigned int) (c & 0x0f) << 12)
|
||||
| ((unsigned int) (s[1] ^ 0x80) << 6)
|
||||
| (unsigned int) (s[2] ^ 0x80);
|
||||
return 3;
|
||||
}
|
||||
/* invalid multibyte character */
|
||||
}
|
||||
else
|
||||
{
|
||||
/* incomplete multibyte character */
|
||||
*puc = 0xfffd;
|
||||
return n;
|
||||
}
|
||||
}
|
||||
else if (c < 0xf8)
|
||||
{
|
||||
if (n >= 4)
|
||||
{
|
||||
if ((s[1] ^ 0x80) < 0x40 && (s[2] ^ 0x80) < 0x40
|
||||
&& (s[3] ^ 0x80) < 0x40
|
||||
&& (c >= 0xf1 || s[1] >= 0x90)
|
||||
#if 1
|
||||
&& (c < 0xf4 || (c == 0xf4 && s[1] < 0x90))
|
||||
#endif
|
||||
)
|
||||
{
|
||||
*puc = ((unsigned int) (c & 0x07) << 18)
|
||||
| ((unsigned int) (s[1] ^ 0x80) << 12)
|
||||
| ((unsigned int) (s[2] ^ 0x80) << 6)
|
||||
| (unsigned int) (s[3] ^ 0x80);
|
||||
return 4;
|
||||
}
|
||||
/* invalid multibyte character */
|
||||
}
|
||||
else
|
||||
{
|
||||
/* incomplete multibyte character */
|
||||
*puc = 0xfffd;
|
||||
return n;
|
||||
}
|
||||
}
|
||||
#if 0
|
||||
else if (c < 0xfc)
|
||||
{
|
||||
if (n >= 5)
|
||||
{
|
||||
if ((s[1] ^ 0x80) < 0x40 && (s[2] ^ 0x80) < 0x40
|
||||
&& (s[3] ^ 0x80) < 0x40 && (s[4] ^ 0x80) < 0x40
|
||||
&& (c >= 0xf9 || s[1] >= 0x88))
|
||||
{
|
||||
*puc = ((unsigned int) (c & 0x03) << 24)
|
||||
| ((unsigned int) (s[1] ^ 0x80) << 18)
|
||||
| ((unsigned int) (s[2] ^ 0x80) << 12)
|
||||
| ((unsigned int) (s[3] ^ 0x80) << 6)
|
||||
| (unsigned int) (s[4] ^ 0x80);
|
||||
return 5;
|
||||
}
|
||||
/* invalid multibyte character */
|
||||
}
|
||||
else
|
||||
{
|
||||
/* incomplete multibyte character */
|
||||
*puc = 0xfffd;
|
||||
return n;
|
||||
}
|
||||
}
|
||||
else if (c < 0xfe)
|
||||
{
|
||||
if (n >= 6)
|
||||
{
|
||||
if ((s[1] ^ 0x80) < 0x40 && (s[2] ^ 0x80) < 0x40
|
||||
&& (s[3] ^ 0x80) < 0x40 && (s[4] ^ 0x80) < 0x40
|
||||
&& (s[5] ^ 0x80) < 0x40
|
||||
&& (c >= 0xfd || s[1] >= 0x84))
|
||||
{
|
||||
*puc = ((unsigned int) (c & 0x01) << 30)
|
||||
| ((unsigned int) (s[1] ^ 0x80) << 24)
|
||||
| ((unsigned int) (s[2] ^ 0x80) << 18)
|
||||
| ((unsigned int) (s[3] ^ 0x80) << 12)
|
||||
| ((unsigned int) (s[4] ^ 0x80) << 6)
|
||||
| (unsigned int) (s[5] ^ 0x80);
|
||||
return 6;
|
||||
}
|
||||
/* invalid multibyte character */
|
||||
}
|
||||
else
|
||||
{
|
||||
/* incomplete multibyte character */
|
||||
*puc = 0xfffd;
|
||||
return n;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
/* invalid multibyte character */
|
||||
*puc = 0xfffd;
|
||||
return 1;
|
||||
}
|
||||
|
||||
#endif
|
168
lib/unistr/u8-mbtouc-unsafe-aux.c
Normal file
168
lib/unistr/u8-mbtouc-unsafe-aux.c
Normal file
|
@ -0,0 +1,168 @@
|
|||
/* Conversion UTF-8 to UCS-4.
|
||||
Copyright (C) 2001-2002, 2006-2007, 2009 Free Software Foundation, Inc.
|
||||
Written by Bruno Haible <bruno@clisp.org>, 2001.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU Lesser General Public License as published
|
||||
by the Free Software Foundation; either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
/* Specification. */
|
||||
#include "unistr.h"
|
||||
|
||||
#if defined IN_LIBUNISTRING || HAVE_INLINE
|
||||
|
||||
int
|
||||
u8_mbtouc_unsafe_aux (ucs4_t *puc, const uint8_t *s, size_t n)
|
||||
{
|
||||
uint8_t c = *s;
|
||||
|
||||
if (c >= 0xc2)
|
||||
{
|
||||
if (c < 0xe0)
|
||||
{
|
||||
if (n >= 2)
|
||||
{
|
||||
#if CONFIG_UNICODE_SAFETY
|
||||
if ((s[1] ^ 0x80) < 0x40)
|
||||
#endif
|
||||
{
|
||||
*puc = ((unsigned int) (c & 0x1f) << 6)
|
||||
| (unsigned int) (s[1] ^ 0x80);
|
||||
return 2;
|
||||
}
|
||||
/* invalid multibyte character */
|
||||
}
|
||||
else
|
||||
{
|
||||
/* incomplete multibyte character */
|
||||
*puc = 0xfffd;
|
||||
return n;
|
||||
}
|
||||
}
|
||||
else if (c < 0xf0)
|
||||
{
|
||||
if (n >= 3)
|
||||
{
|
||||
#if CONFIG_UNICODE_SAFETY
|
||||
if ((s[1] ^ 0x80) < 0x40 && (s[2] ^ 0x80) < 0x40
|
||||
&& (c >= 0xe1 || s[1] >= 0xa0)
|
||||
&& (c != 0xed || s[1] < 0xa0))
|
||||
#endif
|
||||
{
|
||||
*puc = ((unsigned int) (c & 0x0f) << 12)
|
||||
| ((unsigned int) (s[1] ^ 0x80) << 6)
|
||||
| (unsigned int) (s[2] ^ 0x80);
|
||||
return 3;
|
||||
}
|
||||
/* invalid multibyte character */
|
||||
}
|
||||
else
|
||||
{
|
||||
/* incomplete multibyte character */
|
||||
*puc = 0xfffd;
|
||||
return n;
|
||||
}
|
||||
}
|
||||
else if (c < 0xf8)
|
||||
{
|
||||
if (n >= 4)
|
||||
{
|
||||
#if CONFIG_UNICODE_SAFETY
|
||||
if ((s[1] ^ 0x80) < 0x40 && (s[2] ^ 0x80) < 0x40
|
||||
&& (s[3] ^ 0x80) < 0x40
|
||||
&& (c >= 0xf1 || s[1] >= 0x90)
|
||||
#if 1
|
||||
&& (c < 0xf4 || (c == 0xf4 && s[1] < 0x90))
|
||||
#endif
|
||||
)
|
||||
#endif
|
||||
{
|
||||
*puc = ((unsigned int) (c & 0x07) << 18)
|
||||
| ((unsigned int) (s[1] ^ 0x80) << 12)
|
||||
| ((unsigned int) (s[2] ^ 0x80) << 6)
|
||||
| (unsigned int) (s[3] ^ 0x80);
|
||||
return 4;
|
||||
}
|
||||
/* invalid multibyte character */
|
||||
}
|
||||
else
|
||||
{
|
||||
/* incomplete multibyte character */
|
||||
*puc = 0xfffd;
|
||||
return n;
|
||||
}
|
||||
}
|
||||
#if 0
|
||||
else if (c < 0xfc)
|
||||
{
|
||||
if (n >= 5)
|
||||
{
|
||||
#if CONFIG_UNICODE_SAFETY
|
||||
if ((s[1] ^ 0x80) < 0x40 && (s[2] ^ 0x80) < 0x40
|
||||
&& (s[3] ^ 0x80) < 0x40 && (s[4] ^ 0x80) < 0x40
|
||||
&& (c >= 0xf9 || s[1] >= 0x88))
|
||||
#endif
|
||||
{
|
||||
*puc = ((unsigned int) (c & 0x03) << 24)
|
||||
| ((unsigned int) (s[1] ^ 0x80) << 18)
|
||||
| ((unsigned int) (s[2] ^ 0x80) << 12)
|
||||
| ((unsigned int) (s[3] ^ 0x80) << 6)
|
||||
| (unsigned int) (s[4] ^ 0x80);
|
||||
return 5;
|
||||
}
|
||||
/* invalid multibyte character */
|
||||
}
|
||||
else
|
||||
{
|
||||
/* incomplete multibyte character */
|
||||
*puc = 0xfffd;
|
||||
return n;
|
||||
}
|
||||
}
|
||||
else if (c < 0xfe)
|
||||
{
|
||||
if (n >= 6)
|
||||
{
|
||||
#if CONFIG_UNICODE_SAFETY
|
||||
if ((s[1] ^ 0x80) < 0x40 && (s[2] ^ 0x80) < 0x40
|
||||
&& (s[3] ^ 0x80) < 0x40 && (s[4] ^ 0x80) < 0x40
|
||||
&& (s[5] ^ 0x80) < 0x40
|
||||
&& (c >= 0xfd || s[1] >= 0x84))
|
||||
#endif
|
||||
{
|
||||
*puc = ((unsigned int) (c & 0x01) << 30)
|
||||
| ((unsigned int) (s[1] ^ 0x80) << 24)
|
||||
| ((unsigned int) (s[2] ^ 0x80) << 18)
|
||||
| ((unsigned int) (s[3] ^ 0x80) << 12)
|
||||
| ((unsigned int) (s[4] ^ 0x80) << 6)
|
||||
| (unsigned int) (s[5] ^ 0x80);
|
||||
return 6;
|
||||
}
|
||||
/* invalid multibyte character */
|
||||
}
|
||||
else
|
||||
{
|
||||
/* incomplete multibyte character */
|
||||
*puc = 0xfffd;
|
||||
return n;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
/* invalid multibyte character */
|
||||
*puc = 0xfffd;
|
||||
return 1;
|
||||
}
|
||||
|
||||
#endif
|
179
lib/unistr/u8-mbtouc-unsafe.c
Normal file
179
lib/unistr/u8-mbtouc-unsafe.c
Normal file
|
@ -0,0 +1,179 @@
|
|||
/* Look at first character in UTF-8 string.
|
||||
Copyright (C) 1999-2002, 2006-2007, 2009 Free Software Foundation, Inc.
|
||||
Written by Bruno Haible <bruno@clisp.org>, 2001.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU Lesser General Public License as published
|
||||
by the Free Software Foundation; either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#if defined IN_LIBUNISTRING
|
||||
/* Tell unistr.h to declare u8_mbtouc_unsafe as 'extern', not
|
||||
'static inline'. */
|
||||
# include "unistring-notinline.h"
|
||||
#endif
|
||||
|
||||
/* Specification. */
|
||||
#include "unistr.h"
|
||||
|
||||
#if !HAVE_INLINE
|
||||
|
||||
int
|
||||
u8_mbtouc_unsafe (ucs4_t *puc, const uint8_t *s, size_t n)
|
||||
{
|
||||
uint8_t c = *s;
|
||||
|
||||
if (c < 0x80)
|
||||
{
|
||||
*puc = c;
|
||||
return 1;
|
||||
}
|
||||
else if (c >= 0xc2)
|
||||
{
|
||||
if (c < 0xe0)
|
||||
{
|
||||
if (n >= 2)
|
||||
{
|
||||
#if CONFIG_UNICODE_SAFETY
|
||||
if ((s[1] ^ 0x80) < 0x40)
|
||||
#endif
|
||||
{
|
||||
*puc = ((unsigned int) (c & 0x1f) << 6)
|
||||
| (unsigned int) (s[1] ^ 0x80);
|
||||
return 2;
|
||||
}
|
||||
/* invalid multibyte character */
|
||||
}
|
||||
else
|
||||
{
|
||||
/* incomplete multibyte character */
|
||||
*puc = 0xfffd;
|
||||
return n;
|
||||
}
|
||||
}
|
||||
else if (c < 0xf0)
|
||||
{
|
||||
if (n >= 3)
|
||||
{
|
||||
#if CONFIG_UNICODE_SAFETY
|
||||
if ((s[1] ^ 0x80) < 0x40 && (s[2] ^ 0x80) < 0x40
|
||||
&& (c >= 0xe1 || s[1] >= 0xa0)
|
||||
&& (c != 0xed || s[1] < 0xa0))
|
||||
#endif
|
||||
{
|
||||
*puc = ((unsigned int) (c & 0x0f) << 12)
|
||||
| ((unsigned int) (s[1] ^ 0x80) << 6)
|
||||
| (unsigned int) (s[2] ^ 0x80);
|
||||
return 3;
|
||||
}
|
||||
/* invalid multibyte character */
|
||||
}
|
||||
else
|
||||
{
|
||||
/* incomplete multibyte character */
|
||||
*puc = 0xfffd;
|
||||
return n;
|
||||
}
|
||||
}
|
||||
else if (c < 0xf8)
|
||||
{
|
||||
if (n >= 4)
|
||||
{
|
||||
#if CONFIG_UNICODE_SAFETY
|
||||
if ((s[1] ^ 0x80) < 0x40 && (s[2] ^ 0x80) < 0x40
|
||||
&& (s[3] ^ 0x80) < 0x40
|
||||
&& (c >= 0xf1 || s[1] >= 0x90)
|
||||
#if 1
|
||||
&& (c < 0xf4 || (c == 0xf4 && s[1] < 0x90))
|
||||
#endif
|
||||
)
|
||||
#endif
|
||||
{
|
||||
*puc = ((unsigned int) (c & 0x07) << 18)
|
||||
| ((unsigned int) (s[1] ^ 0x80) << 12)
|
||||
| ((unsigned int) (s[2] ^ 0x80) << 6)
|
||||
| (unsigned int) (s[3] ^ 0x80);
|
||||
return 4;
|
||||
}
|
||||
/* invalid multibyte character */
|
||||
}
|
||||
else
|
||||
{
|
||||
/* incomplete multibyte character */
|
||||
*puc = 0xfffd;
|
||||
return n;
|
||||
}
|
||||
}
|
||||
#if 0
|
||||
else if (c < 0xfc)
|
||||
{
|
||||
if (n >= 5)
|
||||
{
|
||||
#if CONFIG_UNICODE_SAFETY
|
||||
if ((s[1] ^ 0x80) < 0x40 && (s[2] ^ 0x80) < 0x40
|
||||
&& (s[3] ^ 0x80) < 0x40 && (s[4] ^ 0x80) < 0x40
|
||||
&& (c >= 0xf9 || s[1] >= 0x88))
|
||||
#endif
|
||||
{
|
||||
*puc = ((unsigned int) (c & 0x03) << 24)
|
||||
| ((unsigned int) (s[1] ^ 0x80) << 18)
|
||||
| ((unsigned int) (s[2] ^ 0x80) << 12)
|
||||
| ((unsigned int) (s[3] ^ 0x80) << 6)
|
||||
| (unsigned int) (s[4] ^ 0x80);
|
||||
return 5;
|
||||
}
|
||||
/* invalid multibyte character */
|
||||
}
|
||||
else
|
||||
{
|
||||
/* incomplete multibyte character */
|
||||
*puc = 0xfffd;
|
||||
return n;
|
||||
}
|
||||
}
|
||||
else if (c < 0xfe)
|
||||
{
|
||||
if (n >= 6)
|
||||
{
|
||||
#if CONFIG_UNICODE_SAFETY
|
||||
if ((s[1] ^ 0x80) < 0x40 && (s[2] ^ 0x80) < 0x40
|
||||
&& (s[3] ^ 0x80) < 0x40 && (s[4] ^ 0x80) < 0x40
|
||||
&& (s[5] ^ 0x80) < 0x40
|
||||
&& (c >= 0xfd || s[1] >= 0x84))
|
||||
#endif
|
||||
{
|
||||
*puc = ((unsigned int) (c & 0x01) << 30)
|
||||
| ((unsigned int) (s[1] ^ 0x80) << 24)
|
||||
| ((unsigned int) (s[2] ^ 0x80) << 18)
|
||||
| ((unsigned int) (s[3] ^ 0x80) << 12)
|
||||
| ((unsigned int) (s[4] ^ 0x80) << 6)
|
||||
| (unsigned int) (s[5] ^ 0x80);
|
||||
return 6;
|
||||
}
|
||||
/* invalid multibyte character */
|
||||
}
|
||||
else
|
||||
{
|
||||
/* incomplete multibyte character */
|
||||
*puc = 0xfffd;
|
||||
return n;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
/* invalid multibyte character */
|
||||
*puc = 0xfffd;
|
||||
return 1;
|
||||
}
|
||||
|
||||
#endif
|
168
lib/unistr/u8-mbtouc.c
Normal file
168
lib/unistr/u8-mbtouc.c
Normal file
|
@ -0,0 +1,168 @@
|
|||
/* Look at first character in UTF-8 string.
|
||||
Copyright (C) 1999-2002, 2006-2007, 2009 Free Software Foundation, Inc.
|
||||
Written by Bruno Haible <bruno@clisp.org>, 2001.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU Lesser General Public License as published
|
||||
by the Free Software Foundation; either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#if defined IN_LIBUNISTRING
|
||||
/* Tell unistr.h to declare u8_mbtouc as 'extern', not 'static inline'. */
|
||||
# include "unistring-notinline.h"
|
||||
#endif
|
||||
|
||||
/* Specification. */
|
||||
#include "unistr.h"
|
||||
|
||||
#if !HAVE_INLINE
|
||||
|
||||
int
|
||||
u8_mbtouc (ucs4_t *puc, const uint8_t *s, size_t n)
|
||||
{
|
||||
uint8_t c = *s;
|
||||
|
||||
if (c < 0x80)
|
||||
{
|
||||
*puc = c;
|
||||
return 1;
|
||||
}
|
||||
else if (c >= 0xc2)
|
||||
{
|
||||
if (c < 0xe0)
|
||||
{
|
||||
if (n >= 2)
|
||||
{
|
||||
if ((s[1] ^ 0x80) < 0x40)
|
||||
{
|
||||
*puc = ((unsigned int) (c & 0x1f) << 6)
|
||||
| (unsigned int) (s[1] ^ 0x80);
|
||||
return 2;
|
||||
}
|
||||
/* invalid multibyte character */
|
||||
}
|
||||
else
|
||||
{
|
||||
/* incomplete multibyte character */
|
||||
*puc = 0xfffd;
|
||||
return n;
|
||||
}
|
||||
}
|
||||
else if (c < 0xf0)
|
||||
{
|
||||
if (n >= 3)
|
||||
{
|
||||
if ((s[1] ^ 0x80) < 0x40 && (s[2] ^ 0x80) < 0x40
|
||||
&& (c >= 0xe1 || s[1] >= 0xa0)
|
||||
&& (c != 0xed || s[1] < 0xa0))
|
||||
{
|
||||
*puc = ((unsigned int) (c & 0x0f) << 12)
|
||||
| ((unsigned int) (s[1] ^ 0x80) << 6)
|
||||
| (unsigned int) (s[2] ^ 0x80);
|
||||
return 3;
|
||||
}
|
||||
/* invalid multibyte character */
|
||||
}
|
||||
else
|
||||
{
|
||||
/* incomplete multibyte character */
|
||||
*puc = 0xfffd;
|
||||
return n;
|
||||
}
|
||||
}
|
||||
else if (c < 0xf8)
|
||||
{
|
||||
if (n >= 4)
|
||||
{
|
||||
if ((s[1] ^ 0x80) < 0x40 && (s[2] ^ 0x80) < 0x40
|
||||
&& (s[3] ^ 0x80) < 0x40
|
||||
&& (c >= 0xf1 || s[1] >= 0x90)
|
||||
#if 1
|
||||
&& (c < 0xf4 || (c == 0xf4 && s[1] < 0x90))
|
||||
#endif
|
||||
)
|
||||
{
|
||||
*puc = ((unsigned int) (c & 0x07) << 18)
|
||||
| ((unsigned int) (s[1] ^ 0x80) << 12)
|
||||
| ((unsigned int) (s[2] ^ 0x80) << 6)
|
||||
| (unsigned int) (s[3] ^ 0x80);
|
||||
return 4;
|
||||
}
|
||||
/* invalid multibyte character */
|
||||
}
|
||||
else
|
||||
{
|
||||
/* incomplete multibyte character */
|
||||
*puc = 0xfffd;
|
||||
return n;
|
||||
}
|
||||
}
|
||||
#if 0
|
||||
else if (c < 0xfc)
|
||||
{
|
||||
if (n >= 5)
|
||||
{
|
||||
if ((s[1] ^ 0x80) < 0x40 && (s[2] ^ 0x80) < 0x40
|
||||
&& (s[3] ^ 0x80) < 0x40 && (s[4] ^ 0x80) < 0x40
|
||||
&& (c >= 0xf9 || s[1] >= 0x88))
|
||||
{
|
||||
*puc = ((unsigned int) (c & 0x03) << 24)
|
||||
| ((unsigned int) (s[1] ^ 0x80) << 18)
|
||||
| ((unsigned int) (s[2] ^ 0x80) << 12)
|
||||
| ((unsigned int) (s[3] ^ 0x80) << 6)
|
||||
| (unsigned int) (s[4] ^ 0x80);
|
||||
return 5;
|
||||
}
|
||||
/* invalid multibyte character */
|
||||
}
|
||||
else
|
||||
{
|
||||
/* incomplete multibyte character */
|
||||
*puc = 0xfffd;
|
||||
return n;
|
||||
}
|
||||
}
|
||||
else if (c < 0xfe)
|
||||
{
|
||||
if (n >= 6)
|
||||
{
|
||||
if ((s[1] ^ 0x80) < 0x40 && (s[2] ^ 0x80) < 0x40
|
||||
&& (s[3] ^ 0x80) < 0x40 && (s[4] ^ 0x80) < 0x40
|
||||
&& (s[5] ^ 0x80) < 0x40
|
||||
&& (c >= 0xfd || s[1] >= 0x84))
|
||||
{
|
||||
*puc = ((unsigned int) (c & 0x01) << 30)
|
||||
| ((unsigned int) (s[1] ^ 0x80) << 24)
|
||||
| ((unsigned int) (s[2] ^ 0x80) << 18)
|
||||
| ((unsigned int) (s[3] ^ 0x80) << 12)
|
||||
| ((unsigned int) (s[4] ^ 0x80) << 6)
|
||||
| (unsigned int) (s[5] ^ 0x80);
|
||||
return 6;
|
||||
}
|
||||
/* invalid multibyte character */
|
||||
}
|
||||
else
|
||||
{
|
||||
/* incomplete multibyte character */
|
||||
*puc = 0xfffd;
|
||||
return n;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
/* invalid multibyte character */
|
||||
*puc = 0xfffd;
|
||||
return 1;
|
||||
}
|
||||
|
||||
#endif
|
285
lib/unistr/u8-mbtoucr.c
Normal file
285
lib/unistr/u8-mbtoucr.c
Normal file
|
@ -0,0 +1,285 @@
|
|||
/* Look at first character in UTF-8 string, returning an error code.
|
||||
Copyright (C) 1999-2002, 2006-2007 Free Software Foundation, Inc.
|
||||
Written by Bruno Haible <bruno@clisp.org>, 2001.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU Lesser General Public License as published
|
||||
by the Free Software Foundation; either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
/* Specification. */
|
||||
#include "unistr.h"
|
||||
|
||||
int
|
||||
u8_mbtoucr (ucs4_t *puc, const uint8_t *s, size_t n)
|
||||
{
|
||||
uint8_t c = *s;
|
||||
|
||||
if (c < 0x80)
|
||||
{
|
||||
*puc = c;
|
||||
return 1;
|
||||
}
|
||||
else if (c >= 0xc2)
|
||||
{
|
||||
if (c < 0xe0)
|
||||
{
|
||||
if (n >= 2)
|
||||
{
|
||||
if ((s[1] ^ 0x80) < 0x40)
|
||||
{
|
||||
*puc = ((unsigned int) (c & 0x1f) << 6)
|
||||
| (unsigned int) (s[1] ^ 0x80);
|
||||
return 2;
|
||||
}
|
||||
/* invalid multibyte character */
|
||||
}
|
||||
else
|
||||
{
|
||||
/* incomplete multibyte character */
|
||||
*puc = 0xfffd;
|
||||
return -2;
|
||||
}
|
||||
}
|
||||
else if (c < 0xf0)
|
||||
{
|
||||
if (n >= 2)
|
||||
{
|
||||
if ((s[1] ^ 0x80) < 0x40
|
||||
&& (c >= 0xe1 || s[1] >= 0xa0)
|
||||
&& (c != 0xed || s[1] < 0xa0))
|
||||
{
|
||||
if (n >= 3)
|
||||
{
|
||||
if ((s[2] ^ 0x80) < 0x40)
|
||||
{
|
||||
*puc = ((unsigned int) (c & 0x0f) << 12)
|
||||
| ((unsigned int) (s[1] ^ 0x80) << 6)
|
||||
| (unsigned int) (s[2] ^ 0x80);
|
||||
return 3;
|
||||
}
|
||||
/* invalid multibyte character */
|
||||
}
|
||||
else
|
||||
{
|
||||
/* incomplete multibyte character */
|
||||
*puc = 0xfffd;
|
||||
return -2;
|
||||
}
|
||||
}
|
||||
/* invalid multibyte character */
|
||||
}
|
||||
else
|
||||
{
|
||||
/* incomplete multibyte character */
|
||||
*puc = 0xfffd;
|
||||
return -2;
|
||||
}
|
||||
}
|
||||
else if (c < 0xf8)
|
||||
{
|
||||
if (n >= 2)
|
||||
{
|
||||
if ((s[1] ^ 0x80) < 0x40
|
||||
&& (c >= 0xf1 || s[1] >= 0x90)
|
||||
#if 1
|
||||
&& (c < 0xf4 || (c == 0xf4 && s[1] < 0x90))
|
||||
#endif
|
||||
)
|
||||
{
|
||||
if (n >= 3)
|
||||
{
|
||||
if ((s[2] ^ 0x80) < 0x40)
|
||||
{
|
||||
if (n >= 4)
|
||||
{
|
||||
if ((s[3] ^ 0x80) < 0x40)
|
||||
{
|
||||
*puc = ((unsigned int) (c & 0x07) << 18)
|
||||
| ((unsigned int) (s[1] ^ 0x80) << 12)
|
||||
| ((unsigned int) (s[2] ^ 0x80) << 6)
|
||||
| (unsigned int) (s[3] ^ 0x80);
|
||||
return 4;
|
||||
}
|
||||
/* invalid multibyte character */
|
||||
}
|
||||
else
|
||||
{
|
||||
/* incomplete multibyte character */
|
||||
*puc = 0xfffd;
|
||||
return -2;
|
||||
}
|
||||
}
|
||||
/* invalid multibyte character */
|
||||
}
|
||||
else
|
||||
{
|
||||
/* incomplete multibyte character */
|
||||
*puc = 0xfffd;
|
||||
return -2;
|
||||
}
|
||||
}
|
||||
/* invalid multibyte character */
|
||||
}
|
||||
else
|
||||
{
|
||||
/* incomplete multibyte character */
|
||||
*puc = 0xfffd;
|
||||
return -2;
|
||||
}
|
||||
}
|
||||
#if 0
|
||||
else if (c < 0xfc)
|
||||
{
|
||||
if (n >= 2)
|
||||
{
|
||||
if ((s[1] ^ 0x80) < 0x40
|
||||
&& (c >= 0xf9 || s[1] >= 0x88))
|
||||
{
|
||||
if (n >= 3)
|
||||
{
|
||||
if ((s[2] ^ 0x80) < 0x40)
|
||||
{
|
||||
if (n >= 4)
|
||||
{
|
||||
if ((s[3] ^ 0x80) < 0x40)
|
||||
{
|
||||
if (n >= 5)
|
||||
{
|
||||
if ((s[4] ^ 0x80) < 0x40)
|
||||
{
|
||||
*puc = ((unsigned int) (c & 0x03) << 24)
|
||||
| ((unsigned int) (s[1] ^ 0x80) << 18)
|
||||
| ((unsigned int) (s[2] ^ 0x80) << 12)
|
||||
| ((unsigned int) (s[3] ^ 0x80) << 6)
|
||||
| (unsigned int) (s[4] ^ 0x80);
|
||||
return 5;
|
||||
}
|
||||
/* invalid multibyte character */
|
||||
}
|
||||
else
|
||||
{
|
||||
/* incomplete multibyte character */
|
||||
*puc = 0xfffd;
|
||||
return -2;
|
||||
}
|
||||
}
|
||||
/* invalid multibyte character */
|
||||
}
|
||||
else
|
||||
{
|
||||
/* incomplete multibyte character */
|
||||
*puc = 0xfffd;
|
||||
return -2;
|
||||
}
|
||||
}
|
||||
/* invalid multibyte character */
|
||||
}
|
||||
else
|
||||
{
|
||||
/* incomplete multibyte character */
|
||||
*puc = 0xfffd;
|
||||
return -2;
|
||||
}
|
||||
}
|
||||
/* invalid multibyte character */
|
||||
}
|
||||
else
|
||||
{
|
||||
/* incomplete multibyte character */
|
||||
*puc = 0xfffd;
|
||||
return -2;
|
||||
}
|
||||
}
|
||||
else if (c < 0xfe)
|
||||
{
|
||||
if (n >= 2)
|
||||
{
|
||||
if ((s[1] ^ 0x80) < 0x40
|
||||
&& (c >= 0xfd || s[1] >= 0x84))
|
||||
{
|
||||
if (n >= 3)
|
||||
{
|
||||
if ((s[2] ^ 0x80) < 0x40)
|
||||
{
|
||||
if (n >= 4)
|
||||
{
|
||||
if ((s[3] ^ 0x80) < 0x40)
|
||||
{
|
||||
if (n >= 5)
|
||||
{
|
||||
if ((s[4] ^ 0x80) < 0x40)
|
||||
{
|
||||
if (n >= 6)
|
||||
{
|
||||
if ((s[5] ^ 0x80) < 0x40)
|
||||
{
|
||||
*puc = ((unsigned int) (c & 0x01) << 30)
|
||||
| ((unsigned int) (s[1] ^ 0x80) << 24)
|
||||
| ((unsigned int) (s[2] ^ 0x80) << 18)
|
||||
| ((unsigned int) (s[3] ^ 0x80) << 12)
|
||||
| ((unsigned int) (s[4] ^ 0x80) << 6)
|
||||
| (unsigned int) (s[5] ^ 0x80);
|
||||
return 6;
|
||||
}
|
||||
/* invalid multibyte character */
|
||||
}
|
||||
else
|
||||
{
|
||||
/* incomplete multibyte character */
|
||||
*puc = 0xfffd;
|
||||
return -2;
|
||||
}
|
||||
}
|
||||
/* invalid multibyte character */
|
||||
}
|
||||
else
|
||||
{
|
||||
/* incomplete multibyte character */
|
||||
*puc = 0xfffd;
|
||||
return -2;
|
||||
}
|
||||
}
|
||||
/* invalid multibyte character */
|
||||
}
|
||||
else
|
||||
{
|
||||
/* incomplete multibyte character */
|
||||
*puc = 0xfffd;
|
||||
return -2;
|
||||
}
|
||||
}
|
||||
/* invalid multibyte character */
|
||||
}
|
||||
else
|
||||
{
|
||||
/* incomplete multibyte character */
|
||||
*puc = 0xfffd;
|
||||
return -2;
|
||||
}
|
||||
}
|
||||
/* invalid multibyte character */
|
||||
}
|
||||
else
|
||||
{
|
||||
/* incomplete multibyte character */
|
||||
*puc = 0xfffd;
|
||||
return -2;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
/* invalid multibyte character */
|
||||
*puc = 0xfffd;
|
||||
return -1;
|
||||
}
|
93
lib/unistr/u8-prev.c
Normal file
93
lib/unistr/u8-prev.c
Normal file
|
@ -0,0 +1,93 @@
|
|||
/* Iterate over previous character in UTF-8 string.
|
||||
Copyright (C) 2002, 2006-2007 Free Software Foundation, Inc.
|
||||
Written by Bruno Haible <bruno@clisp.org>, 2002.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU Lesser General Public License as published
|
||||
by the Free Software Foundation; either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
/* Specification. */
|
||||
#include "unistr.h"
|
||||
|
||||
const uint8_t *
|
||||
u8_prev (ucs4_t *puc, const uint8_t *s, const uint8_t *start)
|
||||
{
|
||||
/* Keep in sync with unistr.h and utf8-ucs4.c. */
|
||||
if (s != start)
|
||||
{
|
||||
uint8_t c_1 = s[-1];
|
||||
|
||||
if (c_1 < 0x80)
|
||||
{
|
||||
*puc = c_1;
|
||||
return s - 1;
|
||||
}
|
||||
#if CONFIG_UNICODE_SAFETY
|
||||
if ((c_1 ^ 0x80) < 0x40)
|
||||
#endif
|
||||
if (s - 1 != start)
|
||||
{
|
||||
uint8_t c_2 = s[-2];
|
||||
|
||||
if (c_2 >= 0xc2 && c_2 < 0xe0)
|
||||
{
|
||||
*puc = ((unsigned int) (c_2 & 0x1f) << 6)
|
||||
| (unsigned int) (c_1 ^ 0x80);
|
||||
return s - 2;
|
||||
}
|
||||
#if CONFIG_UNICODE_SAFETY
|
||||
if ((c_2 ^ 0x80) < 0x40)
|
||||
#endif
|
||||
if (s - 2 != start)
|
||||
{
|
||||
uint8_t c_3 = s[-3];
|
||||
|
||||
if (c_3 >= 0xe0 && c_3 < 0xf0
|
||||
#if CONFIG_UNICODE_SAFETY
|
||||
&& (c_3 >= 0xe1 || c_2 >= 0xa0)
|
||||
&& (c_3 != 0xed || c_2 < 0xa0)
|
||||
#endif
|
||||
)
|
||||
{
|
||||
*puc = ((unsigned int) (c_3 & 0x0f) << 12)
|
||||
| ((unsigned int) (c_2 ^ 0x80) << 6)
|
||||
| (unsigned int) (c_1 ^ 0x80);
|
||||
return s - 3;
|
||||
}
|
||||
#if CONFIG_UNICODE_SAFETY
|
||||
if ((c_3 ^ 0x80) < 0x40)
|
||||
#endif
|
||||
if (s - 3 != start)
|
||||
{
|
||||
uint8_t c_4 = s[-4];
|
||||
|
||||
if (c_4 >= 0xf0 && c_4 < 0xf8
|
||||
#if CONFIG_UNICODE_SAFETY
|
||||
&& (c_4 >= 0xf1 || c_3 >= 0x90)
|
||||
&& (c_4 < 0xf4 || (c_4 == 0xf4 && c_3 < 0x90))
|
||||
#endif
|
||||
)
|
||||
{
|
||||
*puc = ((unsigned int) (c_4 & 0x07) << 18)
|
||||
| ((unsigned int) (c_3 ^ 0x80) << 12)
|
||||
| ((unsigned int) (c_2 ^ 0x80) << 6)
|
||||
| (unsigned int) (c_1 ^ 0x80);
|
||||
return s - 4;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
69
lib/unistr/u8-uctomb-aux.c
Normal file
69
lib/unistr/u8-uctomb-aux.c
Normal file
|
@ -0,0 +1,69 @@
|
|||
/* Conversion UCS-4 to UTF-8.
|
||||
Copyright (C) 2002, 2006-2007 Free Software Foundation, Inc.
|
||||
Written by Bruno Haible <bruno@clisp.org>, 2002.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU Lesser General Public License as published
|
||||
by the Free Software Foundation; either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
/* Specification. */
|
||||
#include "unistr.h"
|
||||
|
||||
int
|
||||
u8_uctomb_aux (uint8_t *s, ucs4_t uc, int n)
|
||||
{
|
||||
int count;
|
||||
|
||||
if (uc < 0x80)
|
||||
/* The case n >= 1 is already handled by the caller. */
|
||||
return -2;
|
||||
else if (uc < 0x800)
|
||||
count = 2;
|
||||
else if (uc < 0x10000)
|
||||
{
|
||||
if (uc < 0xd800 || uc >= 0xe000)
|
||||
count = 3;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
#if 0
|
||||
else if (uc < 0x200000)
|
||||
count = 4;
|
||||
else if (uc < 0x4000000)
|
||||
count = 5;
|
||||
else if (uc <= 0x7fffffff)
|
||||
count = 6;
|
||||
#else
|
||||
else if (uc < 0x110000)
|
||||
count = 4;
|
||||
#endif
|
||||
else
|
||||
return -1;
|
||||
|
||||
if (n < count)
|
||||
return -2;
|
||||
|
||||
switch (count) /* note: code falls through cases! */
|
||||
{
|
||||
#if 0
|
||||
case 6: s[5] = 0x80 | (uc & 0x3f); uc = uc >> 6; uc |= 0x4000000;
|
||||
case 5: s[4] = 0x80 | (uc & 0x3f); uc = uc >> 6; uc |= 0x200000;
|
||||
#endif
|
||||
case 4: s[3] = 0x80 | (uc & 0x3f); uc = uc >> 6; uc |= 0x10000;
|
||||
case 3: s[2] = 0x80 | (uc & 0x3f); uc = uc >> 6; uc |= 0x800;
|
||||
case 2: s[1] = 0x80 | (uc & 0x3f); uc = uc >> 6; uc |= 0xc0;
|
||||
/*case 1:*/ s[0] = uc;
|
||||
}
|
||||
return count;
|
||||
}
|
88
lib/unistr/u8-uctomb.c
Normal file
88
lib/unistr/u8-uctomb.c
Normal file
|
@ -0,0 +1,88 @@
|
|||
/* Store a character in UTF-8 string.
|
||||
Copyright (C) 2002, 2005-2006, 2009 Free Software Foundation, Inc.
|
||||
Written by Bruno Haible <bruno@clisp.org>, 2002.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU Lesser General Public License as published
|
||||
by the Free Software Foundation; either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#if defined IN_LIBUNISTRING
|
||||
/* Tell unistr.h to declare u8_uctomb as 'extern', not 'static inline'. */
|
||||
# include "unistring-notinline.h"
|
||||
#endif
|
||||
|
||||
/* Specification. */
|
||||
#include "unistr.h"
|
||||
|
||||
#if !HAVE_INLINE
|
||||
|
||||
int
|
||||
u8_uctomb (uint8_t *s, ucs4_t uc, int n)
|
||||
{
|
||||
if (uc < 0x80)
|
||||
{
|
||||
if (n > 0)
|
||||
{
|
||||
s[0] = uc;
|
||||
return 1;
|
||||
}
|
||||
/* else return -2, below. */
|
||||
}
|
||||
else
|
||||
{
|
||||
int count;
|
||||
|
||||
if (uc < 0x800)
|
||||
count = 2;
|
||||
else if (uc < 0x10000)
|
||||
{
|
||||
if (uc < 0xd800 || uc >= 0xe000)
|
||||
count = 3;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
#if 0
|
||||
else if (uc < 0x200000)
|
||||
count = 4;
|
||||
else if (uc < 0x4000000)
|
||||
count = 5;
|
||||
else if (uc <= 0x7fffffff)
|
||||
count = 6;
|
||||
#else
|
||||
else if (uc < 0x110000)
|
||||
count = 4;
|
||||
#endif
|
||||
else
|
||||
return -1;
|
||||
|
||||
if (n >= count)
|
||||
{
|
||||
switch (count) /* note: code falls through cases! */
|
||||
{
|
||||
#if 0
|
||||
case 6: s[5] = 0x80 | (uc & 0x3f); uc = uc >> 6; uc |= 0x4000000;
|
||||
case 5: s[4] = 0x80 | (uc & 0x3f); uc = uc >> 6; uc |= 0x200000;
|
||||
#endif
|
||||
case 4: s[3] = 0x80 | (uc & 0x3f); uc = uc >> 6; uc |= 0x10000;
|
||||
case 3: s[2] = 0x80 | (uc & 0x3f); uc = uc >> 6; uc |= 0x800;
|
||||
case 2: s[1] = 0x80 | (uc & 0x3f); uc = uc >> 6; uc |= 0xc0;
|
||||
/*case 1:*/ s[0] = uc;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
}
|
||||
return -2;
|
||||
}
|
||||
|
||||
#endif
|
26
lib/unitypes.h
Normal file
26
lib/unitypes.h
Normal file
|
@ -0,0 +1,26 @@
|
|||
/* Elementary types for the GNU UniString library.
|
||||
Copyright (C) 2002, 2005-2006 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU Lesser General Public License as published
|
||||
by the Free Software Foundation; either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef _UNITYPES_H
|
||||
#define _UNITYPES_H
|
||||
|
||||
/* Get uint8_t, uint16_t, uint32_t. */
|
||||
#include <stdint.h>
|
||||
|
||||
/* Type representing a Unicode character. */
|
||||
typedef uint32_t ucs4_t;
|
||||
|
||||
#endif /* _UNITYPES_H */
|
|
@ -1,7 +1,7 @@
|
|||
#ifndef SCM_LIBGUILE_H
|
||||
#define SCM_LIBGUILE_H
|
||||
|
||||
/* Copyright (C) 1995,1996,1997,1998,2000,2001, 2002, 2003, 2004, 2006, 2008 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 1995,1996,1997,1998,2000,2001, 2002, 2003, 2004, 2006, 2008, 2009 Free Software Foundation, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
|
@ -32,6 +32,7 @@ extern "C" {
|
|||
#include "libguile/arbiters.h"
|
||||
#include "libguile/async.h"
|
||||
#include "libguile/boolean.h"
|
||||
#include "libguile/bytevectors.h"
|
||||
#include "libguile/chars.h"
|
||||
#include "libguile/continuations.h"
|
||||
#include "libguile/dynl.h"
|
||||
|
@ -75,6 +76,7 @@ extern "C" {
|
|||
#include "libguile/procprop.h"
|
||||
#include "libguile/properties.h"
|
||||
#include "libguile/procs.h"
|
||||
#include "libguile/r6rs-ports.h"
|
||||
#include "libguile/ramap.h"
|
||||
#include "libguile/random.h"
|
||||
#include "libguile/read.h"
|
||||
|
|
|
@ -32,10 +32,10 @@ DEFAULT_INCLUDES =
|
|||
## Check for headers in $(srcdir)/.., so that #include
|
||||
## <libguile/MUMBLE.h> will find MUMBLE.h in this dir when we're
|
||||
## building. Also look for Gnulib headers in `lib'.
|
||||
AM_CPPFLAGS = -I$(top_srcdir) -I$(top_builddir) \
|
||||
AM_CPPFLAGS = -DBUILDING_LIBGUILE=1 -I$(top_srcdir) -I$(top_builddir) \
|
||||
-I$(top_srcdir)/lib -I$(top_builddir)/lib
|
||||
|
||||
AM_CFLAGS = $(GCC_CFLAGS)
|
||||
AM_CFLAGS = $(GCC_CFLAGS) $(CFLAG_VISIBILITY)
|
||||
|
||||
## The Gnulib Libtool archive.
|
||||
gnulib_library = $(top_builddir)/lib/libgnu.la
|
||||
|
@ -106,7 +106,8 @@ guile_LDFLAGS = $(GUILE_CFLAGS)
|
|||
libguile_la_CFLAGS = $(GUILE_CFLAGS) $(AM_CFLAGS)
|
||||
|
||||
libguile_la_SOURCES = alist.c arbiters.c async.c backtrace.c boolean.c \
|
||||
chars.c continuations.c convert.c debug.c deprecation.c \
|
||||
bytevectors.c chars.c continuations.c \
|
||||
convert.c debug.c deprecation.c \
|
||||
deprecated.c discouraged.c dynwind.c eq.c error.c \
|
||||
eval.c evalext.c extensions.c feature.c fluids.c fports.c \
|
||||
futures.c gc.c gc-mark.c gc-segment.c gc-malloc.c gc-card.c \
|
||||
|
@ -115,7 +116,8 @@ libguile_la_SOURCES = alist.c arbiters.c async.c backtrace.c boolean.c \
|
|||
guardians.c hash.c hashtab.c hooks.c init.c inline.c \
|
||||
ioext.c keywords.c lang.c list.c load.c macros.c mallocs.c \
|
||||
modules.c numbers.c objects.c objprop.c options.c pairs.c ports.c \
|
||||
print.c procprop.c procs.c properties.c random.c rdelim.c read.c \
|
||||
print.c procprop.c procs.c properties.c \
|
||||
r6rs-ports.c random.c rdelim.c read.c \
|
||||
root.c rw.c scmsigs.c script.c simpos.c smob.c sort.c srcprop.c \
|
||||
stackchk.c stacks.c stime.c strings.c srfi-4.c srfi-13.c srfi-14.c \
|
||||
strorder.c strports.c struct.c symbols.c threads.c null-threads.c \
|
||||
|
@ -134,7 +136,8 @@ libguile_i18n_v_@LIBGUILE_I18N_MAJOR@_la_LDFLAGS = \
|
|||
-module -L$(builddir) -lguile \
|
||||
-version-info @LIBGUILE_I18N_INTERFACE@
|
||||
|
||||
DOT_X_FILES = alist.x arbiters.x async.x backtrace.x boolean.x chars.x \
|
||||
DOT_X_FILES = alist.x arbiters.x async.x backtrace.x boolean.x \
|
||||
bytevectors.x chars.x \
|
||||
continuations.x debug.x deprecation.x deprecated.x discouraged.x \
|
||||
dynl.x dynwind.x eq.x error.x eval.x evalext.x \
|
||||
extensions.x feature.x fluids.x fports.x futures.x gc.x gc-mark.x \
|
||||
|
@ -143,7 +146,8 @@ DOT_X_FILES = alist.x arbiters.x async.x backtrace.x boolean.x chars.x \
|
|||
hash.x hashtab.x hooks.x i18n.x init.x ioext.x keywords.x lang.x \
|
||||
list.x load.x macros.x mallocs.x modules.x numbers.x objects.x \
|
||||
objprop.x options.x pairs.x ports.x print.x procprop.x procs.x \
|
||||
properties.x random.x rdelim.x read.x root.x rw.x scmsigs.x \
|
||||
properties.x r6rs-ports.x random.x rdelim.x \
|
||||
read.x root.x rw.x scmsigs.x \
|
||||
script.x simpos.x smob.x sort.x srcprop.x stackchk.x stacks.x \
|
||||
stime.x strings.x srfi-4.x srfi-13.x srfi-14.x strorder.x \
|
||||
strports.x struct.x symbols.x threads.x throw.x values.x \
|
||||
|
@ -155,7 +159,8 @@ DOT_X_FILES += frames.x instructions.x objcodes.x programs.x vm.x
|
|||
EXTRA_DOT_X_FILES = @EXTRA_DOT_X_FILES@
|
||||
|
||||
DOT_DOC_FILES = alist.doc arbiters.doc async.doc backtrace.doc \
|
||||
boolean.doc chars.doc continuations.doc debug.doc deprecation.doc \
|
||||
boolean.doc bytevectors.doc chars.doc \
|
||||
continuations.doc debug.doc deprecation.doc \
|
||||
deprecated.doc discouraged.doc dynl.doc dynwind.doc \
|
||||
eq.doc error.doc eval.doc evalext.doc \
|
||||
extensions.doc feature.doc fluids.doc fports.doc futures.doc \
|
||||
|
@ -165,7 +170,8 @@ DOT_DOC_FILES = alist.doc arbiters.doc async.doc backtrace.doc \
|
|||
hooks.doc i18n.doc init.doc ioext.doc keywords.doc lang.doc \
|
||||
list.doc load.doc macros.doc mallocs.doc modules.doc numbers.doc \
|
||||
objects.doc objprop.doc options.doc pairs.doc ports.doc print.doc \
|
||||
procprop.doc procs.doc properties.doc random.doc rdelim.doc \
|
||||
procprop.doc procs.doc properties.doc r6rs-ports.doc \
|
||||
random.doc rdelim.doc \
|
||||
read.doc root.doc rw.doc scmsigs.doc script.doc simpos.doc \
|
||||
smob.doc sort.doc srcprop.doc stackchk.doc stacks.doc stime.doc \
|
||||
strings.doc srfi-4.doc srfi-13.doc srfi-14.doc strorder.doc \
|
||||
|
@ -204,7 +210,7 @@ install-exec-hook:
|
|||
## working.
|
||||
noinst_HEADERS = convert.i.c \
|
||||
conv-integer.i.c conv-uinteger.i.c \
|
||||
eval.i.c \
|
||||
eval.i.c ieee-754.h \
|
||||
srfi-4.i.c \
|
||||
quicksort.i.c \
|
||||
win32-uname.h win32-dirent.h win32-socket.h \
|
||||
|
@ -223,7 +229,8 @@ pkginclude_HEADERS =
|
|||
# These are headers visible as <libguile/mumble.h>.
|
||||
modincludedir = $(includedir)/libguile
|
||||
modinclude_HEADERS = __scm.h alist.h arbiters.h async.h backtrace.h \
|
||||
boolean.h chars.h continuations.h convert.h debug.h debug-malloc.h \
|
||||
boolean.h bytevectors.h chars.h continuations.h convert.h \
|
||||
debug.h debug-malloc.h \
|
||||
deprecation.h deprecated.h discouraged.h dynl.h dynwind.h \
|
||||
eq.h error.h eval.h evalext.h extensions.h \
|
||||
feature.h filesys.h fluids.h fports.h futures.h gc.h \
|
||||
|
@ -232,7 +239,8 @@ modinclude_HEADERS = __scm.h alist.h arbiters.h async.h backtrace.h \
|
|||
hashtab.h hooks.h i18n.h init.h inline.h ioext.h iselect.h \
|
||||
keywords.h lang.h list.h load.h macros.h mallocs.h modules.h \
|
||||
net_db.h numbers.h objects.h objprop.h options.h pairs.h ports.h \
|
||||
posix.h regex-posix.h print.h procprop.h procs.h properties.h \
|
||||
posix.h r6rs-ports.h regex-posix.h print.h \
|
||||
procprop.h procs.h properties.h \
|
||||
random.h ramap.h rdelim.h read.h root.h rw.h scmsigs.h validate.h \
|
||||
script.h simpos.h smob.h snarf.h socket.h sort.h srcprop.h \
|
||||
stackchk.h stacks.h stime.h strings.h srfi-4.h srfi-13.h srfi-14.h \
|
||||
|
|
|
@ -98,13 +98,10 @@
|
|||
#define SCM_UNLIKELY(_expr) SCM_EXPECT ((_expr), 0)
|
||||
|
||||
/* The SCM_INTERNAL macro makes it possible to explicitly declare a function
|
||||
* as having "internal" linkage. */
|
||||
#if (defined __GNUC__) && \
|
||||
((__GNUC__ >= 4) || (__GNUC__ == 3 && __GNUC_MINOR__ == 3))
|
||||
# define SCM_INTERNAL extern __attribute__ ((__visibility__ ("internal")))
|
||||
#else
|
||||
# define SCM_INTERNAL extern
|
||||
#endif
|
||||
* as having "internal" linkage. However our current tack on this problem is
|
||||
* to use GCC 4's -fvisibility=hidden, making functions internal by default,
|
||||
* and then SCM_API marks them for export. */
|
||||
#define SCM_INTERNAL extern
|
||||
|
||||
|
||||
|
||||
|
@ -154,13 +151,14 @@
|
|||
|
||||
|
||||
/* SCM_API is a macro prepended to all function and data definitions
|
||||
which should be exported or imported in the resulting dynamic link
|
||||
library (DLL) in the Win32 port. */
|
||||
which should be exported from libguile. */
|
||||
|
||||
#if defined (SCM_IMPORT)
|
||||
# define SCM_API __declspec (dllimport) extern
|
||||
#elif defined (SCM_EXPORT) || defined (DLL_EXPORT)
|
||||
# define SCM_API __declspec (dllexport) extern
|
||||
#if BUILDING_LIBGUILE && HAVE_VISIBILITY
|
||||
# define SCM_API extern __attribute__((__visibility__("default")))
|
||||
#elif BUILDING_LIBGUILE && defined _MSC_VER
|
||||
# define SCM_API __declspec(dllexport) extern
|
||||
#elif defined _MSC_VER
|
||||
# define SCM_API __declspec(dllimport) extern
|
||||
#else
|
||||
# define SCM_API extern
|
||||
#endif
|
||||
|
|
1978
libguile/bytevectors.c
Normal file
1978
libguile/bytevectors.c
Normal file
File diff suppressed because it is too large
Load diff
133
libguile/bytevectors.h
Normal file
133
libguile/bytevectors.h
Normal file
|
@ -0,0 +1,133 @@
|
|||
#ifndef SCM_BYTEVECTORS_H
|
||||
#define SCM_BYTEVECTORS_H
|
||||
|
||||
/* Copyright (C) 2009 Free Software Foundation, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#include "libguile/__scm.h"
|
||||
|
||||
|
||||
/* R6RS bytevectors. */
|
||||
|
||||
#define SCM_BYTEVECTOR_LENGTH(_bv) \
|
||||
((unsigned) SCM_SMOB_DATA (_bv))
|
||||
#define SCM_BYTEVECTOR_CONTENTS(_bv) \
|
||||
(SCM_BYTEVECTOR_INLINE_P (_bv) \
|
||||
? (signed char *) SCM_SMOB_OBJECT_2_LOC (_bv) \
|
||||
: (signed char *) SCM_SMOB_DATA_2 (_bv))
|
||||
|
||||
|
||||
SCM_API SCM scm_endianness_big;
|
||||
SCM_API SCM scm_endianness_little;
|
||||
|
||||
SCM_API SCM scm_make_bytevector (SCM, SCM);
|
||||
SCM_API SCM scm_c_make_bytevector (unsigned);
|
||||
SCM_API SCM scm_native_endianness (void);
|
||||
SCM_API SCM scm_bytevector_p (SCM);
|
||||
SCM_API SCM scm_bytevector_length (SCM);
|
||||
SCM_API SCM scm_bytevector_eq_p (SCM, SCM);
|
||||
SCM_API SCM scm_bytevector_fill_x (SCM, SCM);
|
||||
SCM_API SCM scm_bytevector_copy_x (SCM, SCM, SCM, SCM, SCM);
|
||||
SCM_API SCM scm_bytevector_copy (SCM);
|
||||
|
||||
SCM_API SCM scm_bytevector_to_u8_list (SCM);
|
||||
SCM_API SCM scm_u8_list_to_bytevector (SCM);
|
||||
SCM_API SCM scm_uint_list_to_bytevector (SCM, SCM, SCM);
|
||||
SCM_API SCM scm_bytevector_to_uint_list (SCM, SCM, SCM);
|
||||
SCM_API SCM scm_sint_list_to_bytevector (SCM, SCM, SCM);
|
||||
SCM_API SCM scm_bytevector_to_sint_list (SCM, SCM, SCM);
|
||||
|
||||
SCM_API SCM scm_bytevector_u16_native_ref (SCM, SCM);
|
||||
SCM_API SCM scm_bytevector_s16_native_ref (SCM, SCM);
|
||||
SCM_API SCM scm_bytevector_u32_native_ref (SCM, SCM);
|
||||
SCM_API SCM scm_bytevector_s32_native_ref (SCM, SCM);
|
||||
SCM_API SCM scm_bytevector_u64_native_ref (SCM, SCM);
|
||||
SCM_API SCM scm_bytevector_s64_native_ref (SCM, SCM);
|
||||
SCM_API SCM scm_bytevector_u8_ref (SCM, SCM);
|
||||
SCM_API SCM scm_bytevector_s8_ref (SCM, SCM);
|
||||
SCM_API SCM scm_bytevector_uint_ref (SCM, SCM, SCM, SCM);
|
||||
SCM_API SCM scm_bytevector_sint_ref (SCM, SCM, SCM, SCM);
|
||||
SCM_API SCM scm_bytevector_u16_ref (SCM, SCM, SCM);
|
||||
SCM_API SCM scm_bytevector_s16_ref (SCM, SCM, SCM);
|
||||
SCM_API SCM scm_bytevector_u32_ref (SCM, SCM, SCM);
|
||||
SCM_API SCM scm_bytevector_s32_ref (SCM, SCM, SCM);
|
||||
SCM_API SCM scm_bytevector_u64_ref (SCM, SCM, SCM);
|
||||
SCM_API SCM scm_bytevector_s64_ref (SCM, SCM, SCM);
|
||||
SCM_API SCM scm_bytevector_u16_native_set_x (SCM, SCM, SCM);
|
||||
SCM_API SCM scm_bytevector_s16_native_set_x (SCM, SCM, SCM);
|
||||
SCM_API SCM scm_bytevector_u32_native_set_x (SCM, SCM, SCM);
|
||||
SCM_API SCM scm_bytevector_s32_native_set_x (SCM, SCM, SCM);
|
||||
SCM_API SCM scm_bytevector_u64_native_set_x (SCM, SCM, SCM);
|
||||
SCM_API SCM scm_bytevector_s64_native_set_x (SCM, SCM, SCM);
|
||||
SCM_API SCM scm_bytevector_u8_set_x (SCM, SCM, SCM);
|
||||
SCM_API SCM scm_bytevector_s8_set_x (SCM, SCM, SCM);
|
||||
SCM_API SCM scm_bytevector_uint_set_x (SCM, SCM, SCM, SCM, SCM);
|
||||
SCM_API SCM scm_bytevector_sint_set_x (SCM, SCM, SCM, SCM, SCM);
|
||||
SCM_API SCM scm_bytevector_u16_set_x (SCM, SCM, SCM, SCM);
|
||||
SCM_API SCM scm_bytevector_s16_set_x (SCM, SCM, SCM, SCM);
|
||||
SCM_API SCM scm_bytevector_u32_set_x (SCM, SCM, SCM, SCM);
|
||||
SCM_API SCM scm_bytevector_s32_set_x (SCM, SCM, SCM, SCM);
|
||||
SCM_API SCM scm_bytevector_u64_set_x (SCM, SCM, SCM, SCM);
|
||||
SCM_API SCM scm_bytevector_s64_set_x (SCM, SCM, SCM, SCM);
|
||||
SCM_API SCM scm_bytevector_ieee_single_ref (SCM, SCM, SCM);
|
||||
SCM_API SCM scm_bytevector_ieee_single_native_ref (SCM, SCM);
|
||||
SCM_API SCM scm_bytevector_ieee_single_set_x (SCM, SCM, SCM, SCM);
|
||||
SCM_API SCM scm_bytevector_ieee_single_native_set_x (SCM, SCM, SCM);
|
||||
SCM_API SCM scm_bytevector_ieee_double_ref (SCM, SCM, SCM);
|
||||
SCM_API SCM scm_bytevector_ieee_double_native_ref (SCM, SCM);
|
||||
SCM_API SCM scm_bytevector_ieee_double_set_x (SCM, SCM, SCM, SCM);
|
||||
SCM_API SCM scm_bytevector_ieee_double_native_set_x (SCM, SCM, SCM);
|
||||
SCM_API SCM scm_string_to_utf8 (SCM);
|
||||
SCM_API SCM scm_string_to_utf16 (SCM, SCM);
|
||||
SCM_API SCM scm_string_to_utf32 (SCM, SCM);
|
||||
SCM_API SCM scm_utf8_to_string (SCM);
|
||||
SCM_API SCM scm_utf16_to_string (SCM, SCM);
|
||||
SCM_API SCM scm_utf32_to_string (SCM, SCM);
|
||||
|
||||
|
||||
|
||||
/* Internal API. */
|
||||
|
||||
/* The threshold (in octets) under which bytevectors are stored "in-line",
|
||||
i.e., without allocating memory beside the SMOB itself (a double cell).
|
||||
This optimization is necessary since small bytevectors are expected to be
|
||||
common. */
|
||||
#define SCM_BYTEVECTOR_INLINE_THRESHOLD (2 * sizeof (SCM))
|
||||
#define SCM_BYTEVECTOR_INLINEABLE_SIZE_P(_size) \
|
||||
((_size) <= SCM_BYTEVECTOR_INLINE_THRESHOLD)
|
||||
#define SCM_BYTEVECTOR_INLINE_P(_bv) \
|
||||
(SCM_BYTEVECTOR_INLINEABLE_SIZE_P (SCM_BYTEVECTOR_LENGTH (_bv)))
|
||||
|
||||
/* Hint that is passed to `scm_gc_malloc ()' and friends. */
|
||||
#define SCM_GC_BYTEVECTOR "bytevector"
|
||||
|
||||
SCM_API void scm_init_bytevectors (void);
|
||||
|
||||
SCM_INTERNAL scm_t_bits scm_tc16_bytevector;
|
||||
SCM_INTERNAL SCM scm_c_take_bytevector (signed char *, unsigned);
|
||||
|
||||
#define scm_c_shrink_bytevector(_bv, _len) \
|
||||
(SCM_BYTEVECTOR_INLINE_P (_bv) \
|
||||
? (_bv) \
|
||||
: scm_i_shrink_bytevector ((_bv), (_len)))
|
||||
|
||||
SCM_INTERNAL SCM scm_i_shrink_bytevector (SCM, unsigned);
|
||||
SCM_INTERNAL SCM scm_null_bytevector;
|
||||
|
||||
#endif /* SCM_BYTEVECTORS_H */
|
|
@ -2140,6 +2140,25 @@ unmemoize_at_call_with_values (const SCM expr, const SCM env)
|
|||
unmemoize_exprs (SCM_CDR (expr), env));
|
||||
}
|
||||
|
||||
SCM_SYNTAX (s_eval_when, "eval-when", scm_makmmacro, scm_m_eval_when);
|
||||
SCM_GLOBAL_SYMBOL (scm_sym_eval_when, s_eval_when);
|
||||
SCM_SYMBOL (sym_eval, "eval");
|
||||
SCM_SYMBOL (sym_load, "load");
|
||||
|
||||
|
||||
SCM
|
||||
scm_m_eval_when (SCM expr, SCM env SCM_UNUSED)
|
||||
{
|
||||
ASSERT_SYNTAX (scm_ilength (expr) >= 3, s_bad_expression, expr);
|
||||
ASSERT_SYNTAX (scm_ilength (scm_cadr (expr)) > 0, s_bad_expression, expr);
|
||||
|
||||
if (scm_is_true (scm_memq (sym_eval, scm_cadr (expr)))
|
||||
|| scm_is_true (scm_memq (sym_load, scm_cadr (expr))))
|
||||
return scm_cons (SCM_IM_BEGIN, scm_cddr (expr));
|
||||
|
||||
return scm_list_1 (SCM_IM_BEGIN);
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
||||
/* See futures.h for a comment why futures are not enabled.
|
||||
|
|
|
@ -100,6 +100,7 @@ SCM_API SCM scm_sym_atapply;
|
|||
SCM_API SCM scm_sym_atcall_cc;
|
||||
SCM_API SCM scm_sym_at_call_with_values;
|
||||
SCM_API SCM scm_sym_delay;
|
||||
SCM_API SCM scm_sym_eval_when;
|
||||
SCM_API SCM scm_sym_arrow;
|
||||
SCM_API SCM scm_sym_else;
|
||||
SCM_API SCM scm_sym_apply;
|
||||
|
@ -146,6 +147,7 @@ SCM_API SCM scm_m_atslot_ref (SCM xorig, SCM env);
|
|||
SCM_API SCM scm_m_atslot_set_x (SCM xorig, SCM env);
|
||||
SCM_API SCM scm_m_atdispatch (SCM xorig, SCM env);
|
||||
SCM_API SCM scm_m_at_call_with_values (SCM xorig, SCM env);
|
||||
SCM_API SCM scm_m_eval_when (SCM xorig, SCM env);
|
||||
SCM_API int scm_badargsp (SCM formals, SCM args);
|
||||
SCM_API SCM scm_call_0 (SCM proc);
|
||||
SCM_API SCM scm_call_1 (SCM proc, SCM arg1);
|
||||
|
|
|
@ -1,43 +1,19 @@
|
|||
/* Copyright (C) 2001 Free Software Foundation, Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this software; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
||||
* Boston, MA 02111-1307 USA
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* As a special exception, the Free Software Foundation gives permission
|
||||
* for additional uses of the text contained in its release of GUILE.
|
||||
*
|
||||
* The exception is that, if you link the GUILE library with other files
|
||||
* to produce an executable, this does not by itself cause the
|
||||
* resulting executable to be covered by the GNU General Public License.
|
||||
* Your use of that executable is in no way restricted on account of
|
||||
* linking the GUILE library code into it.
|
||||
*
|
||||
* This exception does not however invalidate any other reasons why
|
||||
* the executable file might be covered by the GNU General Public License.
|
||||
*
|
||||
* This exception applies only to the code released by the
|
||||
* Free Software Foundation under the name GUILE. If you copy
|
||||
* code from other Free Software Foundation releases into a copy of
|
||||
* GUILE, as the General Public License permits, the exception does
|
||||
* not apply to the code that you add in this way. To avoid misleading
|
||||
* anyone as to the status of such modified files, you must delete
|
||||
* this exception notice from them.
|
||||
*
|
||||
* If you write modifications of your own for GUILE, it is your choice
|
||||
* whether to permit this exception to apply to your modifications.
|
||||
* If you do not wish that, delete this exception notice. */
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#if HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
|
@ -45,6 +21,7 @@
|
|||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "_scm.h"
|
||||
#include "vm-bootstrap.h"
|
||||
#include "frames.h"
|
||||
|
||||
|
|
|
@ -1,43 +1,19 @@
|
|||
/* Copyright (C) 2001 Free Software Foundation, Inc.
|
||||
* *
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this software; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
||||
* Boston, MA 02111-1307 USA
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* As a special exception, the Free Software Foundation gives permission
|
||||
* for additional uses of the text contained in its release of GUILE.
|
||||
*
|
||||
* The exception is that, if you link the GUILE library with other files
|
||||
* to produce an executable, this does not by itself cause the
|
||||
* resulting executable to be covered by the GNU General Public License.
|
||||
* Your use of that executable is in no way restricted on account of
|
||||
* linking the GUILE library code into it.
|
||||
*
|
||||
* This exception does not however invalidate any other reasons why
|
||||
* the executable file might be covered by the GNU General Public License.
|
||||
*
|
||||
* This exception applies only to the code released by the
|
||||
* Free Software Foundation under the name GUILE. If you copy
|
||||
* code from other Free Software Foundation releases into a copy of
|
||||
* GUILE, as the General Public License permits, the exception does
|
||||
* not apply to the code that you add in this way. To avoid misleading
|
||||
* anyone as to the status of such modified files, you must delete
|
||||
* this exception notice from them.
|
||||
*
|
||||
* If you write modifications of your own for GUILE, it is your choice
|
||||
* whether to permit this exception to apply to your modifications.
|
||||
* If you do not wish that, delete this exception notice. */
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef _SCM_FRAMES_H_
|
||||
#define _SCM_FRAMES_H_
|
||||
|
@ -97,7 +73,7 @@
|
|||
* Heap frames
|
||||
*/
|
||||
|
||||
extern scm_t_bits scm_tc16_vm_frame;
|
||||
SCM_API scm_t_bits scm_tc16_vm_frame;
|
||||
|
||||
struct scm_vm_frame
|
||||
{
|
||||
|
@ -118,24 +94,24 @@ struct scm_vm_frame
|
|||
#define SCM_VALIDATE_VM_FRAME(p,x) SCM_MAKE_VALIDATE (p, x, VM_FRAME_P)
|
||||
|
||||
/* FIXME rename scm_byte_t */
|
||||
extern SCM scm_c_make_vm_frame (SCM stack_holder, SCM *fp, SCM *sp,
|
||||
SCM_API SCM scm_c_make_vm_frame (SCM stack_holder, SCM *fp, SCM *sp,
|
||||
scm_byte_t *ip, scm_t_ptrdiff offset);
|
||||
extern SCM scm_vm_frame_p (SCM obj);
|
||||
extern SCM scm_vm_frame_program (SCM frame);
|
||||
extern SCM scm_vm_frame_arguments (SCM frame);
|
||||
extern SCM scm_vm_frame_source (SCM frame);
|
||||
extern SCM scm_vm_frame_local_ref (SCM frame, SCM index);
|
||||
extern SCM scm_vm_frame_local_set_x (SCM frame, SCM index, SCM val);
|
||||
extern SCM scm_vm_frame_return_address (SCM frame);
|
||||
extern SCM scm_vm_frame_mv_return_address (SCM frame);
|
||||
extern SCM scm_vm_frame_dynamic_link (SCM frame);
|
||||
extern SCM scm_vm_frame_external_link (SCM frame);
|
||||
extern SCM scm_vm_frame_stack (SCM frame);
|
||||
SCM_API SCM scm_vm_frame_p (SCM obj);
|
||||
SCM_API SCM scm_vm_frame_program (SCM frame);
|
||||
SCM_API SCM scm_vm_frame_arguments (SCM frame);
|
||||
SCM_API SCM scm_vm_frame_source (SCM frame);
|
||||
SCM_API SCM scm_vm_frame_local_ref (SCM frame, SCM index);
|
||||
SCM_API SCM scm_vm_frame_local_set_x (SCM frame, SCM index, SCM val);
|
||||
SCM_API SCM scm_vm_frame_return_address (SCM frame);
|
||||
SCM_API SCM scm_vm_frame_mv_return_address (SCM frame);
|
||||
SCM_API SCM scm_vm_frame_dynamic_link (SCM frame);
|
||||
SCM_API SCM scm_vm_frame_external_link (SCM frame);
|
||||
SCM_API SCM scm_vm_frame_stack (SCM frame);
|
||||
|
||||
extern SCM scm_c_vm_frame_prev (SCM frame);
|
||||
SCM_API SCM scm_c_vm_frame_prev (SCM frame);
|
||||
|
||||
extern void scm_bootstrap_frames (void);
|
||||
extern void scm_init_frames (void);
|
||||
SCM_INTERNAL void scm_bootstrap_frames (void);
|
||||
SCM_INTERNAL void scm_init_frames (void);
|
||||
|
||||
#endif /* _SCM_FRAMES_H_ */
|
||||
|
||||
|
|
90
libguile/ieee-754.h
Normal file
90
libguile/ieee-754.h
Normal file
|
@ -0,0 +1,90 @@
|
|||
/* Copyright (C) 1992, 1995, 1996, 1999 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#ifndef SCM_IEEE_754_H
|
||||
#define SCM_IEEE_754_H 1
|
||||
|
||||
/* Based on glibc's <ieee754.h> and modified by Ludovic Courtès to include
|
||||
all possible IEEE-754 double-precision representations. */
|
||||
|
||||
|
||||
/* IEEE 754 simple-precision format (32-bit). */
|
||||
|
||||
union scm_ieee754_float
|
||||
{
|
||||
float f;
|
||||
|
||||
struct
|
||||
{
|
||||
unsigned int negative:1;
|
||||
unsigned int exponent:8;
|
||||
unsigned int mantissa:23;
|
||||
} big_endian;
|
||||
|
||||
struct
|
||||
{
|
||||
unsigned int mantissa:23;
|
||||
unsigned int exponent:8;
|
||||
unsigned int negative:1;
|
||||
} little_endian;
|
||||
};
|
||||
|
||||
|
||||
|
||||
/* IEEE 754 double-precision format (64-bit). */
|
||||
|
||||
union scm_ieee754_double
|
||||
{
|
||||
double d;
|
||||
|
||||
struct
|
||||
{
|
||||
/* Big endian. */
|
||||
|
||||
unsigned int negative:1;
|
||||
unsigned int exponent:11;
|
||||
/* Together these comprise the mantissa. */
|
||||
unsigned int mantissa0:20;
|
||||
unsigned int mantissa1:32;
|
||||
} big_endian;
|
||||
|
||||
struct
|
||||
{
|
||||
/* Both byte order and word order are little endian. */
|
||||
|
||||
/* Together these comprise the mantissa. */
|
||||
unsigned int mantissa1:32;
|
||||
unsigned int mantissa0:20;
|
||||
unsigned int exponent:11;
|
||||
unsigned int negative:1;
|
||||
} little_little_endian;
|
||||
|
||||
struct
|
||||
{
|
||||
/* Byte order is little endian but word order is big endian. Not
|
||||
sure this is very wide spread. */
|
||||
unsigned int mantissa0:20;
|
||||
unsigned int exponent:11;
|
||||
unsigned int negative:1;
|
||||
unsigned int mantissa1:32;
|
||||
} little_big_endian;
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif /* SCM_IEEE_754_H */
|
|
@ -1,49 +1,27 @@
|
|||
/* Copyright (C) 2001 Free Software Foundation, Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this software; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
||||
* Boston, MA 02111-1307 USA
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* As a special exception, the Free Software Foundation gives permission
|
||||
* for additional uses of the text contained in its release of GUILE.
|
||||
*
|
||||
* The exception is that, if you link the GUILE library with other files
|
||||
* to produce an executable, this does not by itself cause the
|
||||
* resulting executable to be covered by the GNU General Public License.
|
||||
* Your use of that executable is in no way restricted on account of
|
||||
* linking the GUILE library code into it.
|
||||
*
|
||||
* This exception does not however invalidate any other reasons why
|
||||
* the executable file might be covered by the GNU General Public License.
|
||||
*
|
||||
* This exception applies only to the code released by the
|
||||
* Free Software Foundation under the name GUILE. If you copy
|
||||
* code from other Free Software Foundation releases into a copy of
|
||||
* GUILE, as the General Public License permits, the exception does
|
||||
* not apply to the code that you add in this way. To avoid misleading
|
||||
* anyone as to the status of such modified files, you must delete
|
||||
* this exception notice from them.
|
||||
*
|
||||
* If you write modifications of your own for GUILE, it is your choice
|
||||
* whether to permit this exception to apply to your modifications.
|
||||
* If you do not wish that, delete this exception notice. */
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#if HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "_scm.h"
|
||||
#include "vm-bootstrap.h"
|
||||
#include "instructions.h"
|
||||
|
||||
|
|
|
@ -1,43 +1,19 @@
|
|||
/* Copyright (C) 2001 Free Software Foundation, Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this software; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
||||
* Boston, MA 02111-1307 USA
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* As a special exception, the Free Software Foundation gives permission
|
||||
* for additional uses of the text contained in its release of GUILE.
|
||||
*
|
||||
* The exception is that, if you link the GUILE library with other files
|
||||
* to produce an executable, this does not by itself cause the
|
||||
* resulting executable to be covered by the GNU General Public License.
|
||||
* Your use of that executable is in no way restricted on account of
|
||||
* linking the GUILE library code into it.
|
||||
*
|
||||
* This exception does not however invalidate any other reasons why
|
||||
* the executable file might be covered by the GNU General Public License.
|
||||
*
|
||||
* This exception applies only to the code released by the
|
||||
* Free Software Foundation under the name GUILE. If you copy
|
||||
* code from other Free Software Foundation releases into a copy of
|
||||
* GUILE, as the General Public License permits, the exception does
|
||||
* not apply to the code that you add in this way. To avoid misleading
|
||||
* anyone as to the status of such modified files, you must delete
|
||||
* this exception notice from them.
|
||||
*
|
||||
* If you write modifications of your own for GUILE, it is your choice
|
||||
* whether to permit this exception to apply to your modifications.
|
||||
* If you do not wish that, delete this exception notice. */
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef _SCM_INSTRUCTIONS_H_
|
||||
#define _SCM_INSTRUCTIONS_H_
|
||||
|
@ -57,16 +33,16 @@ enum scm_opcode {
|
|||
scm_op_last = SCM_VM_NUM_INSTRUCTIONS
|
||||
};
|
||||
|
||||
extern SCM scm_instruction_list (void);
|
||||
extern SCM scm_instruction_p (SCM obj);
|
||||
extern SCM scm_instruction_length (SCM inst);
|
||||
extern SCM scm_instruction_pops (SCM inst);
|
||||
extern SCM scm_instruction_pushes (SCM inst);
|
||||
extern SCM scm_instruction_to_opcode (SCM inst);
|
||||
extern SCM scm_opcode_to_instruction (SCM op);
|
||||
SCM_API SCM scm_instruction_list (void);
|
||||
SCM_API SCM scm_instruction_p (SCM obj);
|
||||
SCM_API SCM scm_instruction_length (SCM inst);
|
||||
SCM_API SCM scm_instruction_pops (SCM inst);
|
||||
SCM_API SCM scm_instruction_pushes (SCM inst);
|
||||
SCM_API SCM scm_instruction_to_opcode (SCM inst);
|
||||
SCM_API SCM scm_opcode_to_instruction (SCM op);
|
||||
|
||||
extern void scm_bootstrap_instructions (void);
|
||||
extern void scm_init_instructions (void);
|
||||
SCM_INTERNAL void scm_bootstrap_instructions (void);
|
||||
SCM_INTERNAL void scm_init_instructions (void);
|
||||
|
||||
#endif /* _SCM_INSTRUCTIONS_H_ */
|
||||
|
||||
|
|
|
@ -48,10 +48,13 @@ macro_print (SCM macro, SCM port, scm_print_state *pstate)
|
|||
|| scm_is_false (scm_printer_apply (SCM_PRINT_CLOSURE,
|
||||
macro, port, pstate)))
|
||||
{
|
||||
scm_puts ("#<", port);
|
||||
|
||||
if (SCM_MACRO_TYPE (macro) < 4 && SCM_MACRO_IS_EXTENDED (macro))
|
||||
scm_puts ("extended-", port);
|
||||
|
||||
if (!SCM_CLOSUREP (code) && !SCM_PROGRAM_P (code))
|
||||
scm_puts ("#<primitive-", port);
|
||||
else
|
||||
scm_puts ("#<", port);
|
||||
scm_puts ("primitive-", port);
|
||||
|
||||
if (SCM_MACRO_TYPE (macro) == 0)
|
||||
scm_puts ("syntax", port);
|
||||
|
@ -63,6 +66,8 @@ macro_print (SCM macro, SCM port, scm_print_state *pstate)
|
|||
scm_puts ("macro!", port);
|
||||
if (SCM_MACRO_TYPE (macro) == 3)
|
||||
scm_puts ("builtin-macro!", port);
|
||||
if (SCM_MACRO_TYPE (macro) == 4)
|
||||
scm_puts ("syncase-macro", port);
|
||||
|
||||
scm_putc (' ', port);
|
||||
scm_iprin1 (scm_macro_name (macro), port, pstate);
|
||||
|
@ -77,12 +82,30 @@ macro_print (SCM macro, SCM port, scm_print_state *pstate)
|
|||
scm_iprin1 (src, port, pstate);
|
||||
}
|
||||
|
||||
if (SCM_MACRO_IS_EXTENDED (macro))
|
||||
{
|
||||
scm_putc (' ', port);
|
||||
scm_write (SCM_SMOB_OBJECT_2 (macro), port);
|
||||
scm_putc (' ', port);
|
||||
scm_write (SCM_SMOB_OBJECT_3 (macro), port);
|
||||
}
|
||||
|
||||
scm_putc ('>', port);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static SCM
|
||||
macro_mark (SCM macro)
|
||||
{
|
||||
if (SCM_MACRO_IS_EXTENDED (macro))
|
||||
{ scm_gc_mark (SCM_SMOB_OBJECT_2 (macro));
|
||||
scm_gc_mark (SCM_SMOB_OBJECT_3 (macro));
|
||||
}
|
||||
return SCM_SMOB_OBJECT (macro);
|
||||
}
|
||||
|
||||
static SCM
|
||||
makmac (SCM code, scm_t_bits flags)
|
||||
{
|
||||
|
@ -164,11 +187,45 @@ SCM_DEFINE (scm_makmacro, "procedure->macro", 1, 0, 0,
|
|||
|
||||
#endif
|
||||
|
||||
SCM_DEFINE (scm_make_syncase_macro, "make-syncase-macro", 2, 0, 0,
|
||||
(SCM type, SCM binding),
|
||||
"Return a @dfn{macro} that requires expansion by syntax-case.\n"
|
||||
"While users should not call this function, it is useful to know\n"
|
||||
"that syntax-case macros are represented as Guile primitive macros.")
|
||||
#define FUNC_NAME s_scm_make_syncase_macro
|
||||
{
|
||||
SCM z;
|
||||
SCM_VALIDATE_SYMBOL (1, type);
|
||||
|
||||
SCM_NEWSMOB3 (z, scm_tc16_macro, SCM_UNPACK (binding), SCM_UNPACK (type),
|
||||
SCM_UNPACK (binding));
|
||||
SCM_SET_SMOB_FLAGS (z, 4 | SCM_F_MACRO_EXTENDED);
|
||||
return z;
|
||||
}
|
||||
#undef FUNC_NAME
|
||||
|
||||
SCM_DEFINE (scm_make_extended_syncase_macro, "make-extended-syncase-macro", 3, 0, 0,
|
||||
(SCM m, SCM type, SCM binding),
|
||||
"Extend a core macro @var{m} with a syntax-case binding.")
|
||||
#define FUNC_NAME s_scm_make_extended_syncase_macro
|
||||
{
|
||||
SCM z;
|
||||
SCM_VALIDATE_SMOB (1, m, macro);
|
||||
SCM_VALIDATE_SYMBOL (2, type);
|
||||
|
||||
SCM_NEWSMOB3 (z, scm_tc16_macro, SCM_SMOB_DATA (m), SCM_UNPACK (type),
|
||||
SCM_UNPACK (binding));
|
||||
SCM_SET_SMOB_FLAGS (z, SCM_SMOB_FLAGS (m) | SCM_F_MACRO_EXTENDED);
|
||||
return z;
|
||||
}
|
||||
#undef FUNC_NAME
|
||||
|
||||
|
||||
|
||||
SCM_DEFINE (scm_macro_p, "macro?", 1, 0, 0,
|
||||
(SCM obj),
|
||||
"Return @code{#t} if @var{obj} is a regular macro, a memoizing macro or a\n"
|
||||
"syntax transformer.")
|
||||
"Return @code{#t} if @var{obj} is a regular macro, a memoizing macro, a\n"
|
||||
"syntax transformer, or a syntax-case macro.")
|
||||
#define FUNC_NAME s_scm_macro_p
|
||||
{
|
||||
return scm_from_bool (SCM_SMOB_PREDICATE (scm_tc16_macro, obj));
|
||||
|
@ -182,14 +239,15 @@ SCM_SYMBOL (scm_sym_macro, "macro");
|
|||
#endif
|
||||
SCM_SYMBOL (scm_sym_mmacro, "macro!");
|
||||
SCM_SYMBOL (scm_sym_bimacro, "builtin-macro!");
|
||||
SCM_SYMBOL (scm_sym_syncase_macro, "syncase-macro");
|
||||
|
||||
SCM_DEFINE (scm_macro_type, "macro-type", 1, 0, 0,
|
||||
(SCM m),
|
||||
"Return one of the symbols @code{syntax}, @code{macro} or\n"
|
||||
"@code{macro!}, depending on whether @var{m} is a syntax\n"
|
||||
"transformer, a regular macro, or a memoizing macro,\n"
|
||||
"respectively. If @var{m} is not a macro, @code{#f} is\n"
|
||||
"returned.")
|
||||
"Return one of the symbols @code{syntax}, @code{macro},\n"
|
||||
"@code{macro!}, or @code{syntax-case}, depending on whether\n"
|
||||
"@var{m} is a syntax transformer, a regular macro, a memoizing\n"
|
||||
"macro, or a syntax-case macro, respectively. If @var{m} is\n"
|
||||
"not a macro, @code{#f} is returned.")
|
||||
#define FUNC_NAME s_scm_macro_type
|
||||
{
|
||||
if (!SCM_SMOB_PREDICATE (scm_tc16_macro, m))
|
||||
|
@ -202,6 +260,7 @@ SCM_DEFINE (scm_macro_type, "macro-type", 1, 0, 0,
|
|||
#endif
|
||||
case 2: return scm_sym_mmacro;
|
||||
case 3: return scm_sym_bimacro;
|
||||
case 4: return scm_sym_syncase_macro;
|
||||
default: scm_wrong_type_arg (FUNC_NAME, 1, m);
|
||||
}
|
||||
}
|
||||
|
@ -214,7 +273,9 @@ SCM_DEFINE (scm_macro_name, "macro-name", 1, 0, 0,
|
|||
#define FUNC_NAME s_scm_macro_name
|
||||
{
|
||||
SCM_VALIDATE_SMOB (1, m, macro);
|
||||
return scm_procedure_name (SCM_PACK (SCM_SMOB_DATA (m)));
|
||||
if (scm_is_true (scm_procedure_p (SCM_SMOB_OBJECT (m))))
|
||||
return scm_procedure_name (SCM_SMOB_OBJECT (m));
|
||||
return SCM_BOOL_F;
|
||||
}
|
||||
#undef FUNC_NAME
|
||||
|
||||
|
@ -236,6 +297,34 @@ SCM_DEFINE (scm_macro_transformer, "macro-transformer", 1, 0, 0,
|
|||
}
|
||||
#undef FUNC_NAME
|
||||
|
||||
SCM_DEFINE (scm_syncase_macro_type, "syncase-macro-type", 1, 0, 0,
|
||||
(SCM m),
|
||||
"Return the type of the macro @var{m}.")
|
||||
#define FUNC_NAME s_scm_syncase_macro_type
|
||||
{
|
||||
SCM_VALIDATE_SMOB (1, m, macro);
|
||||
|
||||
if (SCM_MACRO_IS_EXTENDED (m))
|
||||
return SCM_SMOB_OBJECT_2 (m);
|
||||
else
|
||||
return SCM_BOOL_F;
|
||||
}
|
||||
#undef FUNC_NAME
|
||||
|
||||
SCM_DEFINE (scm_syncase_macro_binding, "syncase-macro-binding", 1, 0, 0,
|
||||
(SCM m),
|
||||
"Return the binding of the macro @var{m}.")
|
||||
#define FUNC_NAME s_scm_syncase_macro_binding
|
||||
{
|
||||
SCM_VALIDATE_SMOB (1, m, macro);
|
||||
|
||||
if (SCM_MACRO_IS_EXTENDED (m))
|
||||
return SCM_SMOB_OBJECT_3 (m);
|
||||
else
|
||||
return SCM_BOOL_F;
|
||||
}
|
||||
#undef FUNC_NAME
|
||||
|
||||
SCM
|
||||
scm_make_synt (const char *name, SCM (*macroizer) (), SCM (*fcn)() )
|
||||
{
|
||||
|
@ -249,7 +338,7 @@ void
|
|||
scm_init_macros ()
|
||||
{
|
||||
scm_tc16_macro = scm_make_smob_type ("macro", 0);
|
||||
scm_set_smob_mark (scm_tc16_macro, scm_markcdr);
|
||||
scm_set_smob_mark (scm_tc16_macro, macro_mark);
|
||||
scm_set_smob_print (scm_tc16_macro, macro_print);
|
||||
#include "libguile/macros.x"
|
||||
}
|
||||
|
|
|
@ -29,9 +29,15 @@
|
|||
#define SCM_ASSYNT(_cond, _msg, _subr) \
|
||||
if (!(_cond)) scm_misc_error (_subr, _msg, SCM_EOL);
|
||||
|
||||
#define SCM_MACRO_TYPE_BITS (3)
|
||||
#define SCM_MACRO_TYPE_MASK ((1<<SCM_MACRO_TYPE_BITS)-1)
|
||||
#define SCM_F_MACRO_EXTENDED (1<<SCM_MACRO_TYPE_BITS)
|
||||
|
||||
#define SCM_MACROP(x) SCM_SMOB_PREDICATE (scm_tc16_macro, (x))
|
||||
#define SCM_MACRO_TYPE(m) SCM_SMOB_FLAGS (m)
|
||||
#define SCM_MACRO_TYPE(m) (SCM_SMOB_FLAGS (m) & SCM_MACRO_TYPE_MASK)
|
||||
#define SCM_MACRO_IS_EXTENDED(m) (SCM_SMOB_FLAGS (m) & SCM_F_MACRO_EXTENDED)
|
||||
#define SCM_BUILTIN_MACRO_P(x) (SCM_MACROP (x) && SCM_MACRO_TYPE (x) == 3)
|
||||
#define SCM_SYNCASE_MACRO_P(x) (SCM_MACROP (x) && SCM_MACRO_TYPE (x) == 4)
|
||||
#define SCM_MACRO_CODE(m) SCM_SMOB_OBJECT (m)
|
||||
|
||||
SCM_API scm_t_bits scm_tc16_macro;
|
||||
|
@ -39,10 +45,15 @@ SCM_API scm_t_bits scm_tc16_macro;
|
|||
SCM_INTERNAL SCM scm_i_makbimacro (SCM code);
|
||||
SCM_API SCM scm_makmmacro (SCM code);
|
||||
SCM_API SCM scm_makacro (SCM code);
|
||||
SCM_API SCM scm_make_syncase_macro (SCM type, SCM binding);
|
||||
SCM_API SCM scm_make_extended_syncase_macro (SCM builtin, SCM type,
|
||||
SCM binding);
|
||||
SCM_API SCM scm_macro_p (SCM obj);
|
||||
SCM_API SCM scm_macro_type (SCM m);
|
||||
SCM_API SCM scm_macro_name (SCM m);
|
||||
SCM_API SCM scm_macro_transformer (SCM m);
|
||||
SCM_API SCM scm_syncase_macro_type (SCM m);
|
||||
SCM_API SCM scm_syncase_macro_binding (SCM m);
|
||||
SCM_API SCM scm_make_synt (const char *name,
|
||||
SCM (*macroizer) (SCM),
|
||||
SCM (*fcn) ());
|
||||
|
|
|
@ -412,13 +412,13 @@ SCM_DEFINE (scm_module_local_variable, "module-local-variable", 2, 0, 0,
|
|||
|
||||
register SCM b;
|
||||
|
||||
/* SCM_MODULE_TAG is not initialized yet when `boot-9.scm' is being
|
||||
evaluated. */
|
||||
if (scm_module_system_booted_p)
|
||||
SCM_VALIDATE_MODULE (1, module);
|
||||
|
||||
SCM_VALIDATE_SYMBOL (2, sym);
|
||||
|
||||
if (scm_is_false (module))
|
||||
return scm_hashq_ref (scm_pre_modules_obarray, sym, SCM_UNDEFINED);
|
||||
|
||||
/* 1. Check module obarray */
|
||||
b = scm_hashq_ref (SCM_MODULE_OBARRAY (module), sym, SCM_UNDEFINED);
|
||||
|
|
|
@ -1,43 +1,19 @@
|
|||
/* Copyright (C) 2001 Free Software Foundation, Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this software; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
||||
* Boston, MA 02111-1307 USA
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* As a special exception, the Free Software Foundation gives permission
|
||||
* for additional uses of the text contained in its release of GUILE.
|
||||
*
|
||||
* The exception is that, if you link the GUILE library with other files
|
||||
* to produce an executable, this does not by itself cause the
|
||||
* resulting executable to be covered by the GNU General Public License.
|
||||
* Your use of that executable is in no way restricted on account of
|
||||
* linking the GUILE library code into it.
|
||||
*
|
||||
* This exception does not however invalidate any other reasons why
|
||||
* the executable file might be covered by the GNU General Public License.
|
||||
*
|
||||
* This exception applies only to the code released by the
|
||||
* Free Software Foundation under the name GUILE. If you copy
|
||||
* code from other Free Software Foundation releases into a copy of
|
||||
* GUILE, as the General Public License permits, the exception does
|
||||
* not apply to the code that you add in this way. To avoid misleading
|
||||
* anyone as to the status of such modified files, you must delete
|
||||
* this exception notice from them.
|
||||
*
|
||||
* If you write modifications of your own for GUILE, it is your choice
|
||||
* whether to permit this exception to apply to your modifications.
|
||||
* If you do not wish that, delete this exception notice. */
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#if HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
|
@ -51,6 +27,7 @@
|
|||
#include <sys/types.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "_scm.h"
|
||||
#include "vm-bootstrap.h"
|
||||
#include "programs.h"
|
||||
#include "objcodes.h"
|
||||
|
|
|
@ -1,43 +1,19 @@
|
|||
/* Copyright (C) 2001 Free Software Foundation, Inc.
|
||||
* *
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this software; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
||||
* Boston, MA 02111-1307 USA
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* As a special exception, the Free Software Foundation gives permission
|
||||
* for additional uses of the text contained in its release of GUILE.
|
||||
*
|
||||
* The exception is that, if you link the GUILE library with other files
|
||||
* to produce an executable, this does not by itself cause the
|
||||
* resulting executable to be covered by the GNU General Public License.
|
||||
* Your use of that executable is in no way restricted on account of
|
||||
* linking the GUILE library code into it.
|
||||
*
|
||||
* This exception does not however invalidate any other reasons why
|
||||
* the executable file might be covered by the GNU General Public License.
|
||||
*
|
||||
* This exception applies only to the code released by the
|
||||
* Free Software Foundation under the name GUILE. If you copy
|
||||
* code from other Free Software Foundation releases into a copy of
|
||||
* GUILE, as the General Public License permits, the exception does
|
||||
* not apply to the code that you add in this way. To avoid misleading
|
||||
* anyone as to the status of such modified files, you must delete
|
||||
* this exception notice from them.
|
||||
*
|
||||
* If you write modifications of your own for GUILE, it is your choice
|
||||
* whether to permit this exception to apply to your modifications.
|
||||
* If you do not wish that, delete this exception notice. */
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef _SCM_OBJCODES_H_
|
||||
#define _SCM_OBJCODES_H_
|
||||
|
@ -60,7 +36,7 @@ struct scm_objcode {
|
|||
#define SCM_F_OBJCODE_IS_U8VECTOR (1<<1)
|
||||
#define SCM_F_OBJCODE_IS_SLICE (1<<2)
|
||||
|
||||
extern scm_t_bits scm_tc16_objcode;
|
||||
SCM_API scm_t_bits scm_tc16_objcode;
|
||||
|
||||
#define SCM_OBJCODE_P(x) (SCM_SMOB_PREDICATE (scm_tc16_objcode, x))
|
||||
#define SCM_OBJCODE_DATA(x) ((struct scm_objcode *) SCM_SMOB_DATA (x))
|
||||
|
@ -80,15 +56,15 @@ extern scm_t_bits scm_tc16_objcode;
|
|||
#define SCM_OBJCODE_IS_SLICE(x) (SCM_SMOB_FLAGS (x) & SCM_F_OBJCODE_IS_SLICE)
|
||||
|
||||
SCM scm_c_make_objcode_slice (SCM parent, scm_t_uint8 *ptr);
|
||||
extern SCM scm_load_objcode (SCM file);
|
||||
extern SCM scm_objcode_p (SCM obj);
|
||||
extern SCM scm_objcode_meta (SCM objcode);
|
||||
extern SCM scm_bytecode_to_objcode (SCM bytecode);
|
||||
extern SCM scm_objcode_to_bytecode (SCM objcode);
|
||||
extern SCM scm_write_objcode (SCM objcode, SCM port);
|
||||
SCM_API SCM scm_load_objcode (SCM file);
|
||||
SCM_API SCM scm_objcode_p (SCM obj);
|
||||
SCM_API SCM scm_objcode_meta (SCM objcode);
|
||||
SCM_API SCM scm_bytecode_to_objcode (SCM bytecode);
|
||||
SCM_API SCM scm_objcode_to_bytecode (SCM objcode);
|
||||
SCM_API SCM scm_write_objcode (SCM objcode, SCM port);
|
||||
|
||||
extern void scm_bootstrap_objcodes (void);
|
||||
extern void scm_init_objcodes (void);
|
||||
SCM_INTERNAL void scm_bootstrap_objcodes (void);
|
||||
SCM_INTERNAL void scm_init_objcodes (void);
|
||||
|
||||
#endif /* _SCM_OBJCODES_H_ */
|
||||
|
||||
|
|
|
@ -101,8 +101,6 @@ extern char *ttyname();
|
|||
|
||||
#include <signal.h>
|
||||
|
||||
extern char ** environ;
|
||||
|
||||
#ifdef HAVE_GRP_H
|
||||
#include <grp.h>
|
||||
#endif
|
||||
|
@ -140,10 +138,6 @@ extern char ** environ;
|
|||
|
||||
#include <sys/file.h> /* from Gnulib */
|
||||
|
||||
#if HAVE_CRT_EXTERNS_H
|
||||
#include <crt_externs.h> /* for Darwin _NSGetEnviron */
|
||||
#endif
|
||||
|
||||
/* Some Unix systems don't define these. CPP hair is dangerous, but
|
||||
this seems safe enough... */
|
||||
#ifndef R_OK
|
||||
|
@ -196,13 +190,6 @@ int sethostname (char *name, size_t namelen);
|
|||
|
||||
|
||||
|
||||
/* On Apple Darwin in a shared library there's no "environ" to access
|
||||
directly, instead the address of that variable must be obtained with
|
||||
_NSGetEnviron(). */
|
||||
#if HAVE__NSGETENVIRON && defined (PIC)
|
||||
#define environ (*_NSGetEnviron())
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/* Two often used patterns
|
||||
|
|
|
@ -1,49 +1,26 @@
|
|||
/* Copyright (C) 2001 Free Software Foundation, Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this software; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
||||
* Boston, MA 02111-1307 USA
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* As a special exception, the Free Software Foundation gives permission
|
||||
* for additional uses of the text contained in its release of GUILE.
|
||||
*
|
||||
* The exception is that, if you link the GUILE library with other files
|
||||
* to produce an executable, this does not by itself cause the
|
||||
* resulting executable to be covered by the GNU General Public License.
|
||||
* Your use of that executable is in no way restricted on account of
|
||||
* linking the GUILE library code into it.
|
||||
*
|
||||
* This exception does not however invalidate any other reasons why
|
||||
* the executable file might be covered by the GNU General Public License.
|
||||
*
|
||||
* This exception applies only to the code released by the
|
||||
* Free Software Foundation under the name GUILE. If you copy
|
||||
* code from other Free Software Foundation releases into a copy of
|
||||
* GUILE, as the General Public License permits, the exception does
|
||||
* not apply to the code that you add in this way. To avoid misleading
|
||||
* anyone as to the status of such modified files, you must delete
|
||||
* this exception notice from them.
|
||||
*
|
||||
* If you write modifications of your own for GUILE, it is your choice
|
||||
* whether to permit this exception to apply to your modifications.
|
||||
* If you do not wish that, delete this exception notice. */
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#if HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <string.h>
|
||||
#include "_scm.h"
|
||||
#include "vm-bootstrap.h"
|
||||
#include "instructions.h"
|
||||
#include "modules.h"
|
||||
|
|
|
@ -1,43 +1,19 @@
|
|||
/* Copyright (C) 2001 Free Software Foundation, Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this software; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
||||
* Boston, MA 02111-1307 USA
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* As a special exception, the Free Software Foundation gives permission
|
||||
* for additional uses of the text contained in its release of GUILE.
|
||||
*
|
||||
* The exception is that, if you link the GUILE library with other files
|
||||
* to produce an executable, this does not by itself cause the
|
||||
* resulting executable to be covered by the GNU General Public License.
|
||||
* Your use of that executable is in no way restricted on account of
|
||||
* linking the GUILE library code into it.
|
||||
*
|
||||
* This exception does not however invalidate any other reasons why
|
||||
* the executable file might be covered by the GNU General Public License.
|
||||
*
|
||||
* This exception applies only to the code released by the
|
||||
* Free Software Foundation under the name GUILE. If you copy
|
||||
* code from other Free Software Foundation releases into a copy of
|
||||
* GUILE, as the General Public License permits, the exception does
|
||||
* not apply to the code that you add in this way. To avoid misleading
|
||||
* anyone as to the status of such modified files, you must delete
|
||||
* this exception notice from them.
|
||||
*
|
||||
* If you write modifications of your own for GUILE, it is your choice
|
||||
* whether to permit this exception to apply to your modifications.
|
||||
* If you do not wish that, delete this exception notice. */
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef _SCM_PROGRAMS_H_
|
||||
#define _SCM_PROGRAMS_H_
|
||||
|
@ -51,7 +27,7 @@
|
|||
|
||||
typedef unsigned char scm_byte_t;
|
||||
|
||||
extern scm_t_bits scm_tc16_program;
|
||||
SCM_API scm_t_bits scm_tc16_program;
|
||||
|
||||
#define SCM_F_PROGRAM_IS_BOOT (1<<0)
|
||||
|
||||
|
@ -63,27 +39,27 @@ extern scm_t_bits scm_tc16_program;
|
|||
#define SCM_VALIDATE_PROGRAM(p,x) SCM_MAKE_VALIDATE (p, x, PROGRAM_P)
|
||||
#define SCM_PROGRAM_IS_BOOT(x) (SCM_SMOB_FLAGS (x) & SCM_F_PROGRAM_IS_BOOT)
|
||||
|
||||
extern SCM scm_make_program (SCM objcode, SCM objtable, SCM externals);
|
||||
SCM_API SCM scm_make_program (SCM objcode, SCM objtable, SCM externals);
|
||||
|
||||
extern SCM scm_program_p (SCM obj);
|
||||
extern SCM scm_program_base (SCM program);
|
||||
extern SCM scm_program_arity (SCM program);
|
||||
extern SCM scm_program_meta (SCM program);
|
||||
extern SCM scm_program_bindings (SCM program);
|
||||
extern SCM scm_program_sources (SCM program);
|
||||
extern SCM scm_program_source (SCM program, SCM ip);
|
||||
extern SCM scm_program_properties (SCM program);
|
||||
extern SCM scm_program_name (SCM program);
|
||||
extern SCM scm_program_objects (SCM program);
|
||||
extern SCM scm_program_module (SCM program);
|
||||
extern SCM scm_program_external (SCM program);
|
||||
extern SCM scm_program_external_set_x (SCM program, SCM external);
|
||||
extern SCM scm_program_objcode (SCM program);
|
||||
SCM_API SCM scm_program_p (SCM obj);
|
||||
SCM_API SCM scm_program_base (SCM program);
|
||||
SCM_API SCM scm_program_arity (SCM program);
|
||||
SCM_API SCM scm_program_meta (SCM program);
|
||||
SCM_API SCM scm_program_bindings (SCM program);
|
||||
SCM_API SCM scm_program_sources (SCM program);
|
||||
SCM_API SCM scm_program_source (SCM program, SCM ip);
|
||||
SCM_API SCM scm_program_properties (SCM program);
|
||||
SCM_API SCM scm_program_name (SCM program);
|
||||
SCM_API SCM scm_program_objects (SCM program);
|
||||
SCM_API SCM scm_program_module (SCM program);
|
||||
SCM_API SCM scm_program_external (SCM program);
|
||||
SCM_API SCM scm_program_external_set_x (SCM program, SCM external);
|
||||
SCM_API SCM scm_program_objcode (SCM program);
|
||||
|
||||
extern SCM scm_c_program_source (SCM program, size_t ip);
|
||||
SCM_API SCM scm_c_program_source (SCM program, size_t ip);
|
||||
|
||||
extern void scm_bootstrap_programs (void);
|
||||
extern void scm_init_programs (void);
|
||||
SCM_INTERNAL void scm_bootstrap_programs (void);
|
||||
SCM_INTERNAL void scm_init_programs (void);
|
||||
|
||||
#endif /* _SCM_PROGRAMS_H_ */
|
||||
|
||||
|
|
1118
libguile/r6rs-ports.c
Normal file
1118
libguile/r6rs-ports.c
Normal file
File diff suppressed because it is too large
Load diff
43
libguile/r6rs-ports.h
Normal file
43
libguile/r6rs-ports.h
Normal file
|
@ -0,0 +1,43 @@
|
|||
#ifndef SCM_R6RS_PORTS_H
|
||||
#define SCM_R6RS_PORTS_H
|
||||
|
||||
/* Copyright (C) 2009 Free Software Foundation, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#include "libguile/__scm.h"
|
||||
|
||||
/* R6RS I/O Ports. */
|
||||
|
||||
SCM_API SCM scm_eof_object (void);
|
||||
SCM_API SCM scm_open_bytevector_input_port (SCM, SCM);
|
||||
SCM_API SCM scm_make_custom_binary_input_port (SCM, SCM, SCM, SCM, SCM);
|
||||
SCM_API SCM scm_get_u8 (SCM);
|
||||
SCM_API SCM scm_lookahead_u8 (SCM);
|
||||
SCM_API SCM scm_get_bytevector_n (SCM, SCM);
|
||||
SCM_API SCM scm_get_bytevector_n_x (SCM, SCM, SCM, SCM);
|
||||
SCM_API SCM scm_get_bytevector_some (SCM);
|
||||
SCM_API SCM scm_get_bytevector_all (SCM);
|
||||
SCM_API SCM scm_put_u8 (SCM, SCM);
|
||||
SCM_API SCM scm_put_bytevector (SCM, SCM, SCM, SCM);
|
||||
SCM_API SCM scm_open_bytevector_output_port (SCM);
|
||||
SCM_API SCM scm_make_custom_binary_output_port (SCM, SCM, SCM, SCM, SCM);
|
||||
|
||||
SCM_API void scm_init_r6rs_ports (void);
|
||||
|
||||
#endif /* SCM_R6RS_PORTS_H */
|
|
@ -182,6 +182,7 @@ static SCM *scm_read_hash_procedures;
|
|||
|
||||
/* Read an SCSH block comment. */
|
||||
static inline SCM scm_read_scsh_block_comment (int chr, SCM port);
|
||||
static SCM scm_read_commented_expression (int chr, SCM port);
|
||||
|
||||
/* Read from PORT until a delimiter (e.g., a whitespace) is read. Return
|
||||
zero if the whole token fits in BUF, non-zero otherwise. */
|
||||
|
@ -257,6 +258,9 @@ flush_ws (SCM port, const char *eoferr)
|
|||
case '!':
|
||||
scm_read_scsh_block_comment (c, port);
|
||||
break;
|
||||
case ';':
|
||||
scm_read_commented_expression (c, port);
|
||||
break;
|
||||
default:
|
||||
scm_ungetc (c, port);
|
||||
return '#';
|
||||
|
@ -700,6 +704,65 @@ scm_read_quote (int chr, SCM port)
|
|||
return p;
|
||||
}
|
||||
|
||||
SCM_SYMBOL (sym_syntax, "syntax");
|
||||
SCM_SYMBOL (sym_quasisyntax, "quasisyntax");
|
||||
SCM_SYMBOL (sym_unsyntax, "unsyntax");
|
||||
SCM_SYMBOL (sym_unsyntax_splicing, "unsyntax-splicing");
|
||||
|
||||
static SCM
|
||||
scm_read_syntax (int chr, SCM port)
|
||||
{
|
||||
SCM p;
|
||||
long line = SCM_LINUM (port);
|
||||
int column = SCM_COL (port) - 1;
|
||||
|
||||
switch (chr)
|
||||
{
|
||||
case '`':
|
||||
p = sym_quasisyntax;
|
||||
break;
|
||||
|
||||
case '\'':
|
||||
p = sym_syntax;
|
||||
break;
|
||||
|
||||
case ',':
|
||||
{
|
||||
int c;
|
||||
|
||||
c = scm_getc (port);
|
||||
if ('@' == c)
|
||||
p = sym_unsyntax_splicing;
|
||||
else
|
||||
{
|
||||
scm_ungetc (c, port);
|
||||
p = sym_unsyntax;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
fprintf (stderr, "%s: unhandled syntax character (%i)\n",
|
||||
"scm_read_syntax", chr);
|
||||
abort ();
|
||||
}
|
||||
|
||||
p = scm_cons2 (p, scm_read_expression (port), SCM_EOL);
|
||||
if (SCM_RECORD_POSITIONS_P)
|
||||
scm_whash_insert (scm_source_whash, p,
|
||||
scm_make_srcprops (line, column,
|
||||
SCM_FILENAME (port),
|
||||
SCM_COPY_SOURCE_P
|
||||
? (scm_cons2 (SCM_CAR (p),
|
||||
SCM_CAR (SCM_CDR (p)),
|
||||
SCM_EOL))
|
||||
: SCM_UNDEFINED,
|
||||
SCM_EOL));
|
||||
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
static inline SCM
|
||||
scm_read_semicolon_comment (int chr, SCM port)
|
||||
{
|
||||
|
@ -862,6 +925,20 @@ scm_read_scsh_block_comment (int chr, SCM port)
|
|||
return SCM_UNSPECIFIED;
|
||||
}
|
||||
|
||||
static SCM
|
||||
scm_read_commented_expression (int chr, SCM port)
|
||||
{
|
||||
int c;
|
||||
|
||||
c = flush_ws (port, (char *) NULL);
|
||||
if (EOF == c)
|
||||
scm_i_input_error ("read_commented_expression", port,
|
||||
"no expression after #; comment", SCM_EOL);
|
||||
scm_ungetc (c, port);
|
||||
scm_read_expression (port);
|
||||
return SCM_UNSPECIFIED;
|
||||
}
|
||||
|
||||
static SCM
|
||||
scm_read_extended_symbol (int chr, SCM port)
|
||||
{
|
||||
|
@ -1023,6 +1100,12 @@ scm_read_sharp (int chr, SCM port)
|
|||
return (scm_read_extended_symbol (chr, port));
|
||||
case '!':
|
||||
return (scm_read_scsh_block_comment (chr, port));
|
||||
case ';':
|
||||
return (scm_read_commented_expression (chr, port));
|
||||
case '`':
|
||||
case '\'':
|
||||
case ',':
|
||||
return (scm_read_syntax (chr, port));
|
||||
default:
|
||||
result = scm_read_sharp_extension (chr, port);
|
||||
if (scm_is_eq (result, SCM_UNSPECIFIED))
|
||||
|
|
|
@ -77,10 +77,6 @@
|
|||
# include <sys/timeb.h>
|
||||
#endif
|
||||
|
||||
#if HAVE_CRT_EXTERNS_H
|
||||
#include <crt_externs.h> /* for Darwin _NSGetEnviron */
|
||||
#endif
|
||||
|
||||
#ifndef tzname /* For SGI. */
|
||||
extern char *tzname[]; /* RS6000 and others reject char **tzname. */
|
||||
#endif
|
||||
|
@ -98,15 +94,6 @@ extern char *strptime ();
|
|||
# define timet long
|
||||
#endif
|
||||
|
||||
extern char ** environ;
|
||||
|
||||
/* On Apple Darwin in a shared library there's no "environ" to access
|
||||
directly, instead the address of that variable must be obtained with
|
||||
_NSGetEnviron(). */
|
||||
#if HAVE__NSGETENVIRON && defined (PIC)
|
||||
#define environ (*_NSGetEnviron())
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef HAVE_TIMES
|
||||
static
|
||||
|
|
|
@ -1161,6 +1161,16 @@ SCM_DEFINE (scm_join_thread_timed, "join-thread", 1, 2, 0,
|
|||
scm_i_pthread_mutex_unlock (&t->admin_mutex);
|
||||
SCM_TICK;
|
||||
scm_i_scm_pthread_mutex_lock (&t->admin_mutex);
|
||||
|
||||
/* Check for exit again, since we just released and
|
||||
reacquired the admin mutex, before the next block_self
|
||||
call (which would block forever if t has already
|
||||
exited). */
|
||||
if (t->exited)
|
||||
{
|
||||
res = t->result;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1491,6 +1501,7 @@ fat_mutex_unlock (SCM mutex, SCM cond,
|
|||
{
|
||||
if (relock)
|
||||
scm_lock_mutex_timed (mutex, SCM_UNDEFINED, owner);
|
||||
t->block_asyncs--;
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
#ifndef SCM_VALIDATE_H
|
||||
#define SCM_VALIDATE_H
|
||||
|
||||
/* Copyright (C) 1999,2000,2001, 2002, 2004, 2006, 2007 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 1999,2000,2001, 2002, 2004, 2006, 2007, 2009 Free Software Foundation, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
|
@ -150,6 +150,9 @@
|
|||
cvar = scm_to_bool (flag); \
|
||||
} while (0)
|
||||
|
||||
#define SCM_VALIDATE_BYTEVECTOR(_pos, _obj) \
|
||||
SCM_VALIDATE_SMOB ((_pos), (_obj), bytevector)
|
||||
|
||||
#define SCM_VALIDATE_CHAR(pos, scm) SCM_MAKE_VALIDATE_MSG (pos, scm, CHARP, "character")
|
||||
|
||||
#define SCM_VALIDATE_CHAR_COPY(pos, scm, cvar) \
|
||||
|
|
|
@ -1,48 +1,24 @@
|
|||
/* Copyright (C) 2001 Free Software Foundation, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this software; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
||||
* Boston, MA 02111-1307 USA
|
||||
*
|
||||
* As a special exception, the Free Software Foundation gives permission
|
||||
* for additional uses of the text contained in its release of GUILE.
|
||||
*
|
||||
* The exception is that, if you link the GUILE library with other files
|
||||
* to produce an executable, this does not by itself cause the
|
||||
* resulting executable to be covered by the GNU General Public License.
|
||||
* Your use of that executable is in no way restricted on account of
|
||||
* linking the GUILE library code into it.
|
||||
*
|
||||
* This exception does not however invalidate any other reasons why
|
||||
* the executable file might be covered by the GNU General Public License.
|
||||
*
|
||||
* This exception applies only to the code released by the
|
||||
* Free Software Foundation under the name GUILE. If you copy
|
||||
* code from other Free Software Foundation releases into a copy of
|
||||
* GUILE, as the General Public License permits, the exception does
|
||||
* not apply to the code that you add in this way. To avoid misleading
|
||||
* anyone as to the status of such modified files, you must delete
|
||||
* this exception notice from them.
|
||||
*
|
||||
* If you write modifications of your own for GUILE, it is your choice
|
||||
* whether to permit this exception to apply to your modifications.
|
||||
* If you do not wish that, delete this exception notice. */
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef _SCM_VM_BOOTSTRAP_H_
|
||||
#define _SCM_VM_BOOTSTRAP_H_
|
||||
|
||||
extern void scm_bootstrap_vm (void);
|
||||
SCM_INTERNAL void scm_bootstrap_vm (void);
|
||||
|
||||
#endif /* _SCM_VM_BOOTSTRAP_H_ */
|
||||
|
||||
|
|
|
@ -1,43 +1,19 @@
|
|||
/* Copyright (C) 2001 Free Software Foundation, Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this software; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
||||
* Boston, MA 02111-1307 USA
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* As a special exception, the Free Software Foundation gives permission
|
||||
* for additional uses of the text contained in its release of GUILE.
|
||||
*
|
||||
* The exception is that, if you link the GUILE library with other files
|
||||
* to produce an executable, this does not by itself cause the
|
||||
* resulting executable to be covered by the GNU General Public License.
|
||||
* Your use of that executable is in no way restricted on account of
|
||||
* linking the GUILE library code into it.
|
||||
*
|
||||
* This exception does not however invalidate any other reasons why
|
||||
* the executable file might be covered by the GNU General Public License.
|
||||
*
|
||||
* This exception applies only to the code released by the
|
||||
* Free Software Foundation under the name GUILE. If you copy
|
||||
* code from other Free Software Foundation releases into a copy of
|
||||
* GUILE, as the General Public License permits, the exception does
|
||||
* not apply to the code that you add in this way. To avoid misleading
|
||||
* anyone as to the status of such modified files, you must delete
|
||||
* this exception notice from them.
|
||||
*
|
||||
* If you write modifications of your own for GUILE, it is your choice
|
||||
* whether to permit this exception to apply to your modifications.
|
||||
* If you do not wish that, delete this exception notice. */
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/* This file is included in vm.c multiple times */
|
||||
|
||||
|
|
|
@ -1,43 +1,19 @@
|
|||
/* Copyright (C) 2001 Free Software Foundation, Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this software; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
||||
* Boston, MA 02111-1307 USA
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* As a special exception, the Free Software Foundation gives permission
|
||||
* for additional uses of the text contained in its release of GUILE.
|
||||
*
|
||||
* The exception is that, if you link the GUILE library with other files
|
||||
* to produce an executable, this does not by itself cause the
|
||||
* resulting executable to be covered by the GNU General Public License.
|
||||
* Your use of that executable is in no way restricted on account of
|
||||
* linking the GUILE library code into it.
|
||||
*
|
||||
* This exception does not however invalidate any other reasons why
|
||||
* the executable file might be covered by the GNU General Public License.
|
||||
*
|
||||
* This exception applies only to the code released by the
|
||||
* Free Software Foundation under the name GUILE. If you copy
|
||||
* code from other Free Software Foundation releases into a copy of
|
||||
* GUILE, as the General Public License permits, the exception does
|
||||
* not apply to the code that you add in this way. To avoid misleading
|
||||
* anyone as to the status of such modified files, you must delete
|
||||
* this exception notice from them.
|
||||
*
|
||||
* If you write modifications of your own for GUILE, it is your choice
|
||||
* whether to permit this exception to apply to your modifications.
|
||||
* If you do not wish that, delete this exception notice. */
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/* This file is included in vm_engine.c */
|
||||
|
||||
|
@ -147,8 +123,12 @@
|
|||
#ifdef VM_ENABLE_PARANOID_ASSERTIONS
|
||||
#define CHECK_IP() \
|
||||
do { if (ip < bp->base || ip - bp->base > bp->len) abort (); } while (0)
|
||||
#define ASSERT_BOUND(x) \
|
||||
do { if ((x) == SCM_UNDEFINED) { SYNC_REGISTER (); abort(); } \
|
||||
} while (0)
|
||||
#else
|
||||
#define CHECK_IP()
|
||||
#define ASSERT_BOUND(x)
|
||||
#endif
|
||||
|
||||
/* Get a local copy of the program's "object table" (i.e. the vector of
|
||||
|
|
|
@ -1,43 +1,19 @@
|
|||
/* Copyright (C) 2001 Free Software Foundation, Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this software; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
||||
* Boston, MA 02111-1307 USA
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* As a special exception, the Free Software Foundation gives permission
|
||||
* for additional uses of the text contained in its release of GUILE.
|
||||
*
|
||||
* The exception is that, if you link the GUILE library with other files
|
||||
* to produce an executable, this does not by itself cause the
|
||||
* resulting executable to be covered by the GNU General Public License.
|
||||
* Your use of that executable is in no way restricted on account of
|
||||
* linking the GUILE library code into it.
|
||||
*
|
||||
* This exception does not however invalidate any other reasons why
|
||||
* the executable file might be covered by the GNU General Public License.
|
||||
*
|
||||
* This exception applies only to the code released by the
|
||||
* Free Software Foundation under the name GUILE. If you copy
|
||||
* code from other Free Software Foundation releases into a copy of
|
||||
* GUILE, as the General Public License permits, the exception does
|
||||
* not apply to the code that you add in this way. To avoid misleading
|
||||
* anyone as to the status of such modified files, you must delete
|
||||
* this exception notice from them.
|
||||
*
|
||||
* If you write modifications of your own for GUILE, it is your choice
|
||||
* whether to permit this exception to apply to your modifications.
|
||||
* If you do not wish that, delete this exception notice. */
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef VM_LABEL
|
||||
#define VM_LABEL(tag) l_##tag
|
||||
|
|
|
@ -1,43 +1,19 @@
|
|||
/* Copyright (C) 2001 Free Software Foundation, Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this software; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
||||
* Boston, MA 02111-1307 USA
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* As a special exception, the Free Software Foundation gives permission
|
||||
* for additional uses of the text contained in its release of GUILE.
|
||||
*
|
||||
* The exception is that, if you link the GUILE library with other files
|
||||
* to produce an executable, this does not by itself cause the
|
||||
* resulting executable to be covered by the GNU General Public License.
|
||||
* Your use of that executable is in no way restricted on account of
|
||||
* linking the GUILE library code into it.
|
||||
*
|
||||
* This exception does not however invalidate any other reasons why
|
||||
* the executable file might be covered by the GNU General Public License.
|
||||
*
|
||||
* This exception applies only to the code released by the
|
||||
* Free Software Foundation under the name GUILE. If you copy
|
||||
* code from other Free Software Foundation releases into a copy of
|
||||
* GUILE, as the General Public License permits, the exception does
|
||||
* not apply to the code that you add in this way. To avoid misleading
|
||||
* anyone as to the status of such modified files, you must delete
|
||||
* this exception notice from them.
|
||||
*
|
||||
* If you write modifications of your own for GUILE, it is your choice
|
||||
* whether to permit this exception to apply to your modifications.
|
||||
* If you do not wish that, delete this exception notice. */
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/* This file is included in vm_engine.c */
|
||||
|
||||
|
|
|
@ -230,6 +230,7 @@ VM_DEFINE_INSTRUCTION (21, object_ref, "object-ref", 1, 0, 1)
|
|||
VM_DEFINE_INSTRUCTION (22, local_ref, "local-ref", 1, 0, 1)
|
||||
{
|
||||
PUSH (LOCAL_REF (FETCH ()));
|
||||
ASSERT_BOUND (*sp);
|
||||
NEXT;
|
||||
}
|
||||
|
||||
|
@ -244,6 +245,7 @@ VM_DEFINE_INSTRUCTION (23, external_ref, "external-ref", 1, 0, 1)
|
|||
}
|
||||
CHECK_EXTERNAL(e);
|
||||
PUSH (SCM_CAR (e));
|
||||
ASSERT_BOUND (*sp);
|
||||
NEXT;
|
||||
}
|
||||
|
||||
|
@ -408,12 +410,6 @@ VM_DEFINE_INSTRUCTION (29, toplevel_set, "toplevel-set", 1, 1, 0)
|
|||
NEXT;
|
||||
}
|
||||
|
||||
VM_DEFINE_INSTRUCTION (30, externals, "externals", 0, 0, 1)
|
||||
{
|
||||
PUSH (external);
|
||||
NEXT;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* branch and jump
|
||||
|
|
|
@ -1,43 +1,19 @@
|
|||
/* Copyright (C) 2001 Free Software Foundation, Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this software; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
||||
* Boston, MA 02111-1307 USA
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* As a special exception, the Free Software Foundation gives permission
|
||||
* for additional uses of the text contained in its release of GUILE.
|
||||
*
|
||||
* The exception is that, if you link the GUILE library with other files
|
||||
* to produce an executable, this does not by itself cause the
|
||||
* resulting executable to be covered by the GNU General Public License.
|
||||
* Your use of that executable is in no way restricted on account of
|
||||
* linking the GUILE library code into it.
|
||||
*
|
||||
* This exception does not however invalidate any other reasons why
|
||||
* the executable file might be covered by the GNU General Public License.
|
||||
*
|
||||
* This exception applies only to the code released by the
|
||||
* Free Software Foundation under the name GUILE. If you copy
|
||||
* code from other Free Software Foundation releases into a copy of
|
||||
* GUILE, as the General Public License permits, the exception does
|
||||
* not apply to the code that you add in this way. To avoid misleading
|
||||
* anyone as to the status of such modified files, you must delete
|
||||
* this exception notice from them.
|
||||
*
|
||||
* If you write modifications of your own for GUILE, it is your choice
|
||||
* whether to permit this exception to apply to your modifications.
|
||||
* If you do not wish that, delete this exception notice. */
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#if HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
|
@ -46,6 +22,7 @@
|
|||
#include <stdlib.h>
|
||||
#include <alloca.h>
|
||||
#include <string.h>
|
||||
#include "_scm.h"
|
||||
#include "vm-bootstrap.h"
|
||||
#include "frames.h"
|
||||
#include "instructions.h"
|
||||
|
|
108
libguile/vm.h
108
libguile/vm.h
|
@ -1,43 +1,19 @@
|
|||
/* Copyright (C) 2001 Free Software Foundation, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this software; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
||||
* Boston, MA 02111-1307 USA
|
||||
*
|
||||
* As a special exception, the Free Software Foundation gives permission
|
||||
* for additional uses of the text contained in its release of GUILE.
|
||||
*
|
||||
* The exception is that, if you link the GUILE library with other files
|
||||
* to produce an executable, this does not by itself cause the
|
||||
* resulting executable to be covered by the GNU General Public License.
|
||||
* Your use of that executable is in no way restricted on account of
|
||||
* linking the GUILE library code into it.
|
||||
*
|
||||
* This exception does not however invalidate any other reasons why
|
||||
* the executable file might be covered by the GNU General Public License.
|
||||
*
|
||||
* This exception applies only to the code released by the
|
||||
* Free Software Foundation under the name GUILE. If you copy
|
||||
* code from other Free Software Foundation releases into a copy of
|
||||
* GUILE, as the General Public License permits, the exception does
|
||||
* not apply to the code that you add in this way. To avoid misleading
|
||||
* anyone as to the status of such modified files, you must delete
|
||||
* this exception notice from them.
|
||||
*
|
||||
* If you write modifications of your own for GUILE, it is your choice
|
||||
* whether to permit this exception to apply to your modifications.
|
||||
* If you do not wish that, delete this exception notice. */
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef _SCM_VM_H_
|
||||
#define _SCM_VM_H_
|
||||
|
@ -78,37 +54,37 @@ struct scm_vm {
|
|||
SCM trace_frame; /* a frame being traced */
|
||||
};
|
||||
|
||||
extern SCM scm_the_vm_fluid;
|
||||
SCM_API SCM scm_the_vm_fluid;
|
||||
|
||||
#define SCM_VM_P(x) SCM_SMOB_PREDICATE (scm_tc16_vm, x)
|
||||
#define SCM_VM_DATA(vm) ((struct scm_vm *) SCM_SMOB_DATA (vm))
|
||||
#define SCM_VALIDATE_VM(pos,x) SCM_MAKE_VALIDATE (pos, x, VM_P)
|
||||
|
||||
extern SCM scm_the_vm ();
|
||||
extern SCM scm_make_vm (void);
|
||||
extern SCM scm_vm_apply (SCM vm, SCM program, SCM args);
|
||||
extern SCM scm_c_vm_run (SCM vm, SCM program, SCM *argv, int nargs);
|
||||
extern SCM scm_vm_option_ref (SCM vm, SCM key);
|
||||
extern SCM scm_vm_option_set_x (SCM vm, SCM key, SCM val);
|
||||
SCM_API SCM scm_the_vm ();
|
||||
SCM_API SCM scm_make_vm (void);
|
||||
SCM_API SCM scm_vm_apply (SCM vm, SCM program, SCM args);
|
||||
SCM_API SCM scm_c_vm_run (SCM vm, SCM program, SCM *argv, int nargs);
|
||||
SCM_API SCM scm_vm_option_ref (SCM vm, SCM key);
|
||||
SCM_API SCM scm_vm_option_set_x (SCM vm, SCM key, SCM val);
|
||||
|
||||
extern SCM scm_vm_version (void);
|
||||
extern SCM scm_the_vm (void);
|
||||
extern SCM scm_vm_p (SCM obj);
|
||||
extern SCM scm_vm_ip (SCM vm);
|
||||
extern SCM scm_vm_sp (SCM vm);
|
||||
extern SCM scm_vm_fp (SCM vm);
|
||||
extern SCM scm_vm_boot_hook (SCM vm);
|
||||
extern SCM scm_vm_halt_hook (SCM vm);
|
||||
extern SCM scm_vm_next_hook (SCM vm);
|
||||
extern SCM scm_vm_break_hook (SCM vm);
|
||||
extern SCM scm_vm_enter_hook (SCM vm);
|
||||
extern SCM scm_vm_apply_hook (SCM vm);
|
||||
extern SCM scm_vm_exit_hook (SCM vm);
|
||||
extern SCM scm_vm_return_hook (SCM vm);
|
||||
extern SCM scm_vm_option (SCM vm, SCM key);
|
||||
extern SCM scm_set_vm_option_x (SCM vm, SCM key, SCM val);
|
||||
extern SCM scm_vm_stats (SCM vm);
|
||||
extern SCM scm_vm_trace_frame (SCM vm);
|
||||
SCM_API SCM scm_vm_version (void);
|
||||
SCM_API SCM scm_the_vm (void);
|
||||
SCM_API SCM scm_vm_p (SCM obj);
|
||||
SCM_API SCM scm_vm_ip (SCM vm);
|
||||
SCM_API SCM scm_vm_sp (SCM vm);
|
||||
SCM_API SCM scm_vm_fp (SCM vm);
|
||||
SCM_API SCM scm_vm_boot_hook (SCM vm);
|
||||
SCM_API SCM scm_vm_halt_hook (SCM vm);
|
||||
SCM_API SCM scm_vm_next_hook (SCM vm);
|
||||
SCM_API SCM scm_vm_break_hook (SCM vm);
|
||||
SCM_API SCM scm_vm_enter_hook (SCM vm);
|
||||
SCM_API SCM scm_vm_apply_hook (SCM vm);
|
||||
SCM_API SCM scm_vm_exit_hook (SCM vm);
|
||||
SCM_API SCM scm_vm_return_hook (SCM vm);
|
||||
SCM_API SCM scm_vm_option (SCM vm, SCM key);
|
||||
SCM_API SCM scm_set_vm_option_x (SCM vm, SCM key, SCM val);
|
||||
SCM_API SCM scm_vm_stats (SCM vm);
|
||||
SCM_API SCM scm_vm_trace_frame (SCM vm);
|
||||
|
||||
struct scm_vm_cont {
|
||||
scm_byte_t *ip;
|
||||
|
@ -119,16 +95,16 @@ struct scm_vm_cont {
|
|||
scm_t_ptrdiff reloc;
|
||||
};
|
||||
|
||||
extern scm_t_bits scm_tc16_vm_cont;
|
||||
SCM_API scm_t_bits scm_tc16_vm_cont;
|
||||
#define SCM_VM_CONT_P(OBJ) SCM_SMOB_PREDICATE (scm_tc16_vm_cont, OBJ)
|
||||
#define SCM_VM_CONT_DATA(CONT) ((struct scm_vm_cont *) SCM_CELL_WORD_1 (CONT))
|
||||
|
||||
extern SCM scm_vm_capture_continuations (void);
|
||||
extern void scm_vm_reinstate_continuations (SCM conts);
|
||||
SCM_API SCM scm_vm_capture_continuations (void);
|
||||
SCM_API void scm_vm_reinstate_continuations (SCM conts);
|
||||
|
||||
extern SCM scm_load_compiled_with_vm (SCM file);
|
||||
SCM_API SCM scm_load_compiled_with_vm (SCM file);
|
||||
|
||||
extern void scm_init_vm (void);
|
||||
SCM_INTERNAL void scm_init_vm (void);
|
||||
|
||||
#endif /* _SCM_VM_H_ */
|
||||
|
||||
|
|
18
m4/byteswap.m4
Normal file
18
m4/byteswap.m4
Normal file
|
@ -0,0 +1,18 @@
|
|||
# byteswap.m4 serial 3
|
||||
dnl Copyright (C) 2005, 2007, 2009 Free Software Foundation, Inc.
|
||||
dnl This file is free software; the Free Software Foundation
|
||||
dnl gives unlimited permission to copy and/or distribute it,
|
||||
dnl with or without modifications, as long as this notice is preserved.
|
||||
|
||||
dnl Written by Oskar Liljeblad.
|
||||
|
||||
AC_DEFUN([gl_BYTESWAP],
|
||||
[
|
||||
dnl Prerequisites of lib/byteswap.in.h.
|
||||
AC_CHECK_HEADERS([byteswap.h], [
|
||||
BYTESWAP_H=''
|
||||
], [
|
||||
BYTESWAP_H='byteswap.h'
|
||||
])
|
||||
AC_SUBST([BYTESWAP_H])
|
||||
])
|
36
m4/environ.m4
Normal file
36
m4/environ.m4
Normal file
|
@ -0,0 +1,36 @@
|
|||
# environ.m4 serial 2
|
||||
dnl Copyright (C) 2001-2004, 2006-2009 Free Software Foundation, Inc.
|
||||
dnl This file is free software; the Free Software Foundation
|
||||
dnl gives unlimited permission to copy and/or distribute it,
|
||||
dnl with or without modifications, as long as this notice is preserved.
|
||||
|
||||
AC_DEFUN([gl_ENVIRON],
|
||||
[
|
||||
AC_REQUIRE([gl_UNISTD_H_DEFAULTS])
|
||||
dnl Persuade glibc <unistd.h> to declare environ.
|
||||
AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS])
|
||||
gt_CHECK_VAR_DECL([#include <unistd.h>], environ)
|
||||
if test $gt_cv_var_environ_declaration != yes; then
|
||||
HAVE_DECL_ENVIRON=0
|
||||
fi
|
||||
])
|
||||
|
||||
# Check if a variable is properly declared.
|
||||
# gt_CHECK_VAR_DECL(includes,variable)
|
||||
AC_DEFUN([gt_CHECK_VAR_DECL],
|
||||
[
|
||||
define([gt_cv_var], [gt_cv_var_]$2[_declaration])
|
||||
AC_MSG_CHECKING([if $2 is properly declared])
|
||||
AC_CACHE_VAL([gt_cv_var], [
|
||||
AC_TRY_COMPILE([$1
|
||||
extern struct { int foo; } $2;],
|
||||
[$2.foo = 1;],
|
||||
gt_cv_var=no,
|
||||
gt_cv_var=yes)])
|
||||
AC_MSG_RESULT([$gt_cv_var])
|
||||
if test $gt_cv_var = yes; then
|
||||
AC_DEFINE([HAVE_]translit($2, [a-z], [A-Z])[_DECL], 1,
|
||||
[Define if you have the declaration of $2.])
|
||||
fi
|
||||
undefine([gt_cv_var])
|
||||
])
|
|
@ -15,23 +15,30 @@
|
|||
|
||||
|
||||
# Specification in the form of a command-line invocation:
|
||||
# gnulib-tool --import --dir=. --lib=libgnu --source-base=lib --m4-base=m4 --doc-base=doc --tests-base=tests --aux-dir=build-aux --lgpl --libtool --macro-prefix=gl --no-vc-files alloca-opt autobuild count-one-bits extensions flock fpieee full-read full-write putenv stdlib strcase strftime
|
||||
# gnulib-tool --import --dir=. --lib=libgnu --source-base=lib --m4-base=m4 --doc-base=doc --tests-base=tests --aux-dir=build-aux --lgpl --libtool --macro-prefix=gl --no-vc-files alloca-opt autobuild byteswap count-one-bits environ extensions flock fpieee full-read full-write iconv_open-utf lib-symbol-visibility libunistring putenv stdlib strcase strftime striconveh string
|
||||
|
||||
# Specification in the form of a few gnulib-tool.m4 macro invocations:
|
||||
gl_LOCAL_DIR([])
|
||||
gl_MODULES([
|
||||
alloca-opt
|
||||
autobuild
|
||||
byteswap
|
||||
count-one-bits
|
||||
environ
|
||||
extensions
|
||||
flock
|
||||
fpieee
|
||||
full-read
|
||||
full-write
|
||||
iconv_open-utf
|
||||
lib-symbol-visibility
|
||||
libunistring
|
||||
putenv
|
||||
stdlib
|
||||
strcase
|
||||
strftime
|
||||
striconveh
|
||||
string
|
||||
])
|
||||
gl_AVOID([])
|
||||
gl_SOURCE_BASE([lib])
|
||||
|
|
|
@ -25,6 +25,7 @@ AC_DEFUN([gl_EARLY],
|
|||
m4_pattern_allow([^gl_LIBOBJS$])dnl a variable
|
||||
m4_pattern_allow([^gl_LTLIBOBJS$])dnl a variable
|
||||
AC_REQUIRE([AC_PROG_RANLIB])
|
||||
AC_REQUIRE([AM_PROG_CC_C_O])
|
||||
AB_INIT
|
||||
AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS])
|
||||
AC_REQUIRE([gl_FP_IEEE])
|
||||
|
@ -44,10 +45,19 @@ AC_DEFUN([gl_INIT],
|
|||
gl_COMMON
|
||||
gl_source_base='lib'
|
||||
gl_FUNC_ALLOCA
|
||||
gl_BYTESWAP
|
||||
gl_COUNT_ONE_BITS
|
||||
gl_ENVIRON
|
||||
gl_UNISTD_MODULE_INDICATOR([environ])
|
||||
gl_FUNC_FLOCK
|
||||
gl_HEADER_SYS_FILE_MODULE_INDICATOR([flock])
|
||||
AM_ICONV
|
||||
gl_ICONV_H
|
||||
gl_FUNC_ICONV_OPEN
|
||||
gl_FUNC_ICONV_OPEN_UTF
|
||||
gl_INLINE
|
||||
gl_VISIBILITY
|
||||
gl_LIBUNISTRING
|
||||
gl_LOCALCHARSET
|
||||
LOCALCHARSET_TESTS_ENVIRONMENT="CHARSETALIASDIR=\"\$(top_builddir)/$gl_source_base\""
|
||||
AC_SUBST([LOCALCHARSET_TESTS_ENVIRONMENT])
|
||||
|
@ -70,12 +80,21 @@ AC_DEFUN([gl_INIT],
|
|||
gl_STDLIB_H
|
||||
gl_STRCASE
|
||||
gl_FUNC_GNU_STRFTIME
|
||||
if test $gl_cond_libtool = false; then
|
||||
gl_ltlibdeps="$gl_ltlibdeps $LTLIBICONV"
|
||||
gl_libdeps="$gl_libdeps $LIBICONV"
|
||||
fi
|
||||
gl_HEADER_STRING_H
|
||||
gl_HEADER_STRINGS_H
|
||||
gl_HEADER_SYS_FILE_H
|
||||
AC_PROG_MKDIR_P
|
||||
gl_HEADER_TIME_H
|
||||
gl_TIME_R
|
||||
gl_UNISTD_H
|
||||
gl_MODULE_INDICATOR([unistr/u8-mbtouc])
|
||||
gl_MODULE_INDICATOR([unistr/u8-mbtouc-unsafe])
|
||||
gl_MODULE_INDICATOR([unistr/u8-mbtoucr])
|
||||
gl_MODULE_INDICATOR([unistr/u8-uctomb])
|
||||
gl_WCHAR_H
|
||||
gl_FUNC_WRITE
|
||||
gl_UNISTD_MODULE_INDICATOR([write])
|
||||
|
@ -207,8 +226,16 @@ AC_DEFUN([gltests_LIBSOURCES], [
|
|||
# This macro records the list of files which have been installed by
|
||||
# gnulib-tool and may be removed by future gnulib-tool invocations.
|
||||
AC_DEFUN([gl_FILE_LIST], [
|
||||
build-aux/config.rpath
|
||||
build-aux/link-warning.h
|
||||
lib/alloca.in.h
|
||||
lib/byteswap.in.h
|
||||
lib/c-ctype.c
|
||||
lib/c-ctype.h
|
||||
lib/c-strcase.h
|
||||
lib/c-strcasecmp.c
|
||||
lib/c-strcaseeq.h
|
||||
lib/c-strncasecmp.c
|
||||
lib/config.charset
|
||||
lib/count-one-bits.h
|
||||
lib/flock.c
|
||||
|
@ -216,6 +243,15 @@ AC_DEFUN([gl_FILE_LIST], [
|
|||
lib/full-read.h
|
||||
lib/full-write.c
|
||||
lib/full-write.h
|
||||
lib/iconv.c
|
||||
lib/iconv.in.h
|
||||
lib/iconv_close.c
|
||||
lib/iconv_open-aix.gperf
|
||||
lib/iconv_open-hpux.gperf
|
||||
lib/iconv_open-irix.gperf
|
||||
lib/iconv_open-osf.gperf
|
||||
lib/iconv_open.c
|
||||
lib/iconveh.h
|
||||
lib/localcharset.c
|
||||
lib/localcharset.h
|
||||
lib/malloc.c
|
||||
|
@ -236,27 +272,49 @@ AC_DEFUN([gl_FILE_LIST], [
|
|||
lib/streq.h
|
||||
lib/strftime.c
|
||||
lib/strftime.h
|
||||
lib/striconveh.c
|
||||
lib/striconveh.h
|
||||
lib/string.in.h
|
||||
lib/strings.in.h
|
||||
lib/strncasecmp.c
|
||||
lib/sys_file.in.h
|
||||
lib/time.in.h
|
||||
lib/time_r.c
|
||||
lib/unistd.in.h
|
||||
lib/unistr.h
|
||||
lib/unistr/u8-mbtouc-aux.c
|
||||
lib/unistr/u8-mbtouc-unsafe-aux.c
|
||||
lib/unistr/u8-mbtouc-unsafe.c
|
||||
lib/unistr/u8-mbtouc.c
|
||||
lib/unistr/u8-mbtoucr.c
|
||||
lib/unistr/u8-prev.c
|
||||
lib/unistr/u8-uctomb-aux.c
|
||||
lib/unistr/u8-uctomb.c
|
||||
lib/unitypes.h
|
||||
lib/verify.h
|
||||
lib/wchar.in.h
|
||||
lib/write.c
|
||||
m4/00gnulib.m4
|
||||
m4/alloca.m4
|
||||
m4/autobuild.m4
|
||||
m4/byteswap.m4
|
||||
m4/codeset.m4
|
||||
m4/count-one-bits.m4
|
||||
m4/environ.m4
|
||||
m4/extensions.m4
|
||||
m4/flock.m4
|
||||
m4/fpieee.m4
|
||||
m4/glibc21.m4
|
||||
m4/gnulib-common.m4
|
||||
m4/iconv.m4
|
||||
m4/iconv_h.m4
|
||||
m4/iconv_open.m4
|
||||
m4/include_next.m4
|
||||
m4/inline.m4
|
||||
m4/lib-ld.m4
|
||||
m4/lib-link.m4
|
||||
m4/lib-prefix.m4
|
||||
m4/libunistring.m4
|
||||
m4/localcharset.m4
|
||||
m4/locale-fr.m4
|
||||
m4/locale-ja.m4
|
||||
|
@ -277,12 +335,14 @@ AC_DEFUN([gl_FILE_LIST], [
|
|||
m4/stdlib_h.m4
|
||||
m4/strcase.m4
|
||||
m4/strftime.m4
|
||||
m4/string_h.m4
|
||||
m4/strings_h.m4
|
||||
m4/sys_file_h.m4
|
||||
m4/time_h.m4
|
||||
m4/time_r.m4
|
||||
m4/tm_gmtoff.m4
|
||||
m4/unistd_h.m4
|
||||
m4/visibility.m4
|
||||
m4/wchar.m4
|
||||
m4/wint_t.m4
|
||||
m4/write.m4
|
||||
|
|
180
m4/iconv.m4
Normal file
180
m4/iconv.m4
Normal file
|
@ -0,0 +1,180 @@
|
|||
# iconv.m4 serial AM7 (gettext-0.18)
|
||||
dnl Copyright (C) 2000-2002, 2007-2009 Free Software Foundation, Inc.
|
||||
dnl This file is free software; the Free Software Foundation
|
||||
dnl gives unlimited permission to copy and/or distribute it,
|
||||
dnl with or without modifications, as long as this notice is preserved.
|
||||
|
||||
dnl From Bruno Haible.
|
||||
|
||||
AC_DEFUN([AM_ICONV_LINKFLAGS_BODY],
|
||||
[
|
||||
dnl Prerequisites of AC_LIB_LINKFLAGS_BODY.
|
||||
AC_REQUIRE([AC_LIB_PREPARE_PREFIX])
|
||||
AC_REQUIRE([AC_LIB_RPATH])
|
||||
|
||||
dnl Search for libiconv and define LIBICONV, LTLIBICONV and INCICONV
|
||||
dnl accordingly.
|
||||
AC_LIB_LINKFLAGS_BODY([iconv])
|
||||
])
|
||||
|
||||
AC_DEFUN([AM_ICONV_LINK],
|
||||
[
|
||||
dnl Some systems have iconv in libc, some have it in libiconv (OSF/1 and
|
||||
dnl those with the standalone portable GNU libiconv installed).
|
||||
AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
|
||||
|
||||
dnl Search for libiconv and define LIBICONV, LTLIBICONV and INCICONV
|
||||
dnl accordingly.
|
||||
AC_REQUIRE([AM_ICONV_LINKFLAGS_BODY])
|
||||
|
||||
dnl Add $INCICONV to CPPFLAGS before performing the following checks,
|
||||
dnl because if the user has installed libiconv and not disabled its use
|
||||
dnl via --without-libiconv-prefix, he wants to use it. The first
|
||||
dnl AC_TRY_LINK will then fail, the second AC_TRY_LINK will succeed.
|
||||
am_save_CPPFLAGS="$CPPFLAGS"
|
||||
AC_LIB_APPENDTOVAR([CPPFLAGS], [$INCICONV])
|
||||
|
||||
AC_CACHE_CHECK([for iconv], [am_cv_func_iconv], [
|
||||
am_cv_func_iconv="no, consider installing GNU libiconv"
|
||||
am_cv_lib_iconv=no
|
||||
AC_TRY_LINK([#include <stdlib.h>
|
||||
#include <iconv.h>],
|
||||
[iconv_t cd = iconv_open("","");
|
||||
iconv(cd,NULL,NULL,NULL,NULL);
|
||||
iconv_close(cd);],
|
||||
[am_cv_func_iconv=yes])
|
||||
if test "$am_cv_func_iconv" != yes; then
|
||||
am_save_LIBS="$LIBS"
|
||||
LIBS="$LIBS $LIBICONV"
|
||||
AC_TRY_LINK([#include <stdlib.h>
|
||||
#include <iconv.h>],
|
||||
[iconv_t cd = iconv_open("","");
|
||||
iconv(cd,NULL,NULL,NULL,NULL);
|
||||
iconv_close(cd);],
|
||||
[am_cv_lib_iconv=yes]
|
||||
[am_cv_func_iconv=yes])
|
||||
LIBS="$am_save_LIBS"
|
||||
fi
|
||||
])
|
||||
if test "$am_cv_func_iconv" = yes; then
|
||||
AC_CACHE_CHECK([for working iconv], [am_cv_func_iconv_works], [
|
||||
dnl This tests against bugs in AIX 5.1 and HP-UX 11.11.
|
||||
am_save_LIBS="$LIBS"
|
||||
if test $am_cv_lib_iconv = yes; then
|
||||
LIBS="$LIBS $LIBICONV"
|
||||
fi
|
||||
AC_TRY_RUN([
|
||||
#include <iconv.h>
|
||||
#include <string.h>
|
||||
int main ()
|
||||
{
|
||||
/* Test against AIX 5.1 bug: Failures are not distinguishable from successful
|
||||
returns. */
|
||||
{
|
||||
iconv_t cd_utf8_to_88591 = iconv_open ("ISO8859-1", "UTF-8");
|
||||
if (cd_utf8_to_88591 != (iconv_t)(-1))
|
||||
{
|
||||
static const char input[] = "\342\202\254"; /* EURO SIGN */
|
||||
char buf[10];
|
||||
const char *inptr = input;
|
||||
size_t inbytesleft = strlen (input);
|
||||
char *outptr = buf;
|
||||
size_t outbytesleft = sizeof (buf);
|
||||
size_t res = iconv (cd_utf8_to_88591,
|
||||
(char **) &inptr, &inbytesleft,
|
||||
&outptr, &outbytesleft);
|
||||
if (res == 0)
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
#if 0 /* This bug could be worked around by the caller. */
|
||||
/* Test against HP-UX 11.11 bug: Positive return value instead of 0. */
|
||||
{
|
||||
iconv_t cd_88591_to_utf8 = iconv_open ("utf8", "iso88591");
|
||||
if (cd_88591_to_utf8 != (iconv_t)(-1))
|
||||
{
|
||||
static const char input[] = "\304rger mit b\366sen B\374bchen ohne Augenma\337";
|
||||
char buf[50];
|
||||
const char *inptr = input;
|
||||
size_t inbytesleft = strlen (input);
|
||||
char *outptr = buf;
|
||||
size_t outbytesleft = sizeof (buf);
|
||||
size_t res = iconv (cd_88591_to_utf8,
|
||||
(char **) &inptr, &inbytesleft,
|
||||
&outptr, &outbytesleft);
|
||||
if ((int)res > 0)
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
/* Test against HP-UX 11.11 bug: No converter from EUC-JP to UTF-8 is
|
||||
provided. */
|
||||
if (/* Try standardized names. */
|
||||
iconv_open ("UTF-8", "EUC-JP") == (iconv_t)(-1)
|
||||
/* Try IRIX, OSF/1 names. */
|
||||
&& iconv_open ("UTF-8", "eucJP") == (iconv_t)(-1)
|
||||
/* Try AIX names. */
|
||||
&& iconv_open ("UTF-8", "IBM-eucJP") == (iconv_t)(-1)
|
||||
/* Try HP-UX names. */
|
||||
&& iconv_open ("utf8", "eucJP") == (iconv_t)(-1))
|
||||
return 1;
|
||||
return 0;
|
||||
}], [am_cv_func_iconv_works=yes], [am_cv_func_iconv_works=no],
|
||||
[case "$host_os" in
|
||||
aix* | hpux*) am_cv_func_iconv_works="guessing no" ;;
|
||||
*) am_cv_func_iconv_works="guessing yes" ;;
|
||||
esac])
|
||||
LIBS="$am_save_LIBS"
|
||||
])
|
||||
case "$am_cv_func_iconv_works" in
|
||||
*no) am_func_iconv=no am_cv_lib_iconv=no ;;
|
||||
*) am_func_iconv=yes ;;
|
||||
esac
|
||||
else
|
||||
am_func_iconv=no am_cv_lib_iconv=no
|
||||
fi
|
||||
if test "$am_func_iconv" = yes; then
|
||||
AC_DEFINE([HAVE_ICONV], [1],
|
||||
[Define if you have the iconv() function and it works.])
|
||||
fi
|
||||
if test "$am_cv_lib_iconv" = yes; then
|
||||
AC_MSG_CHECKING([how to link with libiconv])
|
||||
AC_MSG_RESULT([$LIBICONV])
|
||||
else
|
||||
dnl If $LIBICONV didn't lead to a usable library, we don't need $INCICONV
|
||||
dnl either.
|
||||
CPPFLAGS="$am_save_CPPFLAGS"
|
||||
LIBICONV=
|
||||
LTLIBICONV=
|
||||
fi
|
||||
AC_SUBST([LIBICONV])
|
||||
AC_SUBST([LTLIBICONV])
|
||||
])
|
||||
|
||||
AC_DEFUN([AM_ICONV],
|
||||
[
|
||||
AM_ICONV_LINK
|
||||
if test "$am_cv_func_iconv" = yes; then
|
||||
AC_MSG_CHECKING([for iconv declaration])
|
||||
AC_CACHE_VAL([am_cv_proto_iconv], [
|
||||
AC_TRY_COMPILE([
|
||||
#include <stdlib.h>
|
||||
#include <iconv.h>
|
||||
extern
|
||||
#ifdef __cplusplus
|
||||
"C"
|
||||
#endif
|
||||
#if defined(__STDC__) || defined(__cplusplus)
|
||||
size_t iconv (iconv_t cd, char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft);
|
||||
#else
|
||||
size_t iconv();
|
||||
#endif
|
||||
], [], [am_cv_proto_iconv_arg1=""], [am_cv_proto_iconv_arg1="const"])
|
||||
am_cv_proto_iconv="extern size_t iconv (iconv_t cd, $am_cv_proto_iconv_arg1 char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft);"])
|
||||
am_cv_proto_iconv=`echo "[$]am_cv_proto_iconv" | tr -s ' ' | sed -e 's/( /(/'`
|
||||
AC_MSG_RESULT([${ac_t:-
|
||||
}$am_cv_proto_iconv])
|
||||
AC_DEFINE_UNQUOTED([ICONV_CONST], [$am_cv_proto_iconv_arg1],
|
||||
[Define as const if the declaration of iconv() needs const.])
|
||||
fi
|
||||
])
|
34
m4/iconv_h.m4
Normal file
34
m4/iconv_h.m4
Normal file
|
@ -0,0 +1,34 @@
|
|||
# iconv_h.m4 serial 4
|
||||
dnl Copyright (C) 2007-2008 Free Software Foundation, Inc.
|
||||
dnl This file is free software; the Free Software Foundation
|
||||
dnl gives unlimited permission to copy and/or distribute it,
|
||||
dnl with or without modifications, as long as this notice is preserved.
|
||||
|
||||
AC_DEFUN([gl_ICONV_H],
|
||||
[
|
||||
AC_REQUIRE([gl_ICONV_H_DEFAULTS])
|
||||
gl_CHECK_NEXT_HEADERS([iconv.h])
|
||||
])
|
||||
|
||||
dnl Unconditionally enables the replacement of <iconv.h>.
|
||||
AC_DEFUN([gl_REPLACE_ICONV_H],
|
||||
[
|
||||
AC_REQUIRE([gl_ICONV_H_DEFAULTS])
|
||||
ICONV_H='iconv.h'
|
||||
])
|
||||
|
||||
AC_DEFUN([gl_ICONV_MODULE_INDICATOR],
|
||||
[
|
||||
dnl Use AC_REQUIRE here, so that the default settings are expanded once only.
|
||||
AC_REQUIRE([gl_ICONV_H_DEFAULTS])
|
||||
GNULIB_[]m4_translit([$1],[abcdefghijklmnopqrstuvwxyz./-],[ABCDEFGHIJKLMNOPQRSTUVWXYZ___])=1
|
||||
])
|
||||
|
||||
AC_DEFUN([gl_ICONV_H_DEFAULTS],
|
||||
[
|
||||
dnl Assume proper GNU behavior unless another module says otherwise.
|
||||
REPLACE_ICONV=0; AC_SUBST([REPLACE_ICONV])
|
||||
REPLACE_ICONV_OPEN=0; AC_SUBST([REPLACE_ICONV_OPEN])
|
||||
REPLACE_ICONV_UTF=0; AC_SUBST([REPLACE_ICONV_UTF])
|
||||
ICONV_H=''; AC_SUBST([ICONV_H])
|
||||
])
|
237
m4/iconv_open.m4
Normal file
237
m4/iconv_open.m4
Normal file
|
@ -0,0 +1,237 @@
|
|||
# iconv_open.m4 serial 5
|
||||
dnl Copyright (C) 2007-2009 Free Software Foundation, Inc.
|
||||
dnl This file is free software; the Free Software Foundation
|
||||
dnl gives unlimited permission to copy and/or distribute it,
|
||||
dnl with or without modifications, as long as this notice is preserved.
|
||||
|
||||
AC_DEFUN([gl_FUNC_ICONV_OPEN],
|
||||
[
|
||||
AC_REQUIRE([AM_ICONV])
|
||||
AC_REQUIRE([AC_CANONICAL_HOST])
|
||||
AC_REQUIRE([gl_ICONV_H_DEFAULTS])
|
||||
if test "$am_cv_func_iconv" = yes; then
|
||||
dnl Test whether iconv_open accepts standardized encoding names.
|
||||
dnl We know that GNU libiconv and GNU libc do.
|
||||
AC_EGREP_CPP([gnu_iconv], [
|
||||
#include <iconv.h>
|
||||
#if defined _LIBICONV_VERSION || defined __GLIBC__
|
||||
gnu_iconv
|
||||
#endif
|
||||
], [gl_func_iconv_gnu=yes], [gl_func_iconv_gnu=no])
|
||||
if test $gl_func_iconv_gnu = no; then
|
||||
iconv_flavor=
|
||||
case "$host_os" in
|
||||
aix*) iconv_flavor=ICONV_FLAVOR_AIX ;;
|
||||
irix*) iconv_flavor=ICONV_FLAVOR_IRIX ;;
|
||||
hpux*) iconv_flavor=ICONV_FLAVOR_HPUX ;;
|
||||
osf*) iconv_flavor=ICONV_FLAVOR_OSF ;;
|
||||
esac
|
||||
if test -n "$iconv_flavor"; then
|
||||
AC_DEFINE_UNQUOTED([ICONV_FLAVOR], [$iconv_flavor],
|
||||
[Define to a symbolic name denoting the flavor of iconv_open()
|
||||
implementation.])
|
||||
gl_REPLACE_ICONV_OPEN
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
])
|
||||
|
||||
AC_DEFUN([gl_REPLACE_ICONV_OPEN],
|
||||
[
|
||||
gl_REPLACE_ICONV_H
|
||||
REPLACE_ICONV_OPEN=1
|
||||
AC_LIBOBJ([iconv_open])
|
||||
])
|
||||
|
||||
AC_DEFUN([gl_FUNC_ICONV_OPEN_UTF],
|
||||
[
|
||||
AC_REQUIRE([gl_FUNC_ICONV_OPEN])
|
||||
AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
|
||||
AC_REQUIRE([gl_ICONV_H_DEFAULTS])
|
||||
if test "$am_cv_func_iconv" = yes; then
|
||||
if test -n "$am_cv_proto_iconv_arg1"; then
|
||||
ICONV_CONST="const"
|
||||
else
|
||||
ICONV_CONST=
|
||||
fi
|
||||
AC_SUBST([ICONV_CONST])
|
||||
AC_CACHE_CHECK([whether iconv supports conversion between UTF-8 and UTF-{16,32}{BE,LE}],
|
||||
[gl_cv_func_iconv_supports_utf],
|
||||
[
|
||||
save_LIBS="$LIBS"
|
||||
LIBS="$LIBS $LIBICONV"
|
||||
AC_TRY_RUN([
|
||||
#include <iconv.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#define ASSERT(expr) if (!(expr)) return 1;
|
||||
int main ()
|
||||
{
|
||||
/* Test conversion from UTF-8 to UTF-16BE with no errors. */
|
||||
{
|
||||
static const char input[] =
|
||||
"Japanese (\346\227\245\346\234\254\350\252\236) [\360\235\224\215\360\235\224\236\360\235\224\255]";
|
||||
static const char expected[] =
|
||||
"\000J\000a\000p\000a\000n\000e\000s\000e\000 \000(\145\345\147\054\212\236\000)\000 \000[\330\065\335\015\330\065\335\036\330\065\335\055\000]";
|
||||
iconv_t cd;
|
||||
char buf[100];
|
||||
const char *inptr;
|
||||
size_t inbytesleft;
|
||||
char *outptr;
|
||||
size_t outbytesleft;
|
||||
size_t res;
|
||||
cd = iconv_open ("UTF-16BE", "UTF-8");
|
||||
ASSERT (cd != (iconv_t)(-1));
|
||||
inptr = input;
|
||||
inbytesleft = sizeof (input) - 1;
|
||||
outptr = buf;
|
||||
outbytesleft = sizeof (buf);
|
||||
res = iconv (cd,
|
||||
(ICONV_CONST char **) &inptr, &inbytesleft,
|
||||
&outptr, &outbytesleft);
|
||||
ASSERT (res == 0 && inbytesleft == 0);
|
||||
ASSERT (outptr == buf + (sizeof (expected) - 1));
|
||||
ASSERT (memcmp (buf, expected, sizeof (expected) - 1) == 0);
|
||||
ASSERT (iconv_close (cd) == 0);
|
||||
}
|
||||
/* Test conversion from UTF-8 to UTF-16LE with no errors. */
|
||||
{
|
||||
static const char input[] =
|
||||
"Japanese (\346\227\245\346\234\254\350\252\236) [\360\235\224\215\360\235\224\236\360\235\224\255]";
|
||||
static const char expected[] =
|
||||
"J\000a\000p\000a\000n\000e\000s\000e\000 \000(\000\345\145\054\147\236\212)\000 \000[\000\065\330\015\335\065\330\036\335\065\330\055\335]\000";
|
||||
iconv_t cd;
|
||||
char buf[100];
|
||||
const char *inptr;
|
||||
size_t inbytesleft;
|
||||
char *outptr;
|
||||
size_t outbytesleft;
|
||||
size_t res;
|
||||
cd = iconv_open ("UTF-16LE", "UTF-8");
|
||||
ASSERT (cd != (iconv_t)(-1));
|
||||
inptr = input;
|
||||
inbytesleft = sizeof (input) - 1;
|
||||
outptr = buf;
|
||||
outbytesleft = sizeof (buf);
|
||||
res = iconv (cd,
|
||||
(ICONV_CONST char **) &inptr, &inbytesleft,
|
||||
&outptr, &outbytesleft);
|
||||
ASSERT (res == 0 && inbytesleft == 0);
|
||||
ASSERT (outptr == buf + (sizeof (expected) - 1));
|
||||
ASSERT (memcmp (buf, expected, sizeof (expected) - 1) == 0);
|
||||
ASSERT (iconv_close (cd) == 0);
|
||||
}
|
||||
/* Test conversion from UTF-8 to UTF-32BE with no errors. */
|
||||
{
|
||||
static const char input[] =
|
||||
"Japanese (\346\227\245\346\234\254\350\252\236) [\360\235\224\215\360\235\224\236\360\235\224\255]";
|
||||
static const char expected[] =
|
||||
"\000\000\000J\000\000\000a\000\000\000p\000\000\000a\000\000\000n\000\000\000e\000\000\000s\000\000\000e\000\000\000 \000\000\000(\000\000\145\345\000\000\147\054\000\000\212\236\000\000\000)\000\000\000 \000\000\000[\000\001\325\015\000\001\325\036\000\001\325\055\000\000\000]";
|
||||
iconv_t cd;
|
||||
char buf[100];
|
||||
const char *inptr;
|
||||
size_t inbytesleft;
|
||||
char *outptr;
|
||||
size_t outbytesleft;
|
||||
size_t res;
|
||||
cd = iconv_open ("UTF-32BE", "UTF-8");
|
||||
ASSERT (cd != (iconv_t)(-1));
|
||||
inptr = input;
|
||||
inbytesleft = sizeof (input) - 1;
|
||||
outptr = buf;
|
||||
outbytesleft = sizeof (buf);
|
||||
res = iconv (cd,
|
||||
(ICONV_CONST char **) &inptr, &inbytesleft,
|
||||
&outptr, &outbytesleft);
|
||||
ASSERT (res == 0 && inbytesleft == 0);
|
||||
ASSERT (outptr == buf + (sizeof (expected) - 1));
|
||||
ASSERT (memcmp (buf, expected, sizeof (expected) - 1) == 0);
|
||||
ASSERT (iconv_close (cd) == 0);
|
||||
}
|
||||
/* Test conversion from UTF-8 to UTF-32LE with no errors. */
|
||||
{
|
||||
static const char input[] =
|
||||
"Japanese (\346\227\245\346\234\254\350\252\236) [\360\235\224\215\360\235\224\236\360\235\224\255]";
|
||||
static const char expected[] =
|
||||
"J\000\000\000a\000\000\000p\000\000\000a\000\000\000n\000\000\000e\000\000\000s\000\000\000e\000\000\000 \000\000\000(\000\000\000\345\145\000\000\054\147\000\000\236\212\000\000)\000\000\000 \000\000\000[\000\000\000\015\325\001\000\036\325\001\000\055\325\001\000]\000\000\000";
|
||||
iconv_t cd;
|
||||
char buf[100];
|
||||
const char *inptr;
|
||||
size_t inbytesleft;
|
||||
char *outptr;
|
||||
size_t outbytesleft;
|
||||
size_t res;
|
||||
cd = iconv_open ("UTF-32LE", "UTF-8");
|
||||
ASSERT (cd != (iconv_t)(-1));
|
||||
inptr = input;
|
||||
inbytesleft = sizeof (input) - 1;
|
||||
outptr = buf;
|
||||
outbytesleft = sizeof (buf);
|
||||
res = iconv (cd,
|
||||
(ICONV_CONST char **) &inptr, &inbytesleft,
|
||||
&outptr, &outbytesleft);
|
||||
ASSERT (res == 0 && inbytesleft == 0);
|
||||
ASSERT (outptr == buf + (sizeof (expected) - 1));
|
||||
ASSERT (memcmp (buf, expected, sizeof (expected) - 1) == 0);
|
||||
ASSERT (iconv_close (cd) == 0);
|
||||
}
|
||||
/* Test conversion from UTF-16BE to UTF-8 with no errors.
|
||||
This test fails on NetBSD 3.0. */
|
||||
{
|
||||
static const char input[] =
|
||||
"\000J\000a\000p\000a\000n\000e\000s\000e\000 \000(\145\345\147\054\212\236\000)\000 \000[\330\065\335\015\330\065\335\036\330\065\335\055\000]";
|
||||
static const char expected[] =
|
||||
"Japanese (\346\227\245\346\234\254\350\252\236) [\360\235\224\215\360\235\224\236\360\235\224\255]";
|
||||
iconv_t cd;
|
||||
char buf[100];
|
||||
const char *inptr;
|
||||
size_t inbytesleft;
|
||||
char *outptr;
|
||||
size_t outbytesleft;
|
||||
size_t res;
|
||||
cd = iconv_open ("UTF-8", "UTF-16BE");
|
||||
ASSERT (cd != (iconv_t)(-1));
|
||||
inptr = input;
|
||||
inbytesleft = sizeof (input) - 1;
|
||||
outptr = buf;
|
||||
outbytesleft = sizeof (buf);
|
||||
res = iconv (cd,
|
||||
(ICONV_CONST char **) &inptr, &inbytesleft,
|
||||
&outptr, &outbytesleft);
|
||||
ASSERT (res == 0 && inbytesleft == 0);
|
||||
ASSERT (outptr == buf + (sizeof (expected) - 1));
|
||||
ASSERT (memcmp (buf, expected, sizeof (expected) - 1) == 0);
|
||||
ASSERT (iconv_close (cd) == 0);
|
||||
}
|
||||
return 0;
|
||||
}], [gl_cv_func_iconv_supports_utf=yes], [gl_cv_func_iconv_supports_utf=no],
|
||||
[
|
||||
dnl We know that GNU libiconv, GNU libc, and Solaris >= 9 do.
|
||||
dnl OSF/1 5.1 has these encodings, but inserts a BOM in the "to"
|
||||
dnl direction.
|
||||
gl_cv_func_iconv_supports_utf=no
|
||||
if test $gl_func_iconv_gnu = yes; then
|
||||
gl_cv_func_iconv_supports_utf=yes
|
||||
else
|
||||
changequote(,)dnl
|
||||
case "$host_os" in
|
||||
solaris2.9 | solaris2.1[0-9]) gl_cv_func_iconv_supports_utf=yes ;;
|
||||
esac
|
||||
changequote([,])dnl
|
||||
fi
|
||||
])
|
||||
LIBS="$save_LIBS"
|
||||
])
|
||||
if test $gl_cv_func_iconv_supports_utf = no; then
|
||||
REPLACE_ICONV_UTF=1
|
||||
AC_DEFINE([REPLACE_ICONV_UTF], [1],
|
||||
[Define if the iconv() functions are enhanced to handle the UTF-{16,32}{BE,LE} encodings.])
|
||||
REPLACE_ICONV=1
|
||||
gl_REPLACE_ICONV_OPEN
|
||||
AC_LIBOBJ([iconv])
|
||||
AC_LIBOBJ([iconv_close])
|
||||
fi
|
||||
fi
|
||||
])
|
|
@ -1,4 +1,4 @@
|
|||
# include_next.m4 serial 12
|
||||
# include_next.m4 serial 14
|
||||
dnl Copyright (C) 2006-2009 Free Software Foundation, Inc.
|
||||
dnl This file is free software; the Free Software Foundation
|
||||
dnl gives unlimited permission to copy and/or distribute it,
|
||||
|
@ -104,8 +104,14 @@ EOF
|
|||
# For each arg foo.h, if #include_next works, define NEXT_FOO_H to be
|
||||
# '<foo.h>'; otherwise define it to be
|
||||
# '"///usr/include/foo.h"', or whatever other absolute file name is suitable.
|
||||
# Also, if #include_next works as first preprocessing directive in a file,
|
||||
# define NEXT_AS_FIRST_DIRECTIVE_FOO_H to be '<foo.h>'; otherwise define it to
|
||||
# be
|
||||
# '"///usr/include/foo.h"', or whatever other absolute file name is suitable.
|
||||
# That way, a header file with the following line:
|
||||
# #@INCLUDE_NEXT@ @NEXT_FOO_H@
|
||||
# or
|
||||
# #@INCLUDE_NEXT_AS_FIRST_DIRECTIVE@ @NEXT_AS_FIRST_DIRECTIVE_FOO_H@
|
||||
# behaves (after sed substitution) as if it contained
|
||||
# #include_next <foo.h>
|
||||
# even if the compiler does not support include_next.
|
||||
|
@ -123,15 +129,15 @@ AC_DEFUN([gl_CHECK_NEXT_HEADERS],
|
|||
|
||||
m4_foreach_w([gl_HEADER_NAME], [$1],
|
||||
[AS_VAR_PUSHDEF([gl_next_header],
|
||||
[gl_cv_next_]m4_quote(m4_defn([gl_HEADER_NAME])))
|
||||
[gl_cv_next_]m4_defn([gl_HEADER_NAME]))
|
||||
if test $gl_cv_have_include_next = yes; then
|
||||
AS_VAR_SET([gl_next_header], ['<'gl_HEADER_NAME'>'])
|
||||
else
|
||||
AC_CACHE_CHECK(
|
||||
[absolute name of <]m4_quote(m4_defn([gl_HEADER_NAME]))[>],
|
||||
m4_quote(m4_defn([gl_next_header])),
|
||||
[absolute name of <]m4_defn([gl_HEADER_NAME])[>],
|
||||
m4_defn([gl_next_header]),
|
||||
[AS_VAR_PUSHDEF([gl_header_exists],
|
||||
[ac_cv_header_]m4_quote(m4_defn([gl_HEADER_NAME])))
|
||||
[ac_cv_header_]m4_defn([gl_HEADER_NAME]))
|
||||
if test AS_VAR_GET(gl_header_exists) = yes; then
|
||||
AC_LANG_CONFTEST(
|
||||
[AC_LANG_SOURCE(
|
||||
|
@ -153,8 +159,8 @@ AC_DEFUN([gl_CHECK_NEXT_HEADERS],
|
|||
dnl so use subshell.
|
||||
AS_VAR_SET([gl_next_header],
|
||||
['"'`(eval "$gl_absname_cpp conftest.$ac_ext") 2>&AS_MESSAGE_LOG_FD |
|
||||
sed -n '\#/]m4_quote(m4_defn([gl_HEADER_NAME]))[#{
|
||||
s#.*"\(.*/]m4_quote(m4_defn([gl_HEADER_NAME]))[\)".*#\1#
|
||||
sed -n '\#/]m4_defn([gl_HEADER_NAME])[#{
|
||||
s#.*"\(.*/]m4_defn([gl_HEADER_NAME])[\)".*#\1#
|
||||
s#^/[^/]#//&#
|
||||
p
|
||||
q
|
||||
|
@ -165,7 +171,17 @@ AC_DEFUN([gl_CHECK_NEXT_HEADERS],
|
|||
AS_VAR_POPDEF([gl_header_exists])])
|
||||
fi
|
||||
AC_SUBST(
|
||||
AS_TR_CPP([NEXT_]m4_quote(m4_defn([gl_HEADER_NAME]))),
|
||||
AS_TR_CPP([NEXT_]m4_defn([gl_HEADER_NAME])),
|
||||
[AS_VAR_GET([gl_next_header])])
|
||||
if test $gl_cv_have_include_next = yes || test $gl_cv_have_include_next = buggy; then
|
||||
# INCLUDE_NEXT_AS_FIRST_DIRECTIVE='include_next'
|
||||
gl_next_as_first_directive='<'gl_HEADER_NAME'>'
|
||||
else
|
||||
# INCLUDE_NEXT_AS_FIRST_DIRECTIVE='include'
|
||||
gl_next_as_first_directive=AS_VAR_GET([gl_next_header])
|
||||
fi
|
||||
AC_SUBST(
|
||||
AS_TR_CPP([NEXT_AS_FIRST_DIRECTIVE_]m4_defn([gl_HEADER_NAME])),
|
||||
[$gl_next_as_first_directive])
|
||||
AS_VAR_POPDEF([gl_next_header])])
|
||||
])
|
||||
|
|
110
m4/lib-ld.m4
Normal file
110
m4/lib-ld.m4
Normal file
|
@ -0,0 +1,110 @@
|
|||
# lib-ld.m4 serial 4 (gettext-0.18)
|
||||
dnl Copyright (C) 1996-2003, 2009 Free Software Foundation, Inc.
|
||||
dnl This file is free software; the Free Software Foundation
|
||||
dnl gives unlimited permission to copy and/or distribute it,
|
||||
dnl with or without modifications, as long as this notice is preserved.
|
||||
|
||||
dnl Subroutines of libtool.m4,
|
||||
dnl with replacements s/AC_/AC_LIB/ and s/lt_cv/acl_cv/ to avoid collision
|
||||
dnl with libtool.m4.
|
||||
|
||||
dnl From libtool-1.4. Sets the variable with_gnu_ld to yes or no.
|
||||
AC_DEFUN([AC_LIB_PROG_LD_GNU],
|
||||
[AC_CACHE_CHECK([if the linker ($LD) is GNU ld], [acl_cv_prog_gnu_ld],
|
||||
[# I'd rather use --version here, but apparently some GNU ld's only accept -v.
|
||||
case `$LD -v 2>&1 </dev/null` in
|
||||
*GNU* | *'with BFD'*)
|
||||
acl_cv_prog_gnu_ld=yes ;;
|
||||
*)
|
||||
acl_cv_prog_gnu_ld=no ;;
|
||||
esac])
|
||||
with_gnu_ld=$acl_cv_prog_gnu_ld
|
||||
])
|
||||
|
||||
dnl From libtool-1.4. Sets the variable LD.
|
||||
AC_DEFUN([AC_LIB_PROG_LD],
|
||||
[AC_ARG_WITH([gnu-ld],
|
||||
[ --with-gnu-ld assume the C compiler uses GNU ld [default=no]],
|
||||
test "$withval" = no || with_gnu_ld=yes, with_gnu_ld=no)
|
||||
AC_REQUIRE([AC_PROG_CC])dnl
|
||||
AC_REQUIRE([AC_CANONICAL_HOST])dnl
|
||||
# Prepare PATH_SEPARATOR.
|
||||
# The user is always right.
|
||||
if test "${PATH_SEPARATOR+set}" != set; then
|
||||
echo "#! /bin/sh" >conf$$.sh
|
||||
echo "exit 0" >>conf$$.sh
|
||||
chmod +x conf$$.sh
|
||||
if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
|
||||
PATH_SEPARATOR=';'
|
||||
else
|
||||
PATH_SEPARATOR=:
|
||||
fi
|
||||
rm -f conf$$.sh
|
||||
fi
|
||||
ac_prog=ld
|
||||
if test "$GCC" = yes; then
|
||||
# Check if gcc -print-prog-name=ld gives a path.
|
||||
AC_MSG_CHECKING([for ld used by GCC])
|
||||
case $host in
|
||||
*-*-mingw*)
|
||||
# gcc leaves a trailing carriage return which upsets mingw
|
||||
ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;;
|
||||
*)
|
||||
ac_prog=`($CC -print-prog-name=ld) 2>&5` ;;
|
||||
esac
|
||||
case $ac_prog in
|
||||
# Accept absolute paths.
|
||||
[[\\/]* | [A-Za-z]:[\\/]*)]
|
||||
[re_direlt='/[^/][^/]*/\.\./']
|
||||
# Canonicalize the path of ld
|
||||
ac_prog=`echo $ac_prog| sed 's%\\\\%/%g'`
|
||||
while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do
|
||||
ac_prog=`echo $ac_prog| sed "s%$re_direlt%/%"`
|
||||
done
|
||||
test -z "$LD" && LD="$ac_prog"
|
||||
;;
|
||||
"")
|
||||
# If it fails, then pretend we aren't using GCC.
|
||||
ac_prog=ld
|
||||
;;
|
||||
*)
|
||||
# If it is relative, then search for the first ld in PATH.
|
||||
with_gnu_ld=unknown
|
||||
;;
|
||||
esac
|
||||
elif test "$with_gnu_ld" = yes; then
|
||||
AC_MSG_CHECKING([for GNU ld])
|
||||
else
|
||||
AC_MSG_CHECKING([for non-GNU ld])
|
||||
fi
|
||||
AC_CACHE_VAL([acl_cv_path_LD],
|
||||
[if test -z "$LD"; then
|
||||
IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR-:}"
|
||||
for ac_dir in $PATH; do
|
||||
test -z "$ac_dir" && ac_dir=.
|
||||
if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
|
||||
acl_cv_path_LD="$ac_dir/$ac_prog"
|
||||
# Check to see if the program is GNU ld. I'd rather use --version,
|
||||
# but apparently some GNU ld's only accept -v.
|
||||
# Break only if it was the GNU/non-GNU ld that we prefer.
|
||||
case `"$acl_cv_path_LD" -v 2>&1 < /dev/null` in
|
||||
*GNU* | *'with BFD'*)
|
||||
test "$with_gnu_ld" != no && break ;;
|
||||
*)
|
||||
test "$with_gnu_ld" != yes && break ;;
|
||||
esac
|
||||
fi
|
||||
done
|
||||
IFS="$ac_save_ifs"
|
||||
else
|
||||
acl_cv_path_LD="$LD" # Let the user override the test with a path.
|
||||
fi])
|
||||
LD="$acl_cv_path_LD"
|
||||
if test -n "$LD"; then
|
||||
AC_MSG_RESULT([$LD])
|
||||
else
|
||||
AC_MSG_RESULT([no])
|
||||
fi
|
||||
test -z "$LD" && AC_MSG_ERROR([no acceptable ld found in \$PATH])
|
||||
AC_LIB_PROG_LD_GNU
|
||||
])
|
761
m4/lib-link.m4
Normal file
761
m4/lib-link.m4
Normal file
|
@ -0,0 +1,761 @@
|
|||
# lib-link.m4 serial 19 (gettext-0.18)
|
||||
dnl Copyright (C) 2001-2009 Free Software Foundation, Inc.
|
||||
dnl This file is free software; the Free Software Foundation
|
||||
dnl gives unlimited permission to copy and/or distribute it,
|
||||
dnl with or without modifications, as long as this notice is preserved.
|
||||
|
||||
dnl From Bruno Haible.
|
||||
|
||||
AC_PREREQ([2.54])
|
||||
|
||||
dnl AC_LIB_LINKFLAGS(name [, dependencies]) searches for libname and
|
||||
dnl the libraries corresponding to explicit and implicit dependencies.
|
||||
dnl Sets and AC_SUBSTs the LIB${NAME} and LTLIB${NAME} variables and
|
||||
dnl augments the CPPFLAGS variable.
|
||||
dnl Sets and AC_SUBSTs the LIB${NAME}_PREFIX variable to nonempty if libname
|
||||
dnl was found in ${LIB${NAME}_PREFIX}/$acl_libdirstem.
|
||||
AC_DEFUN([AC_LIB_LINKFLAGS],
|
||||
[
|
||||
AC_REQUIRE([AC_LIB_PREPARE_PREFIX])
|
||||
AC_REQUIRE([AC_LIB_RPATH])
|
||||
pushdef([Name],[translit([$1],[./-], [___])])
|
||||
pushdef([NAME],[translit([$1],[abcdefghijklmnopqrstuvwxyz./-],
|
||||
[ABCDEFGHIJKLMNOPQRSTUVWXYZ___])])
|
||||
AC_CACHE_CHECK([how to link with lib[]$1], [ac_cv_lib[]Name[]_libs], [
|
||||
AC_LIB_LINKFLAGS_BODY([$1], [$2])
|
||||
ac_cv_lib[]Name[]_libs="$LIB[]NAME"
|
||||
ac_cv_lib[]Name[]_ltlibs="$LTLIB[]NAME"
|
||||
ac_cv_lib[]Name[]_cppflags="$INC[]NAME"
|
||||
ac_cv_lib[]Name[]_prefix="$LIB[]NAME[]_PREFIX"
|
||||
])
|
||||
LIB[]NAME="$ac_cv_lib[]Name[]_libs"
|
||||
LTLIB[]NAME="$ac_cv_lib[]Name[]_ltlibs"
|
||||
INC[]NAME="$ac_cv_lib[]Name[]_cppflags"
|
||||
LIB[]NAME[]_PREFIX="$ac_cv_lib[]Name[]_prefix"
|
||||
AC_LIB_APPENDTOVAR([CPPFLAGS], [$INC]NAME)
|
||||
AC_SUBST([LIB]NAME)
|
||||
AC_SUBST([LTLIB]NAME)
|
||||
AC_SUBST([LIB]NAME[_PREFIX])
|
||||
dnl Also set HAVE_LIB[]NAME so that AC_LIB_HAVE_LINKFLAGS can reuse the
|
||||
dnl results of this search when this library appears as a dependency.
|
||||
HAVE_LIB[]NAME=yes
|
||||
popdef([NAME])
|
||||
popdef([Name])
|
||||
])
|
||||
|
||||
dnl AC_LIB_HAVE_LINKFLAGS(name, dependencies, includes, testcode, [missing-message])
|
||||
dnl searches for libname and the libraries corresponding to explicit and
|
||||
dnl implicit dependencies, together with the specified include files and
|
||||
dnl the ability to compile and link the specified testcode. The missing-message
|
||||
dnl defaults to 'no' and may contain additional hints for the user.
|
||||
dnl If found, it sets and AC_SUBSTs HAVE_LIB${NAME}=yes and the LIB${NAME}
|
||||
dnl and LTLIB${NAME} variables and augments the CPPFLAGS variable, and
|
||||
dnl #defines HAVE_LIB${NAME} to 1. Otherwise, it sets and AC_SUBSTs
|
||||
dnl HAVE_LIB${NAME}=no and LIB${NAME} and LTLIB${NAME} to empty.
|
||||
dnl Sets and AC_SUBSTs the LIB${NAME}_PREFIX variable to nonempty if libname
|
||||
dnl was found in ${LIB${NAME}_PREFIX}/$acl_libdirstem.
|
||||
AC_DEFUN([AC_LIB_HAVE_LINKFLAGS],
|
||||
[
|
||||
AC_REQUIRE([AC_LIB_PREPARE_PREFIX])
|
||||
AC_REQUIRE([AC_LIB_RPATH])
|
||||
pushdef([Name],[translit([$1],[./-], [___])])
|
||||
pushdef([NAME],[translit([$1],[abcdefghijklmnopqrstuvwxyz./-],
|
||||
[ABCDEFGHIJKLMNOPQRSTUVWXYZ___])])
|
||||
|
||||
dnl Search for lib[]Name and define LIB[]NAME, LTLIB[]NAME and INC[]NAME
|
||||
dnl accordingly.
|
||||
AC_LIB_LINKFLAGS_BODY([$1], [$2])
|
||||
|
||||
dnl Add $INC[]NAME to CPPFLAGS before performing the following checks,
|
||||
dnl because if the user has installed lib[]Name and not disabled its use
|
||||
dnl via --without-lib[]Name-prefix, he wants to use it.
|
||||
ac_save_CPPFLAGS="$CPPFLAGS"
|
||||
AC_LIB_APPENDTOVAR([CPPFLAGS], [$INC]NAME)
|
||||
|
||||
AC_CACHE_CHECK([for lib[]$1], [ac_cv_lib[]Name], [
|
||||
ac_save_LIBS="$LIBS"
|
||||
LIBS="$LIBS $LIB[]NAME"
|
||||
AC_TRY_LINK([$3], [$4],
|
||||
[ac_cv_lib[]Name=yes],
|
||||
[ac_cv_lib[]Name='m4_if([$5], [], [no], [[$5]])'])
|
||||
LIBS="$ac_save_LIBS"
|
||||
])
|
||||
if test "$ac_cv_lib[]Name" = yes; then
|
||||
HAVE_LIB[]NAME=yes
|
||||
AC_DEFINE([HAVE_LIB]NAME, 1, [Define if you have the lib[]$1 library.])
|
||||
AC_MSG_CHECKING([how to link with lib[]$1])
|
||||
AC_MSG_RESULT([$LIB[]NAME])
|
||||
else
|
||||
HAVE_LIB[]NAME=no
|
||||
dnl If $LIB[]NAME didn't lead to a usable library, we don't need
|
||||
dnl $INC[]NAME either.
|
||||
CPPFLAGS="$ac_save_CPPFLAGS"
|
||||
LIB[]NAME=
|
||||
LTLIB[]NAME=
|
||||
LIB[]NAME[]_PREFIX=
|
||||
fi
|
||||
AC_SUBST([HAVE_LIB]NAME)
|
||||
AC_SUBST([LIB]NAME)
|
||||
AC_SUBST([LTLIB]NAME)
|
||||
AC_SUBST([LIB]NAME[_PREFIX])
|
||||
popdef([NAME])
|
||||
popdef([Name])
|
||||
])
|
||||
|
||||
dnl Determine the platform dependent parameters needed to use rpath:
|
||||
dnl acl_libext,
|
||||
dnl acl_shlibext,
|
||||
dnl acl_hardcode_libdir_flag_spec,
|
||||
dnl acl_hardcode_libdir_separator,
|
||||
dnl acl_hardcode_direct,
|
||||
dnl acl_hardcode_minus_L.
|
||||
AC_DEFUN([AC_LIB_RPATH],
|
||||
[
|
||||
dnl Tell automake >= 1.10 to complain if config.rpath is missing.
|
||||
m4_ifdef([AC_REQUIRE_AUX_FILE], [AC_REQUIRE_AUX_FILE([config.rpath])])
|
||||
AC_REQUIRE([AC_PROG_CC]) dnl we use $CC, $GCC, $LDFLAGS
|
||||
AC_REQUIRE([AC_LIB_PROG_LD]) dnl we use $LD, $with_gnu_ld
|
||||
AC_REQUIRE([AC_CANONICAL_HOST]) dnl we use $host
|
||||
AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT]) dnl we use $ac_aux_dir
|
||||
AC_CACHE_CHECK([for shared library run path origin], [acl_cv_rpath], [
|
||||
CC="$CC" GCC="$GCC" LDFLAGS="$LDFLAGS" LD="$LD" with_gnu_ld="$with_gnu_ld" \
|
||||
${CONFIG_SHELL-/bin/sh} "$ac_aux_dir/config.rpath" "$host" > conftest.sh
|
||||
. ./conftest.sh
|
||||
rm -f ./conftest.sh
|
||||
acl_cv_rpath=done
|
||||
])
|
||||
wl="$acl_cv_wl"
|
||||
acl_libext="$acl_cv_libext"
|
||||
acl_shlibext="$acl_cv_shlibext"
|
||||
acl_libname_spec="$acl_cv_libname_spec"
|
||||
acl_library_names_spec="$acl_cv_library_names_spec"
|
||||
acl_hardcode_libdir_flag_spec="$acl_cv_hardcode_libdir_flag_spec"
|
||||
acl_hardcode_libdir_separator="$acl_cv_hardcode_libdir_separator"
|
||||
acl_hardcode_direct="$acl_cv_hardcode_direct"
|
||||
acl_hardcode_minus_L="$acl_cv_hardcode_minus_L"
|
||||
dnl Determine whether the user wants rpath handling at all.
|
||||
AC_ARG_ENABLE([rpath],
|
||||
[ --disable-rpath do not hardcode runtime library paths],
|
||||
:, enable_rpath=yes)
|
||||
])
|
||||
|
||||
dnl AC_LIB_FROMPACKAGE(name, package)
|
||||
dnl declares that libname comes from the given package. The configure file
|
||||
dnl will then not have a --with-libname-prefix option but a
|
||||
dnl --with-package-prefix option. Several libraries can come from the same
|
||||
dnl package. This declaration must occur before an AC_LIB_LINKFLAGS or similar
|
||||
dnl macro call that searches for libname.
|
||||
AC_DEFUN([AC_LIB_FROMPACKAGE],
|
||||
[
|
||||
pushdef([NAME],[translit([$1],[abcdefghijklmnopqrstuvwxyz./-],
|
||||
[ABCDEFGHIJKLMNOPQRSTUVWXYZ___])])
|
||||
define([acl_frompackage_]NAME, [$2])
|
||||
popdef([NAME])
|
||||
pushdef([PACK],[$2])
|
||||
pushdef([PACKUP],[translit(PACK,[abcdefghijklmnopqrstuvwxyz./-],
|
||||
[ABCDEFGHIJKLMNOPQRSTUVWXYZ___])])
|
||||
define([acl_libsinpackage_]PACKUP,
|
||||
m4_ifdef([acl_libsinpackage_]PACKUP, [acl_libsinpackage_]PACKUP[[, ]],)[lib$1])
|
||||
popdef([PACKUP])
|
||||
popdef([PACK])
|
||||
])
|
||||
|
||||
dnl AC_LIB_LINKFLAGS_BODY(name [, dependencies]) searches for libname and
|
||||
dnl the libraries corresponding to explicit and implicit dependencies.
|
||||
dnl Sets the LIB${NAME}, LTLIB${NAME} and INC${NAME} variables.
|
||||
dnl Also, sets the LIB${NAME}_PREFIX variable to nonempty if libname was found
|
||||
dnl in ${LIB${NAME}_PREFIX}/$acl_libdirstem.
|
||||
AC_DEFUN([AC_LIB_LINKFLAGS_BODY],
|
||||
[
|
||||
AC_REQUIRE([AC_LIB_PREPARE_MULTILIB])
|
||||
pushdef([NAME],[translit([$1],[abcdefghijklmnopqrstuvwxyz./-],
|
||||
[ABCDEFGHIJKLMNOPQRSTUVWXYZ___])])
|
||||
pushdef([PACK],[m4_ifdef([acl_frompackage_]NAME, [acl_frompackage_]NAME, lib[$1])])
|
||||
pushdef([PACKUP],[translit(PACK,[abcdefghijklmnopqrstuvwxyz./-],
|
||||
[ABCDEFGHIJKLMNOPQRSTUVWXYZ___])])
|
||||
pushdef([PACKLIBS],[m4_ifdef([acl_frompackage_]NAME, [acl_libsinpackage_]PACKUP, lib[$1])])
|
||||
dnl Autoconf >= 2.61 supports dots in --with options.
|
||||
pushdef([P_A_C_K],[m4_if(m4_version_compare(m4_defn([m4_PACKAGE_VERSION]),[2.61]),[-1],[translit(PACK,[.],[_])],PACK)])
|
||||
dnl By default, look in $includedir and $libdir.
|
||||
use_additional=yes
|
||||
AC_LIB_WITH_FINAL_PREFIX([
|
||||
eval additional_includedir=\"$includedir\"
|
||||
eval additional_libdir=\"$libdir\"
|
||||
])
|
||||
AC_ARG_WITH(P_A_C_K[-prefix],
|
||||
[[ --with-]]P_A_C_K[[-prefix[=DIR] search for ]PACKLIBS[ in DIR/include and DIR/lib
|
||||
--without-]]P_A_C_K[[-prefix don't search for ]PACKLIBS[ in includedir and libdir]],
|
||||
[
|
||||
if test "X$withval" = "Xno"; then
|
||||
use_additional=no
|
||||
else
|
||||
if test "X$withval" = "X"; then
|
||||
AC_LIB_WITH_FINAL_PREFIX([
|
||||
eval additional_includedir=\"$includedir\"
|
||||
eval additional_libdir=\"$libdir\"
|
||||
])
|
||||
else
|
||||
additional_includedir="$withval/include"
|
||||
additional_libdir="$withval/$acl_libdirstem"
|
||||
if test "$acl_libdirstem2" != "$acl_libdirstem" \
|
||||
&& ! test -d "$withval/$acl_libdirstem"; then
|
||||
additional_libdir="$withval/$acl_libdirstem2"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
])
|
||||
dnl Search the library and its dependencies in $additional_libdir and
|
||||
dnl $LDFLAGS. Using breadth-first-seach.
|
||||
LIB[]NAME=
|
||||
LTLIB[]NAME=
|
||||
INC[]NAME=
|
||||
LIB[]NAME[]_PREFIX=
|
||||
rpathdirs=
|
||||
ltrpathdirs=
|
||||
names_already_handled=
|
||||
names_next_round='$1 $2'
|
||||
while test -n "$names_next_round"; do
|
||||
names_this_round="$names_next_round"
|
||||
names_next_round=
|
||||
for name in $names_this_round; do
|
||||
already_handled=
|
||||
for n in $names_already_handled; do
|
||||
if test "$n" = "$name"; then
|
||||
already_handled=yes
|
||||
break
|
||||
fi
|
||||
done
|
||||
if test -z "$already_handled"; then
|
||||
names_already_handled="$names_already_handled $name"
|
||||
dnl See if it was already located by an earlier AC_LIB_LINKFLAGS
|
||||
dnl or AC_LIB_HAVE_LINKFLAGS call.
|
||||
uppername=`echo "$name" | sed -e 'y|abcdefghijklmnopqrstuvwxyz./-|ABCDEFGHIJKLMNOPQRSTUVWXYZ___|'`
|
||||
eval value=\"\$HAVE_LIB$uppername\"
|
||||
if test -n "$value"; then
|
||||
if test "$value" = yes; then
|
||||
eval value=\"\$LIB$uppername\"
|
||||
test -z "$value" || LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$value"
|
||||
eval value=\"\$LTLIB$uppername\"
|
||||
test -z "$value" || LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }$value"
|
||||
else
|
||||
dnl An earlier call to AC_LIB_HAVE_LINKFLAGS has determined
|
||||
dnl that this library doesn't exist. So just drop it.
|
||||
:
|
||||
fi
|
||||
else
|
||||
dnl Search the library lib$name in $additional_libdir and $LDFLAGS
|
||||
dnl and the already constructed $LIBNAME/$LTLIBNAME.
|
||||
found_dir=
|
||||
found_la=
|
||||
found_so=
|
||||
found_a=
|
||||
eval libname=\"$acl_libname_spec\" # typically: libname=lib$name
|
||||
if test -n "$acl_shlibext"; then
|
||||
shrext=".$acl_shlibext" # typically: shrext=.so
|
||||
else
|
||||
shrext=
|
||||
fi
|
||||
if test $use_additional = yes; then
|
||||
dir="$additional_libdir"
|
||||
dnl The same code as in the loop below:
|
||||
dnl First look for a shared library.
|
||||
if test -n "$acl_shlibext"; then
|
||||
if test -f "$dir/$libname$shrext"; then
|
||||
found_dir="$dir"
|
||||
found_so="$dir/$libname$shrext"
|
||||
else
|
||||
if test "$acl_library_names_spec" = '$libname$shrext$versuffix'; then
|
||||
ver=`(cd "$dir" && \
|
||||
for f in "$libname$shrext".*; do echo "$f"; done \
|
||||
| sed -e "s,^$libname$shrext\\\\.,," \
|
||||
| sort -t '.' -n -r -k1,1 -k2,2 -k3,3 -k4,4 -k5,5 \
|
||||
| sed 1q ) 2>/dev/null`
|
||||
if test -n "$ver" && test -f "$dir/$libname$shrext.$ver"; then
|
||||
found_dir="$dir"
|
||||
found_so="$dir/$libname$shrext.$ver"
|
||||
fi
|
||||
else
|
||||
eval library_names=\"$acl_library_names_spec\"
|
||||
for f in $library_names; do
|
||||
if test -f "$dir/$f"; then
|
||||
found_dir="$dir"
|
||||
found_so="$dir/$f"
|
||||
break
|
||||
fi
|
||||
done
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
dnl Then look for a static library.
|
||||
if test "X$found_dir" = "X"; then
|
||||
if test -f "$dir/$libname.$acl_libext"; then
|
||||
found_dir="$dir"
|
||||
found_a="$dir/$libname.$acl_libext"
|
||||
fi
|
||||
fi
|
||||
if test "X$found_dir" != "X"; then
|
||||
if test -f "$dir/$libname.la"; then
|
||||
found_la="$dir/$libname.la"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
if test "X$found_dir" = "X"; then
|
||||
for x in $LDFLAGS $LTLIB[]NAME; do
|
||||
AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"])
|
||||
case "$x" in
|
||||
-L*)
|
||||
dir=`echo "X$x" | sed -e 's/^X-L//'`
|
||||
dnl First look for a shared library.
|
||||
if test -n "$acl_shlibext"; then
|
||||
if test -f "$dir/$libname$shrext"; then
|
||||
found_dir="$dir"
|
||||
found_so="$dir/$libname$shrext"
|
||||
else
|
||||
if test "$acl_library_names_spec" = '$libname$shrext$versuffix'; then
|
||||
ver=`(cd "$dir" && \
|
||||
for f in "$libname$shrext".*; do echo "$f"; done \
|
||||
| sed -e "s,^$libname$shrext\\\\.,," \
|
||||
| sort -t '.' -n -r -k1,1 -k2,2 -k3,3 -k4,4 -k5,5 \
|
||||
| sed 1q ) 2>/dev/null`
|
||||
if test -n "$ver" && test -f "$dir/$libname$shrext.$ver"; then
|
||||
found_dir="$dir"
|
||||
found_so="$dir/$libname$shrext.$ver"
|
||||
fi
|
||||
else
|
||||
eval library_names=\"$acl_library_names_spec\"
|
||||
for f in $library_names; do
|
||||
if test -f "$dir/$f"; then
|
||||
found_dir="$dir"
|
||||
found_so="$dir/$f"
|
||||
break
|
||||
fi
|
||||
done
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
dnl Then look for a static library.
|
||||
if test "X$found_dir" = "X"; then
|
||||
if test -f "$dir/$libname.$acl_libext"; then
|
||||
found_dir="$dir"
|
||||
found_a="$dir/$libname.$acl_libext"
|
||||
fi
|
||||
fi
|
||||
if test "X$found_dir" != "X"; then
|
||||
if test -f "$dir/$libname.la"; then
|
||||
found_la="$dir/$libname.la"
|
||||
fi
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
if test "X$found_dir" != "X"; then
|
||||
break
|
||||
fi
|
||||
done
|
||||
fi
|
||||
if test "X$found_dir" != "X"; then
|
||||
dnl Found the library.
|
||||
LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-L$found_dir -l$name"
|
||||
if test "X$found_so" != "X"; then
|
||||
dnl Linking with a shared library. We attempt to hardcode its
|
||||
dnl directory into the executable's runpath, unless it's the
|
||||
dnl standard /usr/lib.
|
||||
if test "$enable_rpath" = no \
|
||||
|| test "X$found_dir" = "X/usr/$acl_libdirstem" \
|
||||
|| test "X$found_dir" = "X/usr/$acl_libdirstem2"; then
|
||||
dnl No hardcoding is needed.
|
||||
LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so"
|
||||
else
|
||||
dnl Use an explicit option to hardcode DIR into the resulting
|
||||
dnl binary.
|
||||
dnl Potentially add DIR to ltrpathdirs.
|
||||
dnl The ltrpathdirs will be appended to $LTLIBNAME at the end.
|
||||
haveit=
|
||||
for x in $ltrpathdirs; do
|
||||
if test "X$x" = "X$found_dir"; then
|
||||
haveit=yes
|
||||
break
|
||||
fi
|
||||
done
|
||||
if test -z "$haveit"; then
|
||||
ltrpathdirs="$ltrpathdirs $found_dir"
|
||||
fi
|
||||
dnl The hardcoding into $LIBNAME is system dependent.
|
||||
if test "$acl_hardcode_direct" = yes; then
|
||||
dnl Using DIR/libNAME.so during linking hardcodes DIR into the
|
||||
dnl resulting binary.
|
||||
LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so"
|
||||
else
|
||||
if test -n "$acl_hardcode_libdir_flag_spec" && test "$acl_hardcode_minus_L" = no; then
|
||||
dnl Use an explicit option to hardcode DIR into the resulting
|
||||
dnl binary.
|
||||
LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so"
|
||||
dnl Potentially add DIR to rpathdirs.
|
||||
dnl The rpathdirs will be appended to $LIBNAME at the end.
|
||||
haveit=
|
||||
for x in $rpathdirs; do
|
||||
if test "X$x" = "X$found_dir"; then
|
||||
haveit=yes
|
||||
break
|
||||
fi
|
||||
done
|
||||
if test -z "$haveit"; then
|
||||
rpathdirs="$rpathdirs $found_dir"
|
||||
fi
|
||||
else
|
||||
dnl Rely on "-L$found_dir".
|
||||
dnl But don't add it if it's already contained in the LDFLAGS
|
||||
dnl or the already constructed $LIBNAME
|
||||
haveit=
|
||||
for x in $LDFLAGS $LIB[]NAME; do
|
||||
AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"])
|
||||
if test "X$x" = "X-L$found_dir"; then
|
||||
haveit=yes
|
||||
break
|
||||
fi
|
||||
done
|
||||
if test -z "$haveit"; then
|
||||
LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-L$found_dir"
|
||||
fi
|
||||
if test "$acl_hardcode_minus_L" != no; then
|
||||
dnl FIXME: Not sure whether we should use
|
||||
dnl "-L$found_dir -l$name" or "-L$found_dir $found_so"
|
||||
dnl here.
|
||||
LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so"
|
||||
else
|
||||
dnl We cannot use $acl_hardcode_runpath_var and LD_RUN_PATH
|
||||
dnl here, because this doesn't fit in flags passed to the
|
||||
dnl compiler. So give up. No hardcoding. This affects only
|
||||
dnl very old systems.
|
||||
dnl FIXME: Not sure whether we should use
|
||||
dnl "-L$found_dir -l$name" or "-L$found_dir $found_so"
|
||||
dnl here.
|
||||
LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-l$name"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
else
|
||||
if test "X$found_a" != "X"; then
|
||||
dnl Linking with a static library.
|
||||
LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_a"
|
||||
else
|
||||
dnl We shouldn't come here, but anyway it's good to have a
|
||||
dnl fallback.
|
||||
LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-L$found_dir -l$name"
|
||||
fi
|
||||
fi
|
||||
dnl Assume the include files are nearby.
|
||||
additional_includedir=
|
||||
case "$found_dir" in
|
||||
*/$acl_libdirstem | */$acl_libdirstem/)
|
||||
basedir=`echo "X$found_dir" | sed -e 's,^X,,' -e "s,/$acl_libdirstem/"'*$,,'`
|
||||
if test "$name" = '$1'; then
|
||||
LIB[]NAME[]_PREFIX="$basedir"
|
||||
fi
|
||||
additional_includedir="$basedir/include"
|
||||
;;
|
||||
*/$acl_libdirstem2 | */$acl_libdirstem2/)
|
||||
basedir=`echo "X$found_dir" | sed -e 's,^X,,' -e "s,/$acl_libdirstem2/"'*$,,'`
|
||||
if test "$name" = '$1'; then
|
||||
LIB[]NAME[]_PREFIX="$basedir"
|
||||
fi
|
||||
additional_includedir="$basedir/include"
|
||||
;;
|
||||
esac
|
||||
if test "X$additional_includedir" != "X"; then
|
||||
dnl Potentially add $additional_includedir to $INCNAME.
|
||||
dnl But don't add it
|
||||
dnl 1. if it's the standard /usr/include,
|
||||
dnl 2. if it's /usr/local/include and we are using GCC on Linux,
|
||||
dnl 3. if it's already present in $CPPFLAGS or the already
|
||||
dnl constructed $INCNAME,
|
||||
dnl 4. if it doesn't exist as a directory.
|
||||
if test "X$additional_includedir" != "X/usr/include"; then
|
||||
haveit=
|
||||
if test "X$additional_includedir" = "X/usr/local/include"; then
|
||||
if test -n "$GCC"; then
|
||||
case $host_os in
|
||||
linux* | gnu* | k*bsd*-gnu) haveit=yes;;
|
||||
esac
|
||||
fi
|
||||
fi
|
||||
if test -z "$haveit"; then
|
||||
for x in $CPPFLAGS $INC[]NAME; do
|
||||
AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"])
|
||||
if test "X$x" = "X-I$additional_includedir"; then
|
||||
haveit=yes
|
||||
break
|
||||
fi
|
||||
done
|
||||
if test -z "$haveit"; then
|
||||
if test -d "$additional_includedir"; then
|
||||
dnl Really add $additional_includedir to $INCNAME.
|
||||
INC[]NAME="${INC[]NAME}${INC[]NAME:+ }-I$additional_includedir"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
dnl Look for dependencies.
|
||||
if test -n "$found_la"; then
|
||||
dnl Read the .la file. It defines the variables
|
||||
dnl dlname, library_names, old_library, dependency_libs, current,
|
||||
dnl age, revision, installed, dlopen, dlpreopen, libdir.
|
||||
save_libdir="$libdir"
|
||||
case "$found_la" in
|
||||
*/* | *\\*) . "$found_la" ;;
|
||||
*) . "./$found_la" ;;
|
||||
esac
|
||||
libdir="$save_libdir"
|
||||
dnl We use only dependency_libs.
|
||||
for dep in $dependency_libs; do
|
||||
case "$dep" in
|
||||
-L*)
|
||||
additional_libdir=`echo "X$dep" | sed -e 's/^X-L//'`
|
||||
dnl Potentially add $additional_libdir to $LIBNAME and $LTLIBNAME.
|
||||
dnl But don't add it
|
||||
dnl 1. if it's the standard /usr/lib,
|
||||
dnl 2. if it's /usr/local/lib and we are using GCC on Linux,
|
||||
dnl 3. if it's already present in $LDFLAGS or the already
|
||||
dnl constructed $LIBNAME,
|
||||
dnl 4. if it doesn't exist as a directory.
|
||||
if test "X$additional_libdir" != "X/usr/$acl_libdirstem" \
|
||||
&& test "X$additional_libdir" != "X/usr/$acl_libdirstem2"; then
|
||||
haveit=
|
||||
if test "X$additional_libdir" = "X/usr/local/$acl_libdirstem" \
|
||||
|| test "X$additional_libdir" = "X/usr/local/$acl_libdirstem2"; then
|
||||
if test -n "$GCC"; then
|
||||
case $host_os in
|
||||
linux* | gnu* | k*bsd*-gnu) haveit=yes;;
|
||||
esac
|
||||
fi
|
||||
fi
|
||||
if test -z "$haveit"; then
|
||||
haveit=
|
||||
for x in $LDFLAGS $LIB[]NAME; do
|
||||
AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"])
|
||||
if test "X$x" = "X-L$additional_libdir"; then
|
||||
haveit=yes
|
||||
break
|
||||
fi
|
||||
done
|
||||
if test -z "$haveit"; then
|
||||
if test -d "$additional_libdir"; then
|
||||
dnl Really add $additional_libdir to $LIBNAME.
|
||||
LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-L$additional_libdir"
|
||||
fi
|
||||
fi
|
||||
haveit=
|
||||
for x in $LDFLAGS $LTLIB[]NAME; do
|
||||
AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"])
|
||||
if test "X$x" = "X-L$additional_libdir"; then
|
||||
haveit=yes
|
||||
break
|
||||
fi
|
||||
done
|
||||
if test -z "$haveit"; then
|
||||
if test -d "$additional_libdir"; then
|
||||
dnl Really add $additional_libdir to $LTLIBNAME.
|
||||
LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-L$additional_libdir"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
;;
|
||||
-R*)
|
||||
dir=`echo "X$dep" | sed -e 's/^X-R//'`
|
||||
if test "$enable_rpath" != no; then
|
||||
dnl Potentially add DIR to rpathdirs.
|
||||
dnl The rpathdirs will be appended to $LIBNAME at the end.
|
||||
haveit=
|
||||
for x in $rpathdirs; do
|
||||
if test "X$x" = "X$dir"; then
|
||||
haveit=yes
|
||||
break
|
||||
fi
|
||||
done
|
||||
if test -z "$haveit"; then
|
||||
rpathdirs="$rpathdirs $dir"
|
||||
fi
|
||||
dnl Potentially add DIR to ltrpathdirs.
|
||||
dnl The ltrpathdirs will be appended to $LTLIBNAME at the end.
|
||||
haveit=
|
||||
for x in $ltrpathdirs; do
|
||||
if test "X$x" = "X$dir"; then
|
||||
haveit=yes
|
||||
break
|
||||
fi
|
||||
done
|
||||
if test -z "$haveit"; then
|
||||
ltrpathdirs="$ltrpathdirs $dir"
|
||||
fi
|
||||
fi
|
||||
;;
|
||||
-l*)
|
||||
dnl Handle this in the next round.
|
||||
names_next_round="$names_next_round "`echo "X$dep" | sed -e 's/^X-l//'`
|
||||
;;
|
||||
*.la)
|
||||
dnl Handle this in the next round. Throw away the .la's
|
||||
dnl directory; it is already contained in a preceding -L
|
||||
dnl option.
|
||||
names_next_round="$names_next_round "`echo "X$dep" | sed -e 's,^X.*/,,' -e 's,^lib,,' -e 's,\.la$,,'`
|
||||
;;
|
||||
*)
|
||||
dnl Most likely an immediate library name.
|
||||
LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$dep"
|
||||
LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }$dep"
|
||||
;;
|
||||
esac
|
||||
done
|
||||
fi
|
||||
else
|
||||
dnl Didn't find the library; assume it is in the system directories
|
||||
dnl known to the linker and runtime loader. (All the system
|
||||
dnl directories known to the linker should also be known to the
|
||||
dnl runtime loader, otherwise the system is severely misconfigured.)
|
||||
LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-l$name"
|
||||
LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-l$name"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
done
|
||||
done
|
||||
if test "X$rpathdirs" != "X"; then
|
||||
if test -n "$acl_hardcode_libdir_separator"; then
|
||||
dnl Weird platform: only the last -rpath option counts, the user must
|
||||
dnl pass all path elements in one option. We can arrange that for a
|
||||
dnl single library, but not when more than one $LIBNAMEs are used.
|
||||
alldirs=
|
||||
for found_dir in $rpathdirs; do
|
||||
alldirs="${alldirs}${alldirs:+$acl_hardcode_libdir_separator}$found_dir"
|
||||
done
|
||||
dnl Note: acl_hardcode_libdir_flag_spec uses $libdir and $wl.
|
||||
acl_save_libdir="$libdir"
|
||||
libdir="$alldirs"
|
||||
eval flag=\"$acl_hardcode_libdir_flag_spec\"
|
||||
libdir="$acl_save_libdir"
|
||||
LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$flag"
|
||||
else
|
||||
dnl The -rpath options are cumulative.
|
||||
for found_dir in $rpathdirs; do
|
||||
acl_save_libdir="$libdir"
|
||||
libdir="$found_dir"
|
||||
eval flag=\"$acl_hardcode_libdir_flag_spec\"
|
||||
libdir="$acl_save_libdir"
|
||||
LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$flag"
|
||||
done
|
||||
fi
|
||||
fi
|
||||
if test "X$ltrpathdirs" != "X"; then
|
||||
dnl When using libtool, the option that works for both libraries and
|
||||
dnl executables is -R. The -R options are cumulative.
|
||||
for found_dir in $ltrpathdirs; do
|
||||
LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-R$found_dir"
|
||||
done
|
||||
fi
|
||||
popdef([P_A_C_K])
|
||||
popdef([PACKLIBS])
|
||||
popdef([PACKUP])
|
||||
popdef([PACK])
|
||||
popdef([NAME])
|
||||
])
|
||||
|
||||
dnl AC_LIB_APPENDTOVAR(VAR, CONTENTS) appends the elements of CONTENTS to VAR,
|
||||
dnl unless already present in VAR.
|
||||
dnl Works only for CPPFLAGS, not for LIB* variables because that sometimes
|
||||
dnl contains two or three consecutive elements that belong together.
|
||||
AC_DEFUN([AC_LIB_APPENDTOVAR],
|
||||
[
|
||||
for element in [$2]; do
|
||||
haveit=
|
||||
for x in $[$1]; do
|
||||
AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"])
|
||||
if test "X$x" = "X$element"; then
|
||||
haveit=yes
|
||||
break
|
||||
fi
|
||||
done
|
||||
if test -z "$haveit"; then
|
||||
[$1]="${[$1]}${[$1]:+ }$element"
|
||||
fi
|
||||
done
|
||||
])
|
||||
|
||||
dnl For those cases where a variable contains several -L and -l options
|
||||
dnl referring to unknown libraries and directories, this macro determines the
|
||||
dnl necessary additional linker options for the runtime path.
|
||||
dnl AC_LIB_LINKFLAGS_FROM_LIBS([LDADDVAR], [LIBSVALUE], [USE-LIBTOOL])
|
||||
dnl sets LDADDVAR to linker options needed together with LIBSVALUE.
|
||||
dnl If USE-LIBTOOL evaluates to non-empty, linking with libtool is assumed,
|
||||
dnl otherwise linking without libtool is assumed.
|
||||
AC_DEFUN([AC_LIB_LINKFLAGS_FROM_LIBS],
|
||||
[
|
||||
AC_REQUIRE([AC_LIB_RPATH])
|
||||
AC_REQUIRE([AC_LIB_PREPARE_MULTILIB])
|
||||
$1=
|
||||
if test "$enable_rpath" != no; then
|
||||
if test -n "$acl_hardcode_libdir_flag_spec" && test "$acl_hardcode_minus_L" = no; then
|
||||
dnl Use an explicit option to hardcode directories into the resulting
|
||||
dnl binary.
|
||||
rpathdirs=
|
||||
next=
|
||||
for opt in $2; do
|
||||
if test -n "$next"; then
|
||||
dir="$next"
|
||||
dnl No need to hardcode the standard /usr/lib.
|
||||
if test "X$dir" != "X/usr/$acl_libdirstem" \
|
||||
&& test "X$dir" != "X/usr/$acl_libdirstem2"; then
|
||||
rpathdirs="$rpathdirs $dir"
|
||||
fi
|
||||
next=
|
||||
else
|
||||
case $opt in
|
||||
-L) next=yes ;;
|
||||
-L*) dir=`echo "X$opt" | sed -e 's,^X-L,,'`
|
||||
dnl No need to hardcode the standard /usr/lib.
|
||||
if test "X$dir" != "X/usr/$acl_libdirstem" \
|
||||
&& test "X$dir" != "X/usr/$acl_libdirstem2"; then
|
||||
rpathdirs="$rpathdirs $dir"
|
||||
fi
|
||||
next= ;;
|
||||
*) next= ;;
|
||||
esac
|
||||
fi
|
||||
done
|
||||
if test "X$rpathdirs" != "X"; then
|
||||
if test -n ""$3""; then
|
||||
dnl libtool is used for linking. Use -R options.
|
||||
for dir in $rpathdirs; do
|
||||
$1="${$1}${$1:+ }-R$dir"
|
||||
done
|
||||
else
|
||||
dnl The linker is used for linking directly.
|
||||
if test -n "$acl_hardcode_libdir_separator"; then
|
||||
dnl Weird platform: only the last -rpath option counts, the user
|
||||
dnl must pass all path elements in one option.
|
||||
alldirs=
|
||||
for dir in $rpathdirs; do
|
||||
alldirs="${alldirs}${alldirs:+$acl_hardcode_libdir_separator}$dir"
|
||||
done
|
||||
acl_save_libdir="$libdir"
|
||||
libdir="$alldirs"
|
||||
eval flag=\"$acl_hardcode_libdir_flag_spec\"
|
||||
libdir="$acl_save_libdir"
|
||||
$1="$flag"
|
||||
else
|
||||
dnl The -rpath options are cumulative.
|
||||
for dir in $rpathdirs; do
|
||||
acl_save_libdir="$libdir"
|
||||
libdir="$dir"
|
||||
eval flag=\"$acl_hardcode_libdir_flag_spec\"
|
||||
libdir="$acl_save_libdir"
|
||||
$1="${$1}${$1:+ }$flag"
|
||||
done
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
AC_SUBST([$1])
|
||||
])
|
224
m4/lib-prefix.m4
Normal file
224
m4/lib-prefix.m4
Normal file
|
@ -0,0 +1,224 @@
|
|||
# lib-prefix.m4 serial 7 (gettext-0.18)
|
||||
dnl Copyright (C) 2001-2005, 2008-2009 Free Software Foundation, Inc.
|
||||
dnl This file is free software; the Free Software Foundation
|
||||
dnl gives unlimited permission to copy and/or distribute it,
|
||||
dnl with or without modifications, as long as this notice is preserved.
|
||||
|
||||
dnl From Bruno Haible.
|
||||
|
||||
dnl AC_LIB_ARG_WITH is synonymous to AC_ARG_WITH in autoconf-2.13, and
|
||||
dnl similar to AC_ARG_WITH in autoconf 2.52...2.57 except that is doesn't
|
||||
dnl require excessive bracketing.
|
||||
ifdef([AC_HELP_STRING],
|
||||
[AC_DEFUN([AC_LIB_ARG_WITH], [AC_ARG_WITH([$1],[[$2]],[$3],[$4])])],
|
||||
[AC_DEFUN([AC_][LIB_ARG_WITH], [AC_ARG_WITH([$1],[$2],[$3],[$4])])])
|
||||
|
||||
dnl AC_LIB_PREFIX adds to the CPPFLAGS and LDFLAGS the flags that are needed
|
||||
dnl to access previously installed libraries. The basic assumption is that
|
||||
dnl a user will want packages to use other packages he previously installed
|
||||
dnl with the same --prefix option.
|
||||
dnl This macro is not needed if only AC_LIB_LINKFLAGS is used to locate
|
||||
dnl libraries, but is otherwise very convenient.
|
||||
AC_DEFUN([AC_LIB_PREFIX],
|
||||
[
|
||||
AC_BEFORE([$0], [AC_LIB_LINKFLAGS])
|
||||
AC_REQUIRE([AC_PROG_CC])
|
||||
AC_REQUIRE([AC_CANONICAL_HOST])
|
||||
AC_REQUIRE([AC_LIB_PREPARE_MULTILIB])
|
||||
AC_REQUIRE([AC_LIB_PREPARE_PREFIX])
|
||||
dnl By default, look in $includedir and $libdir.
|
||||
use_additional=yes
|
||||
AC_LIB_WITH_FINAL_PREFIX([
|
||||
eval additional_includedir=\"$includedir\"
|
||||
eval additional_libdir=\"$libdir\"
|
||||
])
|
||||
AC_LIB_ARG_WITH([lib-prefix],
|
||||
[ --with-lib-prefix[=DIR] search for libraries in DIR/include and DIR/lib
|
||||
--without-lib-prefix don't search for libraries in includedir and libdir],
|
||||
[
|
||||
if test "X$withval" = "Xno"; then
|
||||
use_additional=no
|
||||
else
|
||||
if test "X$withval" = "X"; then
|
||||
AC_LIB_WITH_FINAL_PREFIX([
|
||||
eval additional_includedir=\"$includedir\"
|
||||
eval additional_libdir=\"$libdir\"
|
||||
])
|
||||
else
|
||||
additional_includedir="$withval/include"
|
||||
additional_libdir="$withval/$acl_libdirstem"
|
||||
fi
|
||||
fi
|
||||
])
|
||||
if test $use_additional = yes; then
|
||||
dnl Potentially add $additional_includedir to $CPPFLAGS.
|
||||
dnl But don't add it
|
||||
dnl 1. if it's the standard /usr/include,
|
||||
dnl 2. if it's already present in $CPPFLAGS,
|
||||
dnl 3. if it's /usr/local/include and we are using GCC on Linux,
|
||||
dnl 4. if it doesn't exist as a directory.
|
||||
if test "X$additional_includedir" != "X/usr/include"; then
|
||||
haveit=
|
||||
for x in $CPPFLAGS; do
|
||||
AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"])
|
||||
if test "X$x" = "X-I$additional_includedir"; then
|
||||
haveit=yes
|
||||
break
|
||||
fi
|
||||
done
|
||||
if test -z "$haveit"; then
|
||||
if test "X$additional_includedir" = "X/usr/local/include"; then
|
||||
if test -n "$GCC"; then
|
||||
case $host_os in
|
||||
linux* | gnu* | k*bsd*-gnu) haveit=yes;;
|
||||
esac
|
||||
fi
|
||||
fi
|
||||
if test -z "$haveit"; then
|
||||
if test -d "$additional_includedir"; then
|
||||
dnl Really add $additional_includedir to $CPPFLAGS.
|
||||
CPPFLAGS="${CPPFLAGS}${CPPFLAGS:+ }-I$additional_includedir"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
dnl Potentially add $additional_libdir to $LDFLAGS.
|
||||
dnl But don't add it
|
||||
dnl 1. if it's the standard /usr/lib,
|
||||
dnl 2. if it's already present in $LDFLAGS,
|
||||
dnl 3. if it's /usr/local/lib and we are using GCC on Linux,
|
||||
dnl 4. if it doesn't exist as a directory.
|
||||
if test "X$additional_libdir" != "X/usr/$acl_libdirstem"; then
|
||||
haveit=
|
||||
for x in $LDFLAGS; do
|
||||
AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"])
|
||||
if test "X$x" = "X-L$additional_libdir"; then
|
||||
haveit=yes
|
||||
break
|
||||
fi
|
||||
done
|
||||
if test -z "$haveit"; then
|
||||
if test "X$additional_libdir" = "X/usr/local/$acl_libdirstem"; then
|
||||
if test -n "$GCC"; then
|
||||
case $host_os in
|
||||
linux*) haveit=yes;;
|
||||
esac
|
||||
fi
|
||||
fi
|
||||
if test -z "$haveit"; then
|
||||
if test -d "$additional_libdir"; then
|
||||
dnl Really add $additional_libdir to $LDFLAGS.
|
||||
LDFLAGS="${LDFLAGS}${LDFLAGS:+ }-L$additional_libdir"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
])
|
||||
|
||||
dnl AC_LIB_PREPARE_PREFIX creates variables acl_final_prefix,
|
||||
dnl acl_final_exec_prefix, containing the values to which $prefix and
|
||||
dnl $exec_prefix will expand at the end of the configure script.
|
||||
AC_DEFUN([AC_LIB_PREPARE_PREFIX],
|
||||
[
|
||||
dnl Unfortunately, prefix and exec_prefix get only finally determined
|
||||
dnl at the end of configure.
|
||||
if test "X$prefix" = "XNONE"; then
|
||||
acl_final_prefix="$ac_default_prefix"
|
||||
else
|
||||
acl_final_prefix="$prefix"
|
||||
fi
|
||||
if test "X$exec_prefix" = "XNONE"; then
|
||||
acl_final_exec_prefix='${prefix}'
|
||||
else
|
||||
acl_final_exec_prefix="$exec_prefix"
|
||||
fi
|
||||
acl_save_prefix="$prefix"
|
||||
prefix="$acl_final_prefix"
|
||||
eval acl_final_exec_prefix=\"$acl_final_exec_prefix\"
|
||||
prefix="$acl_save_prefix"
|
||||
])
|
||||
|
||||
dnl AC_LIB_WITH_FINAL_PREFIX([statement]) evaluates statement, with the
|
||||
dnl variables prefix and exec_prefix bound to the values they will have
|
||||
dnl at the end of the configure script.
|
||||
AC_DEFUN([AC_LIB_WITH_FINAL_PREFIX],
|
||||
[
|
||||
acl_save_prefix="$prefix"
|
||||
prefix="$acl_final_prefix"
|
||||
acl_save_exec_prefix="$exec_prefix"
|
||||
exec_prefix="$acl_final_exec_prefix"
|
||||
$1
|
||||
exec_prefix="$acl_save_exec_prefix"
|
||||
prefix="$acl_save_prefix"
|
||||
])
|
||||
|
||||
dnl AC_LIB_PREPARE_MULTILIB creates
|
||||
dnl - a variable acl_libdirstem, containing the basename of the libdir, either
|
||||
dnl "lib" or "lib64" or "lib/64",
|
||||
dnl - a variable acl_libdirstem2, as a secondary possible value for
|
||||
dnl acl_libdirstem, either the same as acl_libdirstem or "lib/sparcv9" or
|
||||
dnl "lib/amd64".
|
||||
AC_DEFUN([AC_LIB_PREPARE_MULTILIB],
|
||||
[
|
||||
dnl There is no formal standard regarding lib and lib64.
|
||||
dnl On glibc systems, the current practice is that on a system supporting
|
||||
dnl 32-bit and 64-bit instruction sets or ABIs, 64-bit libraries go under
|
||||
dnl $prefix/lib64 and 32-bit libraries go under $prefix/lib. We determine
|
||||
dnl the compiler's default mode by looking at the compiler's library search
|
||||
dnl path. If at least one of its elements ends in /lib64 or points to a
|
||||
dnl directory whose absolute pathname ends in /lib64, we assume a 64-bit ABI.
|
||||
dnl Otherwise we use the default, namely "lib".
|
||||
dnl On Solaris systems, the current practice is that on a system supporting
|
||||
dnl 32-bit and 64-bit instruction sets or ABIs, 64-bit libraries go under
|
||||
dnl $prefix/lib/64 (which is a symlink to either $prefix/lib/sparcv9 or
|
||||
dnl $prefix/lib/amd64) and 32-bit libraries go under $prefix/lib.
|
||||
AC_REQUIRE([AC_CANONICAL_HOST])
|
||||
acl_libdirstem=lib
|
||||
acl_libdirstem2=
|
||||
case "$host_os" in
|
||||
solaris*)
|
||||
dnl See Solaris 10 Software Developer Collection > Solaris 64-bit Developer's Guide > The Development Environment
|
||||
dnl <http://docs.sun.com/app/docs/doc/816-5138/dev-env?l=en&a=view>.
|
||||
dnl "Portable Makefiles should refer to any library directories using the 64 symbolic link."
|
||||
dnl But we want to recognize the sparcv9 or amd64 subdirectory also if the
|
||||
dnl symlink is missing, so we set acl_libdirstem2 too.
|
||||
AC_CACHE_CHECK([for 64-bit host], [gl_cv_solaris_64bit],
|
||||
[AC_EGREP_CPP([sixtyfour bits], [
|
||||
#ifdef _LP64
|
||||
sixtyfour bits
|
||||
#endif
|
||||
], [gl_cv_solaris_64bit=yes], [gl_cv_solaris_64bit=no])
|
||||
])
|
||||
if test $gl_cv_solaris_64bit = yes; then
|
||||
acl_libdirstem=lib/64
|
||||
case "$host_cpu" in
|
||||
sparc*) acl_libdirstem2=lib/sparcv9 ;;
|
||||
i*86 | x86_64) acl_libdirstem2=lib/amd64 ;;
|
||||
esac
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
searchpath=`(LC_ALL=C $CC -print-search-dirs) 2>/dev/null | sed -n -e 's,^libraries: ,,p' | sed -e 's,^=,,'`
|
||||
if test -n "$searchpath"; then
|
||||
acl_save_IFS="${IFS= }"; IFS=":"
|
||||
for searchdir in $searchpath; do
|
||||
if test -d "$searchdir"; then
|
||||
case "$searchdir" in
|
||||
*/lib64/ | */lib64 ) acl_libdirstem=lib64 ;;
|
||||
*/../ | */.. )
|
||||
# Better ignore directories of this form. They are misleading.
|
||||
;;
|
||||
*) searchdir=`cd "$searchdir" && pwd`
|
||||
case "$searchdir" in
|
||||
*/lib64 ) acl_libdirstem=lib64 ;;
|
||||
esac ;;
|
||||
esac
|
||||
fi
|
||||
done
|
||||
IFS="$acl_save_IFS"
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
test -n "$acl_libdirstem2" || acl_libdirstem2="$acl_libdirstem"
|
||||
])
|
37
m4/libunistring.m4
Normal file
37
m4/libunistring.m4
Normal file
|
@ -0,0 +1,37 @@
|
|||
# libunistring.m4 serial 1
|
||||
dnl Copyright (C) 2009 Free Software Foundation, Inc.
|
||||
dnl This file is free software; the Free Software Foundation
|
||||
dnl gives unlimited permission to copy and/or distribute it,
|
||||
dnl with or without modifications, as long as this notice is preserved.
|
||||
|
||||
dnl gl_LIBUNISTRING
|
||||
dnl Searches for an installed libunistring.
|
||||
dnl If found, it sets and AC_SUBSTs HAVE_LIBUNISTRING=yes and the LIBUNISTRING
|
||||
dnl and LTLIBUNISTRING variables and augments the CPPFLAGS variable, and
|
||||
dnl #defines HAVE_LIBUNISTRING to 1. Otherwise, it sets and AC_SUBSTs
|
||||
dnl HAVE_LIBUNISTRING=no and LIBUNINSTRING and LTLIBUNISTRING to empty.
|
||||
|
||||
AC_DEFUN([gl_LIBUNISTRING],
|
||||
[
|
||||
dnl First, try to link without -liconv. libunistring often depends on
|
||||
dnl libiconv, but we don't know (and often don't need to know) where
|
||||
dnl libiconv is installed.
|
||||
AC_LIB_HAVE_LINKFLAGS([unistring], [],
|
||||
[#include <uniconv.h>], [u8_strconv_from_locale((char*)0);],
|
||||
[no, consider installing GNU libunistring])
|
||||
if test "$ac_cv_libunistring" != yes; then
|
||||
dnl Second try, with -liconv.
|
||||
AC_REQUIRE([AM_ICONV])
|
||||
if test -n "$LIBICONV"; then
|
||||
glus_save_LIBS="$LIBS"
|
||||
LIBS="$LIBS $LIBICONV"
|
||||
AC_LIB_HAVE_LINKFLAGS([unistring], [],
|
||||
[#include <uniconv.h>], [u8_strconv_from_locale((char*)0);],
|
||||
[no, consider installing GNU libunistring])
|
||||
if test -n "$LIBUNISTRING"; then
|
||||
LIBUNISTRING="$LIBUNISTRING $LIBICONV"
|
||||
fi
|
||||
LIBS="$glus_save_LIBS"
|
||||
fi
|
||||
fi
|
||||
])
|
92
m4/string_h.m4
Normal file
92
m4/string_h.m4
Normal file
|
@ -0,0 +1,92 @@
|
|||
# Configure a GNU-like replacement for <string.h>.
|
||||
|
||||
# Copyright (C) 2007, 2008 Free Software Foundation, Inc.
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
# serial 6
|
||||
|
||||
# Written by Paul Eggert.
|
||||
|
||||
AC_DEFUN([gl_HEADER_STRING_H],
|
||||
[
|
||||
dnl Use AC_REQUIRE here, so that the default behavior below is expanded
|
||||
dnl once only, before all statements that occur in other macros.
|
||||
AC_REQUIRE([gl_HEADER_STRING_H_BODY])
|
||||
])
|
||||
|
||||
AC_DEFUN([gl_HEADER_STRING_H_BODY],
|
||||
[
|
||||
AC_REQUIRE([AC_C_RESTRICT])
|
||||
AC_REQUIRE([gl_HEADER_STRING_H_DEFAULTS])
|
||||
gl_CHECK_NEXT_HEADERS([string.h])
|
||||
])
|
||||
|
||||
AC_DEFUN([gl_STRING_MODULE_INDICATOR],
|
||||
[
|
||||
dnl Use AC_REQUIRE here, so that the default settings are expanded once only.
|
||||
AC_REQUIRE([gl_HEADER_STRING_H_DEFAULTS])
|
||||
GNULIB_[]m4_translit([$1],[abcdefghijklmnopqrstuvwxyz./-],[ABCDEFGHIJKLMNOPQRSTUVWXYZ___])=1
|
||||
])
|
||||
|
||||
AC_DEFUN([gl_HEADER_STRING_H_DEFAULTS],
|
||||
[
|
||||
GNULIB_MEMMEM=0; AC_SUBST([GNULIB_MEMMEM])
|
||||
GNULIB_MEMPCPY=0; AC_SUBST([GNULIB_MEMPCPY])
|
||||
GNULIB_MEMRCHR=0; AC_SUBST([GNULIB_MEMRCHR])
|
||||
GNULIB_RAWMEMCHR=0; AC_SUBST([GNULIB_RAWMEMCHR])
|
||||
GNULIB_STPCPY=0; AC_SUBST([GNULIB_STPCPY])
|
||||
GNULIB_STPNCPY=0; AC_SUBST([GNULIB_STPNCPY])
|
||||
GNULIB_STRCHRNUL=0; AC_SUBST([GNULIB_STRCHRNUL])
|
||||
GNULIB_STRDUP=0; AC_SUBST([GNULIB_STRDUP])
|
||||
GNULIB_STRNDUP=0; AC_SUBST([GNULIB_STRNDUP])
|
||||
GNULIB_STRNLEN=0; AC_SUBST([GNULIB_STRNLEN])
|
||||
GNULIB_STRPBRK=0; AC_SUBST([GNULIB_STRPBRK])
|
||||
GNULIB_STRSEP=0; AC_SUBST([GNULIB_STRSEP])
|
||||
GNULIB_STRSTR=0; AC_SUBST([GNULIB_STRSTR])
|
||||
GNULIB_STRCASESTR=0; AC_SUBST([GNULIB_STRCASESTR])
|
||||
GNULIB_STRTOK_R=0; AC_SUBST([GNULIB_STRTOK_R])
|
||||
GNULIB_MBSLEN=0; AC_SUBST([GNULIB_MBSLEN])
|
||||
GNULIB_MBSNLEN=0; AC_SUBST([GNULIB_MBSNLEN])
|
||||
GNULIB_MBSCHR=0; AC_SUBST([GNULIB_MBSCHR])
|
||||
GNULIB_MBSRCHR=0; AC_SUBST([GNULIB_MBSRCHR])
|
||||
GNULIB_MBSSTR=0; AC_SUBST([GNULIB_MBSSTR])
|
||||
GNULIB_MBSCASECMP=0; AC_SUBST([GNULIB_MBSCASECMP])
|
||||
GNULIB_MBSNCASECMP=0; AC_SUBST([GNULIB_MBSNCASECMP])
|
||||
GNULIB_MBSPCASECMP=0; AC_SUBST([GNULIB_MBSPCASECMP])
|
||||
GNULIB_MBSCASESTR=0; AC_SUBST([GNULIB_MBSCASESTR])
|
||||
GNULIB_MBSCSPN=0; AC_SUBST([GNULIB_MBSCSPN])
|
||||
GNULIB_MBSPBRK=0; AC_SUBST([GNULIB_MBSPBRK])
|
||||
GNULIB_MBSSPN=0; AC_SUBST([GNULIB_MBSSPN])
|
||||
GNULIB_MBSSEP=0; AC_SUBST([GNULIB_MBSSEP])
|
||||
GNULIB_MBSTOK_R=0; AC_SUBST([GNULIB_MBSTOK_R])
|
||||
GNULIB_STRERROR=0; AC_SUBST([GNULIB_STRERROR])
|
||||
GNULIB_STRSIGNAL=0; AC_SUBST([GNULIB_STRSIGNAL])
|
||||
GNULIB_STRVERSCMP=0; AC_SUBST([GNULIB_STRVERSCMP])
|
||||
dnl Assume proper GNU behavior unless another module says otherwise.
|
||||
HAVE_DECL_MEMMEM=1; AC_SUBST([HAVE_DECL_MEMMEM])
|
||||
HAVE_MEMPCPY=1; AC_SUBST([HAVE_MEMPCPY])
|
||||
HAVE_DECL_MEMRCHR=1; AC_SUBST([HAVE_DECL_MEMRCHR])
|
||||
HAVE_RAWMEMCHR=1; AC_SUBST([HAVE_RAWMEMCHR])
|
||||
HAVE_STPCPY=1; AC_SUBST([HAVE_STPCPY])
|
||||
HAVE_STPNCPY=1; AC_SUBST([HAVE_STPNCPY])
|
||||
HAVE_STRCHRNUL=1; AC_SUBST([HAVE_STRCHRNUL])
|
||||
HAVE_DECL_STRDUP=1; AC_SUBST([HAVE_DECL_STRDUP])
|
||||
HAVE_STRNDUP=1; AC_SUBST([HAVE_STRNDUP])
|
||||
HAVE_DECL_STRNDUP=1; AC_SUBST([HAVE_DECL_STRNDUP])
|
||||
HAVE_DECL_STRNLEN=1; AC_SUBST([HAVE_DECL_STRNLEN])
|
||||
HAVE_STRPBRK=1; AC_SUBST([HAVE_STRPBRK])
|
||||
HAVE_STRSEP=1; AC_SUBST([HAVE_STRSEP])
|
||||
HAVE_STRCASESTR=1; AC_SUBST([HAVE_STRCASESTR])
|
||||
HAVE_DECL_STRTOK_R=1; AC_SUBST([HAVE_DECL_STRTOK_R])
|
||||
HAVE_DECL_STRERROR=1; AC_SUBST([HAVE_DECL_STRERROR])
|
||||
HAVE_DECL_STRSIGNAL=1; AC_SUBST([HAVE_DECL_STRSIGNAL])
|
||||
HAVE_STRVERSCMP=1; AC_SUBST([HAVE_STRVERSCMP])
|
||||
REPLACE_MEMMEM=0; AC_SUBST([REPLACE_MEMMEM])
|
||||
REPLACE_STRDUP=0; AC_SUBST([REPLACE_STRDUP])
|
||||
REPLACE_STRSTR=0; AC_SUBST([REPLACE_STRSTR])
|
||||
REPLACE_STRCASESTR=0; AC_SUBST([REPLACE_STRCASESTR])
|
||||
REPLACE_STRERROR=0; AC_SUBST([REPLACE_STRERROR])
|
||||
REPLACE_STRSIGNAL=0; AC_SUBST([REPLACE_STRSIGNAL])
|
||||
])
|
52
m4/visibility.m4
Normal file
52
m4/visibility.m4
Normal file
|
@ -0,0 +1,52 @@
|
|||
# visibility.m4 serial 2 (gettext-0.18)
|
||||
dnl Copyright (C) 2005, 2008 Free Software Foundation, Inc.
|
||||
dnl This file is free software; the Free Software Foundation
|
||||
dnl gives unlimited permission to copy and/or distribute it,
|
||||
dnl with or without modifications, as long as this notice is preserved.
|
||||
|
||||
dnl From Bruno Haible.
|
||||
|
||||
dnl Tests whether the compiler supports the command-line option
|
||||
dnl -fvisibility=hidden and the function and variable attributes
|
||||
dnl __attribute__((__visibility__("hidden"))) and
|
||||
dnl __attribute__((__visibility__("default"))).
|
||||
dnl Does *not* test for __visibility__("protected") - which has tricky
|
||||
dnl semantics (see the 'vismain' test in glibc) and does not exist e.g. on
|
||||
dnl MacOS X.
|
||||
dnl Does *not* test for __visibility__("internal") - which has processor
|
||||
dnl dependent semantics.
|
||||
dnl Does *not* test for #pragma GCC visibility push(hidden) - which is
|
||||
dnl "really only recommended for legacy code".
|
||||
dnl Set the variable CFLAG_VISIBILITY.
|
||||
dnl Defines and sets the variable HAVE_VISIBILITY.
|
||||
|
||||
AC_DEFUN([gl_VISIBILITY],
|
||||
[
|
||||
AC_REQUIRE([AC_PROG_CC])
|
||||
CFLAG_VISIBILITY=
|
||||
HAVE_VISIBILITY=0
|
||||
if test -n "$GCC"; then
|
||||
AC_MSG_CHECKING([for simple visibility declarations])
|
||||
AC_CACHE_VAL([gl_cv_cc_visibility], [
|
||||
gl_save_CFLAGS="$CFLAGS"
|
||||
CFLAGS="$CFLAGS -fvisibility=hidden"
|
||||
AC_TRY_COMPILE(
|
||||
[extern __attribute__((__visibility__("hidden"))) int hiddenvar;
|
||||
extern __attribute__((__visibility__("default"))) int exportedvar;
|
||||
extern __attribute__((__visibility__("hidden"))) int hiddenfunc (void);
|
||||
extern __attribute__((__visibility__("default"))) int exportedfunc (void);],
|
||||
[],
|
||||
[gl_cv_cc_visibility=yes],
|
||||
[gl_cv_cc_visibility=no])
|
||||
CFLAGS="$gl_save_CFLAGS"])
|
||||
AC_MSG_RESULT([$gl_cv_cc_visibility])
|
||||
if test $gl_cv_cc_visibility = yes; then
|
||||
CFLAG_VISIBILITY="-fvisibility=hidden"
|
||||
HAVE_VISIBILITY=1
|
||||
fi
|
||||
fi
|
||||
AC_SUBST([CFLAG_VISIBILITY])
|
||||
AC_SUBST([HAVE_VISIBILITY])
|
||||
AC_DEFINE_UNQUOTED([HAVE_VISIBILITY], [$HAVE_VISIBILITY],
|
||||
[Define to 1 or 0, depending whether the compiler supports simple visibility declarations.])
|
||||
])
|
|
@ -31,30 +31,25 @@ modpath =
|
|||
# putting these core modules first.
|
||||
|
||||
SOURCES = \
|
||||
ice-9/psyntax-pp.scm \
|
||||
ice-9/psyntax-pp.scm \
|
||||
system/base/pmatch.scm system/base/syntax.scm \
|
||||
system/base/compile.scm system/base/language.scm \
|
||||
\
|
||||
system/vm/debug.scm system/vm/frame.scm system/vm/instruction.scm \
|
||||
system/vm/objcode.scm system/vm/profile.scm system/vm/program.scm \
|
||||
system/vm/trace.scm system/vm/vm.scm \
|
||||
\
|
||||
system/xref.scm \
|
||||
\
|
||||
system/repl/repl.scm system/repl/common.scm \
|
||||
system/repl/command.scm \
|
||||
\
|
||||
language/tree-il.scm \
|
||||
language/ghil.scm language/glil.scm language/assembly.scm \
|
||||
\
|
||||
$(SCHEME_LANG_SOURCES) $(ECMASCRIPT_LANG_SOURCES) \
|
||||
$(SCHEME_LANG_SOURCES) \
|
||||
$(TREE_IL_LANG_SOURCES) \
|
||||
$(GHIL_LANG_SOURCES) $(GLIL_LANG_SOURCES) \
|
||||
$(ASSEMBLY_LANG_SOURCES) $(BYTECODE_LANG_SOURCES) \
|
||||
$(OBJCODE_LANG_SOURCES) $(VALUE_LANG_SOURCES) \
|
||||
\
|
||||
$(ICE_9_SOURCES) \
|
||||
$(SRFI_SOURCES) \
|
||||
$(RNRS_SOURCES) \
|
||||
$(OOP_SOURCES) \
|
||||
\
|
||||
$(SYSTEM_SOURCES) \
|
||||
$(ECMASCRIPT_LANG_SOURCES) \
|
||||
$(SCRIPTS_SOURCES)
|
||||
|
||||
## test.scm is not currently installed.
|
||||
|
@ -71,10 +66,19 @@ ice-9/psyntax-pp.scm: ice-9/psyntax.scm
|
|||
$(srcdir)/ice-9/psyntax.scm $(srcdir)/ice-9/psyntax-pp.scm
|
||||
|
||||
SCHEME_LANG_SOURCES = \
|
||||
language/scheme/amatch.scm language/scheme/expand.scm \
|
||||
language/scheme/compile-ghil.scm language/scheme/spec.scm \
|
||||
language/scheme/compile-ghil.scm \
|
||||
language/scheme/spec.scm \
|
||||
language/scheme/compile-tree-il.scm \
|
||||
language/scheme/decompile-tree-il.scm \
|
||||
language/scheme/inline.scm
|
||||
|
||||
TREE_IL_LANG_SOURCES = \
|
||||
language/tree-il/primitives.scm \
|
||||
language/tree-il/optimize.scm \
|
||||
language/tree-il/analyze.scm \
|
||||
language/tree-il/compile-glil.scm \
|
||||
language/tree-il/spec.scm
|
||||
|
||||
GHIL_LANG_SOURCES = \
|
||||
language/ghil/spec.scm language/ghil/compile-glil.scm
|
||||
|
||||
|
@ -140,7 +144,6 @@ ICE_9_SOURCES = \
|
|||
ice-9/debugger.scm \
|
||||
ice-9/documentation.scm \
|
||||
ice-9/emacs.scm \
|
||||
ice-9/expand-support.scm \
|
||||
ice-9/expect.scm \
|
||||
ice-9/format.scm \
|
||||
ice-9/getopt-long.scm \
|
||||
|
@ -198,6 +201,7 @@ SRFI_SOURCES = \
|
|||
srfi/srfi-14.scm \
|
||||
srfi/srfi-16.scm \
|
||||
srfi/srfi-17.scm \
|
||||
srfi/srfi-18.scm \
|
||||
srfi/srfi-19.scm \
|
||||
srfi/srfi-26.scm \
|
||||
srfi/srfi-31.scm \
|
||||
|
@ -209,6 +213,10 @@ SRFI_SOURCES = \
|
|||
srfi/srfi-69.scm \
|
||||
srfi/srfi-88.scm
|
||||
|
||||
RNRS_SOURCES = \
|
||||
rnrs/bytevector.scm \
|
||||
rnrs/io/ports.scm
|
||||
|
||||
EXTRA_DIST += scripts/ChangeLog-2008
|
||||
EXTRA_DIST += scripts/README
|
||||
|
||||
|
@ -226,6 +234,16 @@ OOP_SOURCES = \
|
|||
oop/goops/accessors.scm \
|
||||
oop/goops/simple.scm
|
||||
|
||||
SYSTEM_SOURCES = \
|
||||
system/vm/debug.scm system/vm/frame.scm system/vm/instruction.scm \
|
||||
system/vm/objcode.scm system/vm/profile.scm system/vm/program.scm \
|
||||
system/vm/trace.scm system/vm/vm.scm \
|
||||
\
|
||||
system/xref.scm \
|
||||
\
|
||||
system/repl/repl.scm system/repl/common.scm \
|
||||
system/repl/command.scm
|
||||
|
||||
EXTRA_DIST += oop/ChangeLog-2008
|
||||
|
||||
NOCOMP_SOURCES = \
|
||||
|
@ -242,5 +260,4 @@ NOCOMP_SOURCES = \
|
|||
ice-9/debugging/steps.scm \
|
||||
ice-9/debugging/trace.scm \
|
||||
ice-9/debugging/traps.scm \
|
||||
ice-9/debugging/trc.scm \
|
||||
srfi/srfi-18.scm
|
||||
ice-9/debugging/trc.scm
|
||||
|
|
|
@ -33,6 +33,13 @@
|
|||
|
||||
|
||||
|
||||
;; Before compiling, make sure any symbols are resolved in the (guile)
|
||||
;; module, the primary location of those symbols, rather than in
|
||||
;; (guile-user), the default module that we compile in.
|
||||
|
||||
(eval-when (compile)
|
||||
(set-current-module (resolve-module '(guile))))
|
||||
|
||||
;;; {R4RS compliance}
|
||||
;;;
|
||||
|
||||
|
@ -86,6 +93,42 @@
|
|||
(define (provided? feature)
|
||||
(and (memq feature *features*) #t))
|
||||
|
||||
|
||||
|
||||
;;; {and-map and or-map}
|
||||
;;;
|
||||
;;; (and-map fn lst) is like (and (fn (car lst)) (fn (cadr lst)) (fn...) ...)
|
||||
;;; (or-map fn lst) is like (or (fn (car lst)) (fn (cadr lst)) (fn...) ...)
|
||||
;;;
|
||||
|
||||
;; and-map f l
|
||||
;;
|
||||
;; Apply f to successive elements of l until exhaustion or f returns #f.
|
||||
;; If returning early, return #f. Otherwise, return the last value returned
|
||||
;; by f. If f has never been called because l is empty, return #t.
|
||||
;;
|
||||
(define (and-map f lst)
|
||||
(let loop ((result #t)
|
||||
(l lst))
|
||||
(and result
|
||||
(or (and (null? l)
|
||||
result)
|
||||
(loop (f (car l)) (cdr l))))))
|
||||
|
||||
;; or-map f l
|
||||
;;
|
||||
;; Apply f to successive elements of l until exhaustion or while f returns #f.
|
||||
;; If returning early, return the return value of f.
|
||||
;;
|
||||
(define (or-map f lst)
|
||||
(let loop ((result #f)
|
||||
(l lst))
|
||||
(or result
|
||||
(and (not (null? l))
|
||||
(loop (f (car l)) (cdr l))))))
|
||||
|
||||
|
||||
|
||||
;; let format alias simple-format until the more complete version is loaded
|
||||
|
||||
(define format simple-format)
|
||||
|
@ -125,97 +168,181 @@
|
|||
|
||||
|
||||
|
||||
;; Before the module system boots, there are no module names. But
|
||||
;; psyntax does want a module-name definition, so give it one.
|
||||
;; Define a minimal stub of the module API for psyntax, before modules
|
||||
;; have booted.
|
||||
(define (module-name x)
|
||||
'(guile))
|
||||
(define (module-define! module sym val)
|
||||
(let ((v (hashq-ref (%get-pre-modules-obarray) sym)))
|
||||
(if v
|
||||
(variable-set! v val)
|
||||
(hashq-set! (%get-pre-modules-obarray) sym
|
||||
(make-variable val)))))
|
||||
(define (module-ref module sym)
|
||||
(let ((v (module-variable module sym)))
|
||||
(if v (variable-ref v) (error "badness!" (pk module) (pk sym)))))
|
||||
(define (resolve-module . args)
|
||||
#f)
|
||||
|
||||
;; (eval-when (situation...) form...)
|
||||
;;
|
||||
;; Evaluate certain code based on the situation that eval-when is used
|
||||
;; in. There are three situations defined.
|
||||
;;
|
||||
;; `load' triggers when a file is loaded via `load', or when a compiled
|
||||
;; file is loaded.
|
||||
;;
|
||||
;; `compile' triggers when an expression is compiled.
|
||||
;;
|
||||
;; `eval' triggers when code is evaluated interactively, as at the REPL
|
||||
;; or via the `compile' or `eval' procedures.
|
||||
;; Input hook to syncase -- so that we might be able to pass annotated
|
||||
;; expressions in. Currently disabled. Maybe we should just use
|
||||
;; source-properties directly.
|
||||
(define (annotation? x) #f)
|
||||
|
||||
;; NB: this macro is only ever expanded by the interpreter. The compiler
|
||||
;; notices it and interprets the situations differently.
|
||||
(define eval-when
|
||||
(procedure->memoizing-macro
|
||||
(lambda (exp env)
|
||||
(let ((situations (cadr exp))
|
||||
(body (cddr exp)))
|
||||
(if (or (memq 'load situations)
|
||||
(memq 'eval situations))
|
||||
`(begin . ,body))))))
|
||||
;; API provided by psyntax
|
||||
(define syntax-violation #f)
|
||||
(define datum->syntax #f)
|
||||
(define syntax->datum #f)
|
||||
(define identifier? #f)
|
||||
(define generate-temporaries #f)
|
||||
(define bound-identifier=? #f)
|
||||
(define free-identifier=? #f)
|
||||
(define sc-expand #f)
|
||||
|
||||
;; $sc-expand is an implementation detail of psyntax. It is used by
|
||||
;; expanded macros, to dispatch an input against a set of patterns.
|
||||
(define $sc-dispatch #f)
|
||||
|
||||
;; Load it up!
|
||||
(primitive-load-path "ice-9/psyntax-pp")
|
||||
|
||||
;; %pre-modules-transformer is the Scheme expander from now until the
|
||||
;; module system has booted up.
|
||||
(define %pre-modules-transformer sc-expand)
|
||||
|
||||
(define-syntax and
|
||||
(syntax-rules ()
|
||||
((_) #t)
|
||||
((_ x) x)
|
||||
((_ x y ...) (if x (and y ...) #f))))
|
||||
|
||||
(define-syntax or
|
||||
(syntax-rules ()
|
||||
((_) #f)
|
||||
((_ x) x)
|
||||
((_ x y ...) (let ((t x)) (if t t (or y ...))))))
|
||||
|
||||
;; The "maybe-more" bits are something of a hack, so that we can support
|
||||
;; SRFI-61. Rewrites into a standalone syntax-case macro would be
|
||||
;; appreciated.
|
||||
(define-syntax cond
|
||||
(syntax-rules (=> else)
|
||||
((_ "maybe-more" test consequent)
|
||||
(if test consequent))
|
||||
|
||||
((_ "maybe-more" test consequent clause ...)
|
||||
(if test consequent (cond clause ...)))
|
||||
|
||||
((_ (else else1 else2 ...))
|
||||
(begin else1 else2 ...))
|
||||
|
||||
((_ (test => receiver) more-clause ...)
|
||||
(let ((t test))
|
||||
(cond "maybe-more" t (receiver t) more-clause ...)))
|
||||
|
||||
((_ (generator guard => receiver) more-clause ...)
|
||||
(call-with-values (lambda () generator)
|
||||
(lambda t
|
||||
(cond "maybe-more"
|
||||
(apply guard t) (apply receiver t) more-clause ...))))
|
||||
|
||||
((_ (test => receiver ...) more-clause ...)
|
||||
(syntax-violation 'cond "wrong number of receiver expressions"
|
||||
'(test => receiver ...)))
|
||||
((_ (generator guard => receiver ...) more-clause ...)
|
||||
(syntax-violation 'cond "wrong number of receiver expressions"
|
||||
'(generator guard => receiver ...)))
|
||||
|
||||
((_ (test) more-clause ...)
|
||||
(let ((t test))
|
||||
(cond "maybe-more" t t more-clause ...)))
|
||||
|
||||
((_ (test body1 body2 ...) more-clause ...)
|
||||
(cond "maybe-more"
|
||||
test (begin body1 body2 ...) more-clause ...))))
|
||||
|
||||
(define-syntax case
|
||||
(syntax-rules (else)
|
||||
((case (key ...)
|
||||
clauses ...)
|
||||
(let ((atom-key (key ...)))
|
||||
(case atom-key clauses ...)))
|
||||
((case key
|
||||
(else result1 result2 ...))
|
||||
(begin result1 result2 ...))
|
||||
((case key
|
||||
((atoms ...) result1 result2 ...))
|
||||
(if (memv key '(atoms ...))
|
||||
(begin result1 result2 ...)))
|
||||
((case key
|
||||
((atoms ...) result1 result2 ...)
|
||||
clause clauses ...)
|
||||
(if (memv key '(atoms ...))
|
||||
(begin result1 result2 ...)
|
||||
(case key clause clauses ...)))))
|
||||
|
||||
(define-syntax do
|
||||
(syntax-rules ()
|
||||
((do ((var init step ...) ...)
|
||||
(test expr ...)
|
||||
command ...)
|
||||
(letrec
|
||||
((loop
|
||||
(lambda (var ...)
|
||||
(if test
|
||||
(begin
|
||||
(if #f #f)
|
||||
expr ...)
|
||||
(begin
|
||||
command
|
||||
...
|
||||
(loop (do "step" var step ...)
|
||||
...))))))
|
||||
(loop init ...)))
|
||||
((do "step" x)
|
||||
x)
|
||||
((do "step" x y)
|
||||
y)))
|
||||
|
||||
(define-syntax delay
|
||||
(syntax-rules ()
|
||||
((_ exp) (make-promise (lambda () exp)))))
|
||||
|
||||
|
||||
|
||||
;; Before compiling, make sure any symbols are resolved in the (guile)
|
||||
;; module, the primary location of those symbols, rather than in
|
||||
;; (guile-user), the default module that we compile in.
|
||||
|
||||
(eval-when (compile)
|
||||
(set-current-module (resolve-module '(guile))))
|
||||
|
||||
;;; {Defmacros}
|
||||
;;;
|
||||
;;; Depends on: features, eval-case
|
||||
;;;
|
||||
|
||||
(define macro-table (make-weak-key-hash-table 61))
|
||||
(define xformer-table (make-weak-key-hash-table 61))
|
||||
(define-syntax define-macro
|
||||
(lambda (x)
|
||||
"Define a defmacro."
|
||||
(syntax-case x ()
|
||||
((_ (macro . args) doc body1 body ...)
|
||||
(string? (syntax->datum (syntax doc)))
|
||||
(syntax (define-macro macro doc (lambda args body1 body ...))))
|
||||
((_ (macro . args) body ...)
|
||||
(syntax (define-macro macro #f (lambda args body ...))))
|
||||
((_ macro doc transformer)
|
||||
(or (string? (syntax->datum (syntax doc)))
|
||||
(not (syntax->datum (syntax doc))))
|
||||
(syntax
|
||||
(define-syntax macro
|
||||
(lambda (y)
|
||||
doc
|
||||
(syntax-case y ()
|
||||
((_ . args)
|
||||
(let ((v (syntax->datum (syntax args))))
|
||||
(datum->syntax y (apply transformer v))))))))))))
|
||||
|
||||
(define (defmacro? m) (hashq-ref macro-table m))
|
||||
(define (assert-defmacro?! m) (hashq-set! macro-table m #t))
|
||||
(define (defmacro-transformer m) (hashq-ref xformer-table m))
|
||||
(define (set-defmacro-transformer! m t) (hashq-set! xformer-table m t))
|
||||
|
||||
(define defmacro:transformer
|
||||
(lambda (f)
|
||||
(let* ((xform (lambda (exp env)
|
||||
(copy-tree (apply f (cdr exp)))))
|
||||
(a (procedure->memoizing-macro xform)))
|
||||
(assert-defmacro?! a)
|
||||
(set-defmacro-transformer! a f)
|
||||
a)))
|
||||
|
||||
|
||||
(define defmacro
|
||||
(let ((defmacro-transformer
|
||||
(lambda (name parms . body)
|
||||
(let ((transformer `(lambda ,parms ,@body)))
|
||||
`(eval-when
|
||||
(eval load compile)
|
||||
(define ,name (defmacro:transformer ,transformer)))))))
|
||||
(defmacro:transformer defmacro-transformer)))
|
||||
|
||||
|
||||
;; XXX - should the definition of the car really be looked up in the
|
||||
;; current module?
|
||||
|
||||
(define (macroexpand-1 e)
|
||||
(cond
|
||||
((pair? e) (let* ((a (car e))
|
||||
(val (and (symbol? a) (local-ref (list a)))))
|
||||
(if (defmacro? val)
|
||||
(apply (defmacro-transformer val) (cdr e))
|
||||
e)))
|
||||
(#t e)))
|
||||
|
||||
(define (macroexpand e)
|
||||
(cond
|
||||
((pair? e) (let* ((a (car e))
|
||||
(val (and (symbol? a) (local-ref (list a)))))
|
||||
(if (defmacro? val)
|
||||
(macroexpand (apply (defmacro-transformer val) (cdr e)))
|
||||
e)))
|
||||
(#t e)))
|
||||
(define-syntax defmacro
|
||||
(lambda (x)
|
||||
"Define a defmacro, with the old lispy defun syntax."
|
||||
(syntax-case x ()
|
||||
((_ macro args doc body1 body ...)
|
||||
(string? (syntax->datum (syntax doc)))
|
||||
(syntax (define-macro macro doc (lambda args body1 body ...))))
|
||||
((_ macro args body ...)
|
||||
(syntax (define-macro macro #f (lambda args body ...)))))))
|
||||
|
||||
(provide 'defmacro)
|
||||
|
||||
|
@ -477,40 +604,6 @@
|
|||
|
||||
|
||||
|
||||
;;; {and-map and or-map}
|
||||
;;;
|
||||
;;; (and-map fn lst) is like (and (fn (car lst)) (fn (cadr lst)) (fn...) ...)
|
||||
;;; (or-map fn lst) is like (or (fn (car lst)) (fn (cadr lst)) (fn...) ...)
|
||||
;;;
|
||||
|
||||
;; and-map f l
|
||||
;;
|
||||
;; Apply f to successive elements of l until exhaustion or f returns #f.
|
||||
;; If returning early, return #f. Otherwise, return the last value returned
|
||||
;; by f. If f has never been called because l is empty, return #t.
|
||||
;;
|
||||
(define (and-map f lst)
|
||||
(let loop ((result #t)
|
||||
(l lst))
|
||||
(and result
|
||||
(or (and (null? l)
|
||||
result)
|
||||
(loop (f (car l)) (cdr l))))))
|
||||
|
||||
;; or-map f l
|
||||
;;
|
||||
;; Apply f to successive elements of l until exhaustion or while f returns #f.
|
||||
;; If returning early, return the return value of f.
|
||||
;;
|
||||
(define (or-map f lst)
|
||||
(let loop ((result #f)
|
||||
(l lst))
|
||||
(or result
|
||||
(and (not (null? l))
|
||||
(loop (f (car l)) (cdr l))))))
|
||||
|
||||
|
||||
|
||||
(if (provided? 'posix)
|
||||
(primitive-load-path "ice-9/posix"))
|
||||
|
||||
|
@ -757,6 +850,26 @@
|
|||
(start-stack 'load-stack
|
||||
(primitive-load-path name)))
|
||||
|
||||
(define %load-verbosely #f)
|
||||
(define (assert-load-verbosity v) (set! %load-verbosely v))
|
||||
|
||||
(define (%load-announce file)
|
||||
(if %load-verbosely
|
||||
(with-output-to-port (current-error-port)
|
||||
(lambda ()
|
||||
(display ";;; ")
|
||||
(display "loading ")
|
||||
(display file)
|
||||
(newline)
|
||||
(force-output)))))
|
||||
|
||||
(set! %load-hook %load-announce)
|
||||
|
||||
(define (load name . reader)
|
||||
(with-fluid* current-reader (and (pair? reader) (car reader))
|
||||
(lambda ()
|
||||
(start-stack 'load-stack
|
||||
(primitive-load name)))))
|
||||
|
||||
|
||||
|
||||
|
@ -848,9 +961,6 @@
|
|||
;;; Reader code for various "#c" forms.
|
||||
;;;
|
||||
|
||||
(read-hash-extend #\' (lambda (c port)
|
||||
(read port)))
|
||||
|
||||
(define read-eval? (make-fluid))
|
||||
(fluid-set! read-eval? #f)
|
||||
(read-hash-extend #\.
|
||||
|
@ -1133,11 +1243,8 @@
|
|||
(define (%print-module mod port) ; unused args: depth length style table)
|
||||
(display "#<" port)
|
||||
(display (or (module-kind mod) "module") port)
|
||||
(let ((name (module-name mod)))
|
||||
(if name
|
||||
(begin
|
||||
(display " " port)
|
||||
(display name port))))
|
||||
(display " " port)
|
||||
(display (module-name mod) port)
|
||||
(display " " port)
|
||||
(display (number->string (object-address mod) 16) port)
|
||||
(display ">" port))
|
||||
|
@ -1194,7 +1301,8 @@
|
|||
"Lazy-binder expected to be a procedure or #f." binder))
|
||||
|
||||
(let ((module (module-constructor (make-hash-table size)
|
||||
uses binder #f #f #f #f #f
|
||||
uses binder #f %pre-modules-transformer
|
||||
#f #f #f
|
||||
(make-hash-table %default-import-size)
|
||||
'()
|
||||
(make-weak-key-hash-table 31))))
|
||||
|
@ -1219,7 +1327,7 @@
|
|||
|
||||
(define module-transformer (record-accessor module-type 'transformer))
|
||||
(define set-module-transformer! (record-modifier module-type 'transformer))
|
||||
(define module-name (record-accessor module-type 'name))
|
||||
;; (define module-name (record-accessor module-type 'name)) wait until mods are booted
|
||||
(define set-module-name! (record-modifier module-type 'name))
|
||||
(define module-kind (record-accessor module-type 'kind))
|
||||
(define set-module-kind! (record-modifier module-type 'kind))
|
||||
|
@ -1363,7 +1471,9 @@
|
|||
;; or its uses?
|
||||
;;
|
||||
(define (module-bound? m v)
|
||||
(module-search module-locally-bound? m v))
|
||||
(let ((var (module-variable m v)))
|
||||
(and var
|
||||
(variable-bound? var))))
|
||||
|
||||
;;; {Is a symbol interned in a module?}
|
||||
;;;
|
||||
|
@ -1799,7 +1909,7 @@
|
|||
val
|
||||
(let ((m (make-module 31)))
|
||||
(set-module-kind! m 'directory)
|
||||
(set-module-name! m (append (or (module-name module) '())
|
||||
(set-module-name! m (append (module-name module)
|
||||
(list (car name))))
|
||||
(module-define! module (car name) m)
|
||||
m)))
|
||||
|
@ -1853,22 +1963,31 @@
|
|||
(define default-duplicate-binding-procedures #f)
|
||||
|
||||
(define %app (make-module 31))
|
||||
(set-module-name! %app '(%app))
|
||||
(define app %app) ;; for backwards compatability
|
||||
|
||||
(local-define '(%app modules) (make-module 31))
|
||||
(let ((m (make-module 31)))
|
||||
(set-module-name! m '())
|
||||
(local-define '(%app modules) m))
|
||||
(local-define '(%app modules guile) the-root-module)
|
||||
|
||||
;; This boots the module system. All bindings needed by modules.c
|
||||
;; must have been defined by now.
|
||||
;;
|
||||
(set-current-module the-root-module)
|
||||
;; definition deferred for syncase's benefit.
|
||||
(define module-name
|
||||
(let ((accessor (record-accessor module-type 'name)))
|
||||
(lambda (mod)
|
||||
(or (accessor mod)
|
||||
(begin
|
||||
(set-module-name! mod (list (gensym)))
|
||||
(accessor mod))))))
|
||||
|
||||
;; (define-special-value '(%app modules new-ws) (lambda () (make-scm-module)))
|
||||
|
||||
(define (try-load-module name)
|
||||
(or (begin-deprecated (try-module-linked name))
|
||||
(try-module-autoload name)
|
||||
(begin-deprecated (try-module-dynamic-link name))))
|
||||
(try-module-autoload name))
|
||||
|
||||
(define (purify-module! module)
|
||||
"Removes bindings in MODULE which are inherited from the (guile) module."
|
||||
|
@ -2002,23 +2121,34 @@
|
|||
((#:use-module #:use-syntax)
|
||||
(or (pair? (cdr kws))
|
||||
(unrecognized kws))
|
||||
(let* ((interface-args (cadr kws))
|
||||
(interface (apply resolve-interface interface-args)))
|
||||
(and (eq? (car kws) #:use-syntax)
|
||||
(or (symbol? (caar interface-args))
|
||||
(error "invalid module name for use-syntax"
|
||||
(car interface-args)))
|
||||
(set-module-transformer!
|
||||
module
|
||||
(module-ref interface
|
||||
(car (last-pair (car interface-args)))
|
||||
#f)))
|
||||
(cond
|
||||
((equal? (caadr kws) '(ice-9 syncase))
|
||||
(issue-deprecation-warning
|
||||
"(ice-9 syncase) is deprecated. Support for syntax-case is now in Guile core.")
|
||||
(loop (cddr kws)
|
||||
(cons interface reversed-interfaces)
|
||||
reversed-interfaces
|
||||
exports
|
||||
re-exports
|
||||
replacements
|
||||
autoloads)))
|
||||
autoloads))
|
||||
(else
|
||||
(let* ((interface-args (cadr kws))
|
||||
(interface (apply resolve-interface interface-args)))
|
||||
(and (eq? (car kws) #:use-syntax)
|
||||
(or (symbol? (caar interface-args))
|
||||
(error "invalid module name for use-syntax"
|
||||
(car interface-args)))
|
||||
(set-module-transformer!
|
||||
module
|
||||
(module-ref interface
|
||||
(car (last-pair (car interface-args)))
|
||||
#f)))
|
||||
(loop (cddr kws)
|
||||
(cons interface reversed-interfaces)
|
||||
exports
|
||||
re-exports
|
||||
replacements
|
||||
autoloads)))))
|
||||
((#:autoload)
|
||||
(or (and (pair? (cdr kws)) (pair? (cddr kws)))
|
||||
(unrecognized kws))
|
||||
|
@ -2310,11 +2440,12 @@ module '(ice-9 q) '(make-q q-length))}."
|
|||
(define (set-repl-prompt! v) (set! scm-repl-prompt v))
|
||||
|
||||
(define (default-pre-unwind-handler key . args)
|
||||
(save-stack pre-unwind-handler-dispatch)
|
||||
(save-stack 1)
|
||||
(apply throw key args))
|
||||
|
||||
(define (pre-unwind-handler-dispatch key . args)
|
||||
(apply default-pre-unwind-handler key args))
|
||||
(begin-deprecated
|
||||
(define (pre-unwind-handler-dispatch key . args)
|
||||
(apply default-pre-unwind-handler key args)))
|
||||
|
||||
(define abort-hook (make-hook))
|
||||
|
||||
|
@ -2391,15 +2522,7 @@ module '(ice-9 q) '(make-q q-length))}."
|
|||
(else
|
||||
(apply bad-throw key args)))))))
|
||||
|
||||
;; Note that having just `pre-unwind-handler-dispatch'
|
||||
;; here is connected with the mechanism that
|
||||
;; produces a nice backtrace upon error. If, for
|
||||
;; example, this is replaced with (lambda args
|
||||
;; (apply pre-unwind-handler-dispatch args)), the stack
|
||||
;; cutting (in save-stack) goes wrong and ends up
|
||||
;; saving no stack at all, so there is no
|
||||
;; backtrace.
|
||||
pre-unwind-handler-dispatch)))
|
||||
default-pre-unwind-handler)))
|
||||
|
||||
(if next (loop next) status)))
|
||||
(set! set-batch-mode?! (lambda (arg)
|
||||
|
@ -2674,32 +2797,6 @@ module '(ice-9 q) '(make-q q-length))}."
|
|||
`(with-fluids* (list ,@fluids) (list ,@values)
|
||||
(lambda () ,@body)))))
|
||||
|
||||
|
||||
|
||||
;;; {Macros}
|
||||
;;;
|
||||
|
||||
;; actually....hobbit might be able to hack these with a little
|
||||
;; coaxing
|
||||
;;
|
||||
|
||||
(define (primitive-macro? m)
|
||||
(and (macro? m)
|
||||
(not (macro-transformer m))))
|
||||
|
||||
(defmacro define-macro (first . rest)
|
||||
(let ((name (if (symbol? first) first (car first)))
|
||||
(transformer
|
||||
(if (symbol? first)
|
||||
(car rest)
|
||||
`(lambda ,(cdr first) ,@rest))))
|
||||
`(eval-when
|
||||
(eval load compile)
|
||||
(define ,name (defmacro:transformer ,transformer)))))
|
||||
|
||||
|
||||
|
||||
|
||||
;;; {While}
|
||||
;;;
|
||||
;;; with `continue' and `break'.
|
||||
|
@ -2839,50 +2936,33 @@ module '(ice-9 q) '(make-q q-length))}."
|
|||
(defmacro use-syntax (spec)
|
||||
`(eval-when
|
||||
(eval load compile)
|
||||
,@(if (pair? spec)
|
||||
`((process-use-modules (list
|
||||
(list ,@(compile-interface-spec spec))))
|
||||
(set-module-transformer! (current-module)
|
||||
,(car (last-pair spec))))
|
||||
`((set-module-transformer! (current-module) ,spec)))
|
||||
*unspecified*))
|
||||
(issue-deprecation-warning
|
||||
"`use-syntax' is deprecated. Please contact guile-devel for more info.")
|
||||
(process-use-modules (list (list ,@(compile-interface-spec spec))))
|
||||
*unspecified*))
|
||||
|
||||
;; Dirk:FIXME:: This incorrect (according to R5RS) syntax needs to be changed
|
||||
;; as soon as guile supports hygienic macros.
|
||||
(define define-private define)
|
||||
(define-syntax define-private
|
||||
(syntax-rules ()
|
||||
((_ foo bar)
|
||||
(define foo bar))))
|
||||
|
||||
(defmacro define-public args
|
||||
(define (syntax)
|
||||
(error "bad syntax" (list 'define-public args)))
|
||||
(define (defined-name n)
|
||||
(cond
|
||||
((symbol? n) n)
|
||||
((pair? n) (defined-name (car n)))
|
||||
(else (syntax))))
|
||||
(cond
|
||||
((null? args)
|
||||
(syntax))
|
||||
(#t
|
||||
(let ((name (defined-name (car args))))
|
||||
`(begin
|
||||
(define-private ,@args)
|
||||
(export ,name))))))
|
||||
(define-syntax define-public
|
||||
(syntax-rules ()
|
||||
((_ (name . args) . body)
|
||||
(define-public name (lambda args . body)))
|
||||
((_ name val)
|
||||
(begin
|
||||
(define name val)
|
||||
(export name)))))
|
||||
|
||||
(defmacro defmacro-public args
|
||||
(define (syntax)
|
||||
(error "bad syntax" (list 'defmacro-public args)))
|
||||
(define (defined-name n)
|
||||
(cond
|
||||
((symbol? n) n)
|
||||
(else (syntax))))
|
||||
(cond
|
||||
((null? args)
|
||||
(syntax))
|
||||
(#t
|
||||
(let ((name (defined-name (car args))))
|
||||
`(begin
|
||||
(export-syntax ,name)
|
||||
(defmacro ,@args))))))
|
||||
(define-syntax defmacro-public
|
||||
(syntax-rules ()
|
||||
((_ name args . body)
|
||||
(begin
|
||||
(defmacro name args . body)
|
||||
(export-syntax name)))))
|
||||
|
||||
;; Export a local variable
|
||||
|
||||
|
@ -2936,19 +3016,6 @@ module '(ice-9 q) '(make-q q-length))}."
|
|||
|
||||
(define load load-module)
|
||||
|
||||
|
||||
|
||||
;;; {Compiler interface}
|
||||
;;;
|
||||
;;; The full compiler interface can be found in (system). Here we put a
|
||||
;;; few useful procedures into the global namespace.
|
||||
|
||||
(module-autoload! the-scm-module
|
||||
'(system base compile)
|
||||
'(compile
|
||||
compile-time-environment))
|
||||
|
||||
|
||||
|
||||
|
||||
;;; {Parameters}
|
||||
|
@ -3371,6 +3438,13 @@ module '(ice-9 q) '(make-q q-length))}."
|
|||
;;; Place the user in the guile-user module.
|
||||
;;;
|
||||
|
||||
(define-module (guile-user))
|
||||
;;; FIXME: annotate ?
|
||||
;; (define (syncase exp)
|
||||
;; (with-fluids ((expansion-eval-closure
|
||||
;; (module-eval-closure (current-module))))
|
||||
;; (deannotate/source-properties (sc-expand (annotate exp)))))
|
||||
|
||||
(define-module (guile-user)
|
||||
#:autoload (system base compile) (compile))
|
||||
|
||||
;;; boot-9.scm ends here
|
||||
|
|
|
@ -1,27 +1,20 @@
|
|||
(use-modules (ice-9 syncase))
|
||||
|
||||
;; XXX - We need to be inside (ice-9 syncase) since psyntax.ss calls
|
||||
;; `eval' int he `interaction-environment' aka the current module and
|
||||
;; it expects to have `andmap' there. The reason for this escapes me
|
||||
;; at the moment.
|
||||
;;
|
||||
(define-module (ice-9 syncase))
|
||||
|
||||
(define source (list-ref (command-line) 1))
|
||||
(define target (list-ref (command-line) 2))
|
||||
|
||||
(let ((in (open-input-file source))
|
||||
(out (open-output-file (string-append target ".tmp"))))
|
||||
(let loop ((x (read in)))
|
||||
(if (eof-object? x)
|
||||
(begin
|
||||
(close-port out)
|
||||
(close-port in))
|
||||
(begin
|
||||
(write (strip-expansion-structures
|
||||
(sc-expand3 x 'c '(compile load eval)))
|
||||
out)
|
||||
(newline out)
|
||||
(loop (read in))))))
|
||||
|
||||
(system (format #f "mv -f ~s.tmp ~s" target target))
|
||||
(use-modules (language tree-il))
|
||||
(let ((source (list-ref (command-line) 1))
|
||||
(target (list-ref (command-line) 2)))
|
||||
(let ((in (open-input-file source))
|
||||
(out (open-output-file (string-append target ".tmp"))))
|
||||
(write '(eval-when (compile) (set-current-module (resolve-module '(guile))))
|
||||
out)
|
||||
(newline out)
|
||||
(let loop ((x (read in)))
|
||||
(if (eof-object? x)
|
||||
(begin
|
||||
(close-port out)
|
||||
(close-port in))
|
||||
(begin
|
||||
(write (tree-il->scheme
|
||||
(sc-expand x 'c '(compile load eval)))
|
||||
out)
|
||||
(newline out)
|
||||
(loop (read in))))))
|
||||
(system (format #f "mv -f ~s.tmp ~s" target target)))
|
||||
|
|
|
@ -195,15 +195,11 @@ OBJECT can be a procedure, macro or any object that has its
|
|||
`documentation' property set."
|
||||
(or (and (procedure? object)
|
||||
(proc-doc object))
|
||||
(and (defmacro? object)
|
||||
(proc-doc (defmacro-transformer object)))
|
||||
(and (macro? object)
|
||||
(let ((transformer (macro-transformer object)))
|
||||
(and transformer
|
||||
(proc-doc transformer))))
|
||||
(object-property object 'documentation)
|
||||
(and (program? object)
|
||||
(program-documentation object))
|
||||
(and (macro? object)
|
||||
(object-documentation (macro-transformer object)))
|
||||
(and (procedure? object)
|
||||
(not (closure? object))
|
||||
(procedure-name object)
|
||||
|
|
|
@ -1,169 +0,0 @@
|
|||
;;;; Copyright (C) 2009 Free Software Foundation, Inc.
|
||||
;;;;
|
||||
;;;; This library is free software; you can redistribute it and/or
|
||||
;;;; modify it under the terms of the GNU Lesser General Public
|
||||
;;;; License as published by the Free Software Foundation; either
|
||||
;;;; version 2.1 of the License, or (at your option) any later version.
|
||||
;;;;
|
||||
;;;; This library is distributed in the hope that it will be useful,
|
||||
;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
;;;; Lesser General Public License for more details.
|
||||
;;;;
|
||||
;;;; You should have received a copy of the GNU Lesser General Public
|
||||
;;;; License along with this library; if not, write to the Free Software
|
||||
;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
;;;;
|
||||
|
||||
|
||||
(define-module (ice-9 expand-support)
|
||||
:export (<annotation> annotation? annotate deannotate make-annotation
|
||||
annotation-expression annotation-source annotation-stripped
|
||||
set-annotation-stripped!
|
||||
deannotate/source-properties
|
||||
|
||||
<module-ref> make-module-ref
|
||||
module-ref-symbol module-ref-modname module-ref-public?
|
||||
|
||||
<lexical> make-lexical
|
||||
lexical-name lexical-gensym
|
||||
|
||||
strip-expansion-structures))
|
||||
|
||||
(define <annotation>
|
||||
(make-vtable "prprpw"
|
||||
(lambda (struct port)
|
||||
(display "#<annotated " port)
|
||||
(display (struct-ref struct 0) port)
|
||||
(display ">" port))))
|
||||
|
||||
(define (annotation? x)
|
||||
(and (struct? x) (eq? (struct-vtable x) <annotation>)))
|
||||
|
||||
(define (make-annotation e s . stripped?)
|
||||
(if (null? stripped?)
|
||||
(make-struct <annotation> 0 e s #f)
|
||||
(apply make-struct <annotation> 0 e s stripped?)))
|
||||
|
||||
(define (annotation-expression a)
|
||||
(struct-ref a 0))
|
||||
(define (annotation-source a)
|
||||
(struct-ref a 1))
|
||||
(define (annotation-stripped a)
|
||||
(struct-ref a 2))
|
||||
(define (set-annotation-stripped! a stripped?)
|
||||
(struct-set! a 2 stripped?))
|
||||
|
||||
(define (annotate e)
|
||||
(let ((p (if (pair? e) (source-properties e) #f))
|
||||
(out (cond ((and (list? e) (not (null? e)))
|
||||
(map annotate e))
|
||||
((pair? e)
|
||||
(cons (annotate (car e)) (annotate (cdr e))))
|
||||
(else e))))
|
||||
(if (pair? p)
|
||||
(make-annotation out p #f)
|
||||
out)))
|
||||
|
||||
(define (deannotate e)
|
||||
(cond ((list? e)
|
||||
(map deannotate e))
|
||||
((pair? e)
|
||||
(cons (deannotate (car e)) (deannotate (cdr e))))
|
||||
((annotation? e) (deannotate (annotation-expression e)))
|
||||
(else e)))
|
||||
|
||||
(define (deannotate/source-properties e)
|
||||
(cond ((list? e)
|
||||
(map deannotate/source-properties e))
|
||||
((pair? e)
|
||||
(cons (deannotate/source-properties (car e))
|
||||
(deannotate/source-properties (cdr e))))
|
||||
((annotation? e)
|
||||
(let ((e (deannotate/source-properties (annotation-expression e)))
|
||||
(source (annotation-source e)))
|
||||
(if (pair? e)
|
||||
(set-source-properties! e source))
|
||||
e))
|
||||
(else e)))
|
||||
|
||||
|
||||
|
||||
(define <module-ref>
|
||||
(make-vtable "prprpr"
|
||||
(lambda (struct port)
|
||||
(display "#<" port)
|
||||
(display (if (module-ref-public? struct) "@ " "@@ ") port)
|
||||
(display (module-ref-modname struct) port)
|
||||
(display " " port)
|
||||
(display (module-ref-symbol struct) port)
|
||||
(display ">" port))))
|
||||
|
||||
(define (module-ref? x)
|
||||
(and (struct? x) (eq? (struct-vtable x) <module-ref>)))
|
||||
|
||||
(define (make-module-ref modname symbol public?)
|
||||
(make-struct <module-ref> 0 modname symbol public?))
|
||||
|
||||
(define (module-ref-modname a)
|
||||
(struct-ref a 0))
|
||||
(define (module-ref-symbol a)
|
||||
(struct-ref a 1))
|
||||
(define (module-ref-public? a)
|
||||
(struct-ref a 2))
|
||||
|
||||
|
||||
|
||||
(define <lexical>
|
||||
(make-vtable "prpr"
|
||||
(lambda (struct port)
|
||||
(display "#<lexical " port)
|
||||
(display (lexical-name struct) port)
|
||||
(display "/" port)
|
||||
(display (lexical-gensym struct) port)
|
||||
(display ">" port))))
|
||||
|
||||
(define (lexical? x)
|
||||
(and (struct? x) (eq? (struct-vtable x) <lexical>)))
|
||||
|
||||
(define (make-lexical name gensym)
|
||||
(make-struct <lexical> 0 name gensym))
|
||||
|
||||
(define (lexical-name a)
|
||||
(struct-ref a 0))
|
||||
(define (lexical-gensym a)
|
||||
(struct-ref a 1))
|
||||
|
||||
|
||||
|
||||
(define (strip-expansion-structures e)
|
||||
(cond ((list? e)
|
||||
(map strip-expansion-structures e))
|
||||
((pair? e)
|
||||
(cons (strip-expansion-structures (car e))
|
||||
(strip-expansion-structures (cdr e))))
|
||||
((annotation? e)
|
||||
(let ((e (strip-expansion-structures (annotation-expression e)))
|
||||
(source (annotation-source e)))
|
||||
(if (pair? e)
|
||||
(set-source-properties! e source))
|
||||
e))
|
||||
((module-ref? e)
|
||||
(cond
|
||||
((or (not (module-ref-modname e))
|
||||
(eq? (module-ref-modname e)
|
||||
(module-name (current-module)))
|
||||
(and (not (module-ref-public? e))
|
||||
(not (module-variable
|
||||
(resolve-module (module-ref-modname e))
|
||||
(module-ref-symbol e)))))
|
||||
(module-ref-symbol e))
|
||||
(else
|
||||
`(,(if (module-ref-public? e) '@ '@@)
|
||||
,(module-ref-modname e)
|
||||
,(module-ref-symbol e)))))
|
||||
((lexical? e)
|
||||
(lexical-gensym e))
|
||||
((record? e)
|
||||
(error "unexpected record in expansion" e))
|
||||
(else e)))
|
|
@ -194,6 +194,6 @@
|
|||
(define match:runtime-structures #f)
|
||||
(define match:set-runtime-structures (lambda (v) (set! match:runtime-structures v)))
|
||||
(define match:primitive-vector? vector?)
|
||||
(defmacro defstruct args (let ((field? (lambda (x) (if (symbol? x) ((lambda () #t)) (if (and (pair? x) (symbol? (car x)) (pair? (cdr x)) (symbol? (cadr x)) (null? (cddr x))) ((lambda () #t)) ((lambda () #f)))))) (selector-name (lambda (x) (if (symbol? x) ((lambda () x)) (if (and (pair? x) (symbol? (car x)) (pair? (cdr x)) (null? (cddr x))) ((lambda (s) s) (car x)) (match:error x))))) (mutator-name (lambda (x) (if (symbol? x) ((lambda () #f)) (if (and (pair? x) (pair? (cdr x)) (symbol? (cadr x)) (null? (cddr x))) ((lambda (s) s) (cadr x)) (match:error x))))) (filter-map-with-index (lambda (f l) (letrec ((mapi (lambda (l i) (cond ((null? l) (quote ())) ((f (car l) i) => (lambda (x) (cons x (mapi (cdr l) (+ 1 i))))) (else (mapi (cdr l) (+ 1 i))))))) (mapi l 1))))) (let ((g296 (lambda () (match:syntax-err (quasiquote ((unquote defstruct) (unquote-splicing args))) "syntax error in")))) (if (and (pair? args) (symbol? (car args)) (pair? (cdr args)) (symbol? (cadr args)) (pair? (cddr args)) (symbol? (caddr args)) (list? (cdddr args))) (let g298 ((g299 (cdddr args)) (g297 (quote ()))) (if (null? g299) ((lambda (name constructor predicate fields) (let* ((selectors (map selector-name fields)) (mutators (map mutator-name fields)) (tag (if match:runtime-structures (gensym) (quasiquote (quote (unquote (match:make-structure-tag name)))))) (vectorP (cond ((eq? match:structure-control (quote disjoint)) (quote match:primitive-vector?)) ((eq? match:structure-control (quote vector)) (quote vector?))))) (cond ((eq? match:structure-control (quote disjoint)) (if (eq? vector? match:primitive-vector?) (set! vector? (lambda (v) (and (match:primitive-vector? v) (or (zero? (vector-length v)) (not (symbol? (vector-ref v 0))) (not (match:structure? (vector-ref v 0)))))))) (if (not (memq predicate match:disjoint-predicates)) (set! match:disjoint-predicates (cons predicate match:disjoint-predicates)))) ((eq? match:structure-control (quote vector)) (if (not (memq predicate match:vector-structures)) (set! match:vector-structures (cons predicate match:vector-structures)))) (else (match:syntax-err (quote (vector disjoint)) "invalid value for match:structure-control, legal values are"))) (quasiquote (begin (unquote-splicing (if match:runtime-structures (quasiquote ((define (unquote tag) (match:make-structure-tag (quote (unquote name)))))) (quote ()))) (define (unquote constructor) (lambda (unquote selectors) (vector (unquote tag) (unquote-splicing selectors)))) (define (unquote predicate) (lambda (obj) (and ((unquote vectorP) obj) (= (vector-length obj) (unquote (+ 1 (length selectors)))) (eq? (vector-ref obj 0) (unquote tag))))) (unquote-splicing (filter-map-with-index (lambda (n i) (quasiquote (define (unquote n) (lambda (obj) (vector-ref obj (unquote i)))))) selectors)) (unquote-splicing (filter-map-with-index (lambda (n i) (and n (quasiquote (define (unquote n) (lambda (obj newval) (vector-set! obj (unquote i) newval)))))) mutators)))))) (car args) (cadr args) (caddr args) (reverse g297)) (if (field? (car g299)) (g298 (cdr g299) (cons (car g299) g297)) (g296)))) (g296)))))
|
||||
(defmacro defstruct args (let ((field? (lambda (x) (if (symbol? x) ((lambda () #t)) (if (and (pair? x) (symbol? (car x)) (pair? (cdr x)) (symbol? (cadr x)) (null? (cddr x))) ((lambda () #t)) ((lambda () #f)))))) (selector-name (lambda (x) (if (symbol? x) ((lambda () x)) (if (and (pair? x) (symbol? (car x)) (pair? (cdr x)) (null? (cddr x))) ((lambda (s) s) (car x)) (match:error x))))) (mutator-name (lambda (x) (if (symbol? x) ((lambda () #f)) (if (and (pair? x) (pair? (cdr x)) (symbol? (cadr x)) (null? (cddr x))) ((lambda (s) s) (cadr x)) (match:error x))))) (filter-map-with-index (lambda (f l) (letrec ((mapi (lambda (l i) (cond ((null? l) (quote ())) ((f (car l) i) => (lambda (x) (cons x (mapi (cdr l) (+ 1 i))))) (else (mapi (cdr l) (+ 1 i))))))) (mapi l 1))))) (let ((g296 (lambda () (match:syntax-err (quasiquote (defstruct (unquote-splicing args))) "syntax error in")))) (if (and (pair? args) (symbol? (car args)) (pair? (cdr args)) (symbol? (cadr args)) (pair? (cddr args)) (symbol? (caddr args)) (list? (cdddr args))) (let g298 ((g299 (cdddr args)) (g297 (quote ()))) (if (null? g299) ((lambda (name constructor predicate fields) (let* ((selectors (map selector-name fields)) (mutators (map mutator-name fields)) (tag (if match:runtime-structures (gensym) (quasiquote (quote (unquote (match:make-structure-tag name)))))) (vectorP (cond ((eq? match:structure-control (quote disjoint)) (quote match:primitive-vector?)) ((eq? match:structure-control (quote vector)) (quote vector?))))) (cond ((eq? match:structure-control (quote disjoint)) (if (eq? vector? match:primitive-vector?) (set! vector? (lambda (v) (and (match:primitive-vector? v) (or (zero? (vector-length v)) (not (symbol? (vector-ref v 0))) (not (match:structure? (vector-ref v 0)))))))) (if (not (memq predicate match:disjoint-predicates)) (set! match:disjoint-predicates (cons predicate match:disjoint-predicates)))) ((eq? match:structure-control (quote vector)) (if (not (memq predicate match:vector-structures)) (set! match:vector-structures (cons predicate match:vector-structures)))) (else (match:syntax-err (quote (vector disjoint)) "invalid value for match:structure-control, legal values are"))) (quasiquote (begin (unquote-splicing (if match:runtime-structures (quasiquote ((define (unquote tag) (match:make-structure-tag (quote (unquote name)))))) (quote ()))) (define (unquote constructor) (lambda (unquote selectors) (vector (unquote tag) (unquote-splicing selectors)))) (define (unquote predicate) (lambda (obj) (and ((unquote vectorP) obj) (= (vector-length obj) (unquote (+ 1 (length selectors)))) (eq? (vector-ref obj 0) (unquote tag))))) (unquote-splicing (filter-map-with-index (lambda (n i) (quasiquote (define (unquote n) (lambda (obj) (vector-ref obj (unquote i)))))) selectors)) (unquote-splicing (filter-map-with-index (lambda (n i) (and n (quasiquote (define (unquote n) (lambda (obj newval) (vector-set! obj (unquote i) newval)))))) mutators)))))) (car args) (cadr args) (caddr args) (reverse g297)) (if (field? (car g299)) (g298 (cdr g299) (cons (car g299) g297)) (g296)))) (g296)))))
|
||||
(defmacro define-structure args (let ((g311 (lambda () (match:syntax-err (quasiquote (define-structure (unquote-splicing args))) "syntax error in")))) (if (and (pair? args) (pair? (car args)) (list? (cdar args))) (if (null? (cdr args)) ((lambda (name id1) (quasiquote (define-structure ((unquote name) (unquote-splicing id1)) ()))) (caar args) (cdar args)) (if (and (pair? (cdr args)) (list? (cadr args))) (let g308 ((g309 (cadr args)) (g307 (quote ())) (g306 (quote ()))) (if (null? g309) (if (null? (cddr args)) ((lambda (name id1 id2 val) (let ((mk-id (lambda (id) (if (and (pair? id) (equal? (car id) (quote @)) (pair? (cdr id)) (symbol? (cadr id)) (null? (cddr id))) ((lambda (x) x) (cadr id)) ((lambda () (quasiquote (! (unquote id))))))))) (quasiquote (define-const-structure ((unquote name) (unquote-splicing (map mk-id id1))) (unquote (map (lambda (id v) (quasiquote ((unquote (mk-id id)) (unquote v)))) id2 val)))))) (caar args) (cdar args) (reverse g306) (reverse g307)) (g311)) (if (and (pair? (car g309)) (pair? (cdar g309)) (null? (cddar g309))) (g308 (cdr g309) (cons (cadar g309) g307) (cons (caar g309) g306)) (g311)))) (g311))) (g311))))
|
||||
(defmacro define-const-structure args (let ((field? (lambda (id) (if (symbol? id) ((lambda () #t)) (if (and (pair? id) (equal? (car id) (quote !)) (pair? (cdr id)) (symbol? (cadr id)) (null? (cddr id))) ((lambda () #t)) ((lambda () #f)))))) (field-name (lambda (x) (if (symbol? x) x (cadr x)))) (has-mutator? (lambda (x) (not (symbol? x)))) (filter-map-with-index (lambda (f l) (letrec ((mapi (lambda (l i) (cond ((null? l) (quote ())) ((f (car l) i) => (lambda (x) (cons x (mapi (cdr l) (+ 1 i))))) (else (mapi (cdr l) (+ 1 i))))))) (mapi l 1)))) (symbol-append (lambda l (string->symbol (apply string-append (map (lambda (x) (cond ((symbol? x) (symbol->string x)) ((number? x) (number->string x)) (else x))) l)))))) (let ((g335 (lambda () (match:syntax-err (quasiquote (define-const-structure (unquote-splicing args))) "syntax error in")))) (if (and (pair? args) (pair? (car args)) (list? (cdar args))) (if (null? (cdr args)) ((lambda (name id1) (quasiquote (define-const-structure ((unquote name) (unquote-splicing id1)) ()))) (caar args) (cdar args)) (if (symbol? (caar args)) (let g328 ((g329 (cdar args)) (g327 (quote ()))) (if (null? g329) (if (and (pair? (cdr args)) (list? (cadr args))) (let g332 ((g333 (cadr args)) (g331 (quote ())) (g330 (quote ()))) (if (null? g333) (if (null? (cddr args)) ((lambda (name id1 id2 val) (let* ((id1id2 (append id1 id2)) (raw-constructor (symbol-append (quote make-raw-) name)) (constructor (symbol-append (quote make-) name)) (predicate (symbol-append name (quote ?)))) (quasiquote (begin ((unquote defstruct) (unquote name) (unquote raw-constructor) (unquote predicate) (unquote-splicing (filter-map-with-index (lambda (arg i) (if (has-mutator? arg) (quasiquote ((unquote (symbol-append name (quote -) i)) (unquote (symbol-append (quote set-) name (quote -) i (quote !))))) (symbol-append name (quote -) i))) id1id2))) (unquote (if (null? id2) (quasiquote (define (unquote constructor) (unquote raw-constructor))) (let* ((make-fresh (lambda (x) (if (eq? (quote _) x) (gensym) x))) (names1 (map make-fresh (map field-name id1))) (names2 (map make-fresh (map field-name id2)))) (quasiquote (define (unquote constructor) (lambda (unquote names1) (let* (unquote (map list names2 val)) ((unquote raw-constructor) (unquote-splicing names1) (unquote-splicing names2))))))))) (unquote-splicing (filter-map-with-index (lambda (field i) (if (eq? (field-name field) (quote _)) #f (quasiquote (define (unquote (symbol-append name (quote -) (field-name field))) (unquote (symbol-append name (quote -) i)))))) id1id2)) (unquote-splicing (filter-map-with-index (lambda (field i) (if (or (eq? (field-name field) (quote _)) (not (has-mutator? field))) #f (quasiquote (define (unquote (symbol-append (quote set-) name (quote -) (field-name field) (quote !))) (unquote (symbol-append (quote set-) name (quote -) i (quote !))))))) id1id2)))))) (caar args) (reverse g327) (reverse g330) (reverse g331)) (g335)) (if (and (pair? (car g333)) (field? (caar g333)) (pair? (cdar g333)) (null? (cddar g333))) (g332 (cdr g333) (cons (cadar g333) g331) (cons (caar g333) g330)) (g335)))) (g335)) (if (field? (car g329)) (g328 (cdr g329) (cons (car g329) g327)) (g335)))) (g335))) (g335)))))
|
||||
(defmacro define-const-structure args (let ((field? (lambda (id) (if (symbol? id) ((lambda () #t)) (if (and (pair? id) (equal? (car id) (quote !)) (pair? (cdr id)) (symbol? (cadr id)) (null? (cddr id))) ((lambda () #t)) ((lambda () #f)))))) (field-name (lambda (x) (if (symbol? x) x (cadr x)))) (has-mutator? (lambda (x) (not (symbol? x)))) (filter-map-with-index (lambda (f l) (letrec ((mapi (lambda (l i) (cond ((null? l) (quote ())) ((f (car l) i) => (lambda (x) (cons x (mapi (cdr l) (+ 1 i))))) (else (mapi (cdr l) (+ 1 i))))))) (mapi l 1)))) (symbol-append (lambda l (string->symbol (apply string-append (map (lambda (x) (cond ((symbol? x) (symbol->string x)) ((number? x) (number->string x)) (else x))) l)))))) (let ((g335 (lambda () (match:syntax-err (quasiquote (define-const-structure (unquote-splicing args))) "syntax error in")))) (if (and (pair? args) (pair? (car args)) (list? (cdar args))) (if (null? (cdr args)) ((lambda (name id1) (quasiquote (define-const-structure ((unquote name) (unquote-splicing id1)) ()))) (caar args) (cdar args)) (if (symbol? (caar args)) (let g328 ((g329 (cdar args)) (g327 (quote ()))) (if (null? g329) (if (and (pair? (cdr args)) (list? (cadr args))) (let g332 ((g333 (cadr args)) (g331 (quote ())) (g330 (quote ()))) (if (null? g333) (if (null? (cddr args)) ((lambda (name id1 id2 val) (let* ((id1id2 (append id1 id2)) (raw-constructor (symbol-append (quote make-raw-) name)) (constructor (symbol-append (quote make-) name)) (predicate (symbol-append name (quote ?)))) (quasiquote (begin (defstruct (unquote name) (unquote raw-constructor) (unquote predicate) (unquote-splicing (filter-map-with-index (lambda (arg i) (if (has-mutator? arg) (quasiquote ((unquote (symbol-append name (quote -) i)) (unquote (symbol-append (quote set-) name (quote -) i (quote !))))) (symbol-append name (quote -) i))) id1id2))) (unquote (if (null? id2) (quasiquote (define (unquote constructor) (unquote raw-constructor))) (let* ((make-fresh (lambda (x) (if (eq? (quote _) x) (gensym) x))) (names1 (map make-fresh (map field-name id1))) (names2 (map make-fresh (map field-name id2)))) (quasiquote (define (unquote constructor) (lambda (unquote names1) (let* (unquote (map list names2 val)) ((unquote raw-constructor) (unquote-splicing names1) (unquote-splicing names2))))))))) (unquote-splicing (filter-map-with-index (lambda (field i) (if (eq? (field-name field) (quote _)) #f (quasiquote (define (unquote (symbol-append name (quote -) (field-name field))) (unquote (symbol-append name (quote -) i)))))) id1id2)) (unquote-splicing (filter-map-with-index (lambda (field i) (if (or (eq? (field-name field) (quote _)) (not (has-mutator? field))) #f (quasiquote (define (unquote (symbol-append (quote set-) name (quote -) (field-name field) (quote !))) (unquote (symbol-append (quote set-) name (quote -) i (quote !))))))) id1id2)))))) (caar args) (reverse g327) (reverse g330) (reverse g331)) (g335)) (if (and (pair? (car g333)) (field? (caar g333)) (pair? (cdar g333)) (null? (cddar g333))) (g332 (cdr g333) (cons (cadar g333) g331) (cons (caar g333) g330)) (g335)))) (g335)) (if (field? (car g329)) (g328 (cdr g329) (cons (car g329) g327)) (g335)))) (g335))) (g335)))))
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue