From da81e75d3e65445fa56865a28f83b07391853a0a Mon Sep 17 00:00:00 2001 From: Mark H Weaver Date: Wed, 15 Jan 2014 02:37:46 -0500 Subject: [PATCH 1/7] Document that we support srfi-87 and add it to %cond-expand-features. * module/ice-9/boot-9.scm (%cond-expand-features): Add srfi-87. * doc/ref/srfi-modules.texi (SRFI-0): Add srfi-87 to the list of core features. (SRFI-87): New node. --- doc/ref/srfi-modules.texi | 10 ++++++++++ module/ice-9/boot-9.scm | 1 + 2 files changed, 11 insertions(+) diff --git a/doc/ref/srfi-modules.texi b/doc/ref/srfi-modules.texi index 6da2b9e88..6f1ed0542 100644 --- a/doc/ref/srfi-modules.texi +++ b/doc/ref/srfi-modules.texi @@ -54,6 +54,7 @@ get the relevant SRFI documents from the SRFI home page * SRFI-62:: S-expression comments. * SRFI-67:: Compare procedures * SRFI-69:: Basic hash tables. +* SRFI-87:: => in case clauses. * SRFI-88:: Keyword objects. * SRFI-98:: Accessing environment variables. * SRFI-105:: Curly-infix expressions. @@ -156,6 +157,7 @@ srfi-39 srfi-55 srfi-61 srfi-62 +srfi-87 srfi-105 @end example @@ -5040,6 +5042,14 @@ Answer a hash value appropriate for equality predicate @code{equal?}, @code{hash} is a backwards-compatible replacement for Guile's built-in @code{hash}. +@node SRFI-87 +@subsection SRFI-87 => in case clauses +@cindex SRFI-87 + +Starting from version 2.0.6, Guile's core @code{case} syntax supports +@code{=>} in clauses, as specified by SRFI-87/R7RS. +@xref{Conditionals}. + @node SRFI-88 @subsection SRFI-88 Keyword Objects @cindex SRFI-88 diff --git a/module/ice-9/boot-9.scm b/module/ice-9/boot-9.scm index 733c2b1a4..640229ef4 100644 --- a/module/ice-9/boot-9.scm +++ b/module/ice-9/boot-9.scm @@ -4044,6 +4044,7 @@ when none is available, reading FILE-NAME with READER." srfi-55 ;; require-extension srfi-61 ;; general cond clause srfi-62 ;; s-expression comments + srfi-87 ;; => in case clauses srfi-105 ;; curly infix expressions )) From 2d6a3144a122982d5b6a9365943f73891bdb87d3 Mon Sep 17 00:00:00 2001 From: Mark H Weaver Date: Wed, 15 Jan 2014 03:08:32 -0500 Subject: [PATCH 2/7] Document that we support srfi-46 and add it to %cond-expand-features. * module/ice-9/boot-9.scm (%cond-expand-features): Add srfi-46. * doc/ref/srfi-modules.texi (SRFI-0): Add srfi-46 to the list of core features. (SRFI-46): New node. * doc/ref/api-macros.texi (Syntax Rules): Mention that the custom ellipsis identifier support is specified by SRFI-46. * test-suite/tests/syntax.test ("syntax-rules"): Add ellipsis hygiene test from SRFI-46. --- doc/ref/api-macros.texi | 6 +++--- doc/ref/srfi-modules.texi | 11 +++++++++++ module/ice-9/boot-9.scm | 1 + test-suite/tests/syntax.test | 17 +++++++++++++++-- 4 files changed, 30 insertions(+), 5 deletions(-) diff --git a/doc/ref/api-macros.texi b/doc/ref/api-macros.texi index 030daedb0..acfbc6556 100644 --- a/doc/ref/api-macros.texi +++ b/doc/ref/api-macros.texi @@ -1,7 +1,7 @@ @c -*-texinfo-*- @c This is part of the GNU Guile Reference Manual. -@c Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004, 2009, 2010, 2011, 2012, 2013 -@c Free Software Foundation, Inc. +@c Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004, 2009, 2010, 2011, +@c 2012, 2013, 2014 Free Software Foundation, Inc. @c See the file guile.texi for copying conditions. @node Macros @@ -392,7 +392,7 @@ templates. For example: When writing macros that generate macro definitions, it is convenient to use a different ellipsis identifier at each level. Guile allows the desired ellipsis identifier to be specified as the first operand to -@code{syntax-rules}, as per R7RS. For example: +@code{syntax-rules}, as specified by SRFI-46 and R7RS. For example: @example (define-syntax define-quotation-macros diff --git a/doc/ref/srfi-modules.texi b/doc/ref/srfi-modules.texi index 6f1ed0542..66d5bd1d9 100644 --- a/doc/ref/srfi-modules.texi +++ b/doc/ref/srfi-modules.texi @@ -48,6 +48,7 @@ get the relevant SRFI documents from the SRFI home page * SRFI-41:: Streams. * SRFI-42:: Eager comprehensions * SRFI-45:: Primitives for expressing iterative lazy algorithms +* SRFI-46:: Basic syntax-rules Extensions. * SRFI-55:: Requiring Features. * SRFI-60:: Integers as bits. * SRFI-61:: A more general `cond' clause @@ -154,6 +155,7 @@ srfi-16 srfi-23 srfi-30 srfi-39 +srfi-46 srfi-55 srfi-61 srfi-62 @@ -4658,6 +4660,15 @@ apply @code{force} to arguments of deconstructors (e.g., @code{car}, wrap procedure bodies with @code{(lazy ...)}. @end itemize +@node SRFI-46 +@subsection SRFI-46 Basic syntax-rules Extensions +@cindex SRFI-46 + +Guile's core @code{syntax-rules} supports the extensions specified by +SRFI-46/R7RS. Tail patterns have been supported since at least Guile +2.0, and custom ellipsis identifiers have been supported since Guile +2.0.10. @xref{Syntax Rules}. + @node SRFI-55 @subsection SRFI-55 - Requiring Features @cindex SRFI-55 diff --git a/module/ice-9/boot-9.scm b/module/ice-9/boot-9.scm index 640229ef4..e4b3b58cf 100644 --- a/module/ice-9/boot-9.scm +++ b/module/ice-9/boot-9.scm @@ -4041,6 +4041,7 @@ when none is available, reading FILE-NAME with READER." srfi-23 ;; `error` procedure srfi-30 ;; nested multi-line comments srfi-39 ;; parameterize + srfi-46 ;; basic syntax-rules extensions srfi-55 ;; require-extension srfi-61 ;; general cond clause srfi-62 ;; s-expression comments diff --git a/test-suite/tests/syntax.test b/test-suite/tests/syntax.test index 5c2a703d8..a1129e9dc 100644 --- a/test-suite/tests/syntax.test +++ b/test-suite/tests/syntax.test @@ -1,7 +1,7 @@ ;;;; syntax.test --- test suite for Guile's syntactic forms -*- scheme -*- ;;;; ;;;; Copyright (C) 2001, 2003, 2004, 2005, 2006, 2009, 2010, -;;;; 2011, 2012, 2013 Free Software Foundation, Inc. +;;;; 2011, 2012, 2013, 2014 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 @@ -1209,7 +1209,20 @@ '((((x y) …) ...) (((x y) ...) …))))))) (define-syntax bar (foo x y z)) - (bar a b c)))) + (bar a b c))) + + ;; This test is given in SRFI-46. + (pass-if-equal "custom ellipsis is handled hygienically" + '((1) 2 (3) (4)) + (let-syntax + ((f (syntax-rules () + ((f ?e) + (let-syntax + ((g (syntax-rules --- () + ((g (??x ?e) (??y ---)) + '((??x) ?e (??y) ---))))) + (g (1 2) (3 4))))))) + (f ---)))) (with-test-prefix "syntax-error" From 6df03222128887bf9982631183ab1cf6c144fe42 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludovic=20Court=C3=A8s?= Date: Wed, 15 Jan 2014 23:07:25 +0100 Subject: [PATCH 3/7] Custom binary input ports sanity-check the return value of 'read!'. * libguile/r6rs-ports.c (cbip_fill_input): Throw an exception when C_OCTETS is greater than what was requested. * test-suite/tests/r6rs-ports.test ("7.2.7 Input Ports")["custom binary input port 'read!' returns too much"]: New test. --- libguile/r6rs-ports.c | 10 +++++++--- test-suite/tests/r6rs-ports.test | 9 +++++++++ 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/libguile/r6rs-ports.c b/libguile/r6rs-ports.c index 790c24cce..0b1d1628e 100644 --- a/libguile/r6rs-ports.c +++ b/libguile/r6rs-ports.c @@ -350,9 +350,11 @@ cbip_fill_input (SCM port) if (c_port->read_pos >= c_port->read_end) { /* Invoke the user's `read!' procedure. */ - unsigned c_octets; + size_t c_octets, c_requested; SCM bv, read_proc, octets; + c_requested = c_port->read_buf_size; + /* Use the bytevector associated with PORT as the buffer passed to the `read!' procedure, thereby avoiding additional allocations. */ bv = SCM_CBIP_BYTEVECTOR (port); @@ -366,8 +368,10 @@ cbip_fill_input (SCM port) == SCM_BYTEVECTOR_LENGTH (bv)); octets = scm_call_3 (read_proc, bv, SCM_INUM0, - SCM_I_MAKINUM (CBIP_BUFFER_SIZE)); - c_octets = scm_to_uint (octets); + scm_from_size_t (c_requested)); + c_octets = scm_to_size_t (octets); + if (SCM_UNLIKELY (c_octets > c_requested)) + scm_out_of_range (FUNC_NAME, octets); c_port->read_pos = (unsigned char *) SCM_BYTEVECTOR_CONTENTS (bv); c_port->read_end = (unsigned char *) c_port->read_pos + c_octets; diff --git a/test-suite/tests/r6rs-ports.test b/test-suite/tests/r6rs-ports.test index eaae29fdc..2b62bedbf 100644 --- a/test-suite/tests/r6rs-ports.test +++ b/test-suite/tests/r6rs-ports.test @@ -411,6 +411,15 @@ (not (or (port-has-port-position? port) (port-has-set-port-position!? port))))) + (pass-if-exception "custom binary input port 'read!' returns too much" + exception:out-of-range + ;; In Guile <= 2.0.9 this would segfault. + (let* ((read! (lambda (bv start count) + (+ count 4242))) + (port (make-custom-binary-input-port "the port" read! + #f #f #f))) + (get-bytevector-all port))) + (pass-if-equal "custom binary input port supports `port-position', \ not `set-port-position!'" 42 From 802a25b1ed5c738aa5f9d3d01f33eb89b22afd1b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludovic=20Court=C3=A8s?= Date: Wed, 15 Jan 2014 23:41:23 +0100 Subject: [PATCH 4/7] web: Don't throw if a response is longer than its Content-Length says. * module/web/response.scm (make-delimited-input-port): Read at most LEN bytes from PORT, instead of trying to read more and returning an error if more is available. Try again when 'get-bytevector-n!' return zero. * test-suite/tests/web-response.test (example-1): Add garbage after the body itself. --- module/web/response.scm | 27 ++++++++++++++++----------- test-suite/tests/web-response.test | 6 ++++-- 2 files changed, 20 insertions(+), 13 deletions(-) diff --git a/module/web/response.scm b/module/web/response.scm index 570a2d7d2..58e3f1141 100644 --- a/module/web/response.scm +++ b/module/web/response.scm @@ -1,6 +1,6 @@ ;;; HTTP response objects -;; Copyright (C) 2010, 2011, 2012, 2013 Free Software Foundation, Inc. +;; Copyright (C) 2010, 2011, 2012, 2013, 2014 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 @@ -246,16 +246,21 @@ closes PORT, unless KEEP-ALIVE? is true." bytes-read len)) (define (read! bv start count) - (let ((ret (get-bytevector-n! port bv start count))) - (if (eof-object? ret) - (if (= bytes-read len) - 0 - (fail)) - (begin - (set! bytes-read (+ bytes-read ret)) - (if (> bytes-read len) - (fail) - ret))))) + ;; Read at most LEN bytes in total. HTTP/1.1 doesn't say what to do + ;; when a server provides more than the Content-Length, but it seems + ;; wise to just stop reading at LEN. + (let ((count (min count (- len bytes-read)))) + (let loop ((ret (get-bytevector-n! port bv start count))) + (cond ((eof-object? ret) + (if (= bytes-read len) + 0 ; EOF + (fail))) + ((and (zero? ret) (> count 0)) + ;; Do not return zero since zero means EOF, so try again. + (loop (get-bytevector-n! port bv start count))) + (else + (set! bytes-read (+ bytes-read ret)) + ret))))) (define close (and (not keep-alive?) diff --git a/test-suite/tests/web-response.test b/test-suite/tests/web-response.test index f9679f5e2..99b129334 100644 --- a/test-suite/tests/web-response.test +++ b/test-suite/tests/web-response.test @@ -1,6 +1,6 @@ ;;;; web-response.test --- HTTP responses -*- mode: scheme; coding: utf-8; -*- ;;;; -;;;; Copyright (C) 2010, 2011, 2012 Free Software Foundation, Inc. +;;;; Copyright (C) 2010, 2011, 2012, 2014 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 @@ -39,7 +39,9 @@ Content-Encoding: gzip\r Content-Length: 36\r Content-Type: text/html; charset=utf-8\r \r -abcdefghijklmnopqrstuvwxyz0123456789") +abcdefghijklmnopqrstuvwxyz0123456789 +-> Here is trailing garbage that should be ignored because it is + beyond Content-Length.") (define example-2 "HTTP/1.1 200 OK\r From 3ff8a9d6ff9c8b9f3be7c03b624b3042bb61079f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludovic=20Court=C3=A8s?= Date: Fri, 17 Jan 2014 18:18:41 +0100 Subject: [PATCH 5/7] Arrange so that 'file-encoding' does not truncate the encoding name. Fixes . Reported by Sree Harsha Totakura . * libguile/read.c (ENCODING_NAME_MAX_SIZE): New macro. (SCM_ENCODING_SEARCH_SIZE): Change to 500 + ENCODING_NAME_MAX_SIZE. (scm_i_scan_for_encoding): Return NULL if there's less than ENCODING_NAME_MAX_SIZE bytes once "coding: *" has been read. * test-suite/tests/coding.test ("line comment")["http://bugs.gnu.org/16463"]: New test. --- libguile/read.c | 30 +++++++++++++++++++++++------- test-suite/tests/coding.test | 10 ++++++++-- 2 files changed, 31 insertions(+), 9 deletions(-) diff --git a/libguile/read.c b/libguile/read.c index f7edc4f8a..419ad1276 100644 --- a/libguile/read.c +++ b/libguile/read.c @@ -2046,11 +2046,20 @@ scm_get_hash_procedure (int c) } } -#define SCM_ENCODING_SEARCH_SIZE (500) +/* Maximum size of an encoding name. This is a bit more than the + longest name listed at + ("ISO-2022-JP-2", 13 + characters.) */ +#define ENCODING_NAME_MAX_SIZE 20 -/* Search the first few hundred characters of a file for an Emacs-like coding - declaration. Returns either NULL or a string whose storage has been - allocated with `scm_gc_malloc ()'. */ +/* Number of bytes at the beginning or end of a file that are scanned + for a "coding:" declaration. */ +#define SCM_ENCODING_SEARCH_SIZE (500 + ENCODING_NAME_MAX_SIZE) + + +/* Search the SCM_ENCODING_SEARCH_SIZE bytes of a file for an Emacs-like + coding declaration. Returns either NULL or a string whose storage + has been allocated with `scm_gc_malloc'. */ char * scm_i_scan_for_encoding (SCM port) { @@ -2109,8 +2118,8 @@ scm_i_scan_for_encoding (SCM port) if ((pos = strstr(pos, "coding")) == NULL) return NULL; - pos += strlen("coding"); - if (pos - header >= SCM_ENCODING_SEARCH_SIZE || + pos += strlen ("coding"); + if (pos - header >= SCM_ENCODING_SEARCH_SIZE || (*pos == ':' || *pos == '=')) { pos ++; @@ -2119,10 +2128,17 @@ scm_i_scan_for_encoding (SCM port) } /* skip spaces */ - while (pos - header <= SCM_ENCODING_SEARCH_SIZE && + while (pos - header <= SCM_ENCODING_SEARCH_SIZE && (*pos == ' ' || *pos == '\t')) pos ++; + if (pos - header >= SCM_ENCODING_SEARCH_SIZE - ENCODING_NAME_MAX_SIZE) + /* We found the "coding:" string, but there is probably not enough + room to store an encoding name in its entirety, so ignore it. + This makes sure we do not end up returning a truncated encoding + name. */ + return NULL; + /* grab the next token */ encoding_start = pos; i = 0; diff --git a/test-suite/tests/coding.test b/test-suite/tests/coding.test index a8a415ff4..b57ef7da7 100644 --- a/test-suite/tests/coding.test +++ b/test-suite/tests/coding.test @@ -1,6 +1,6 @@ ;;;; coding.test --- test suite for coding declarations. -*- mode: scheme -*- ;;;; -;;;; Copyright (C) 2011, 2013 Free Software Foundation, Inc. +;;;; Copyright (C) 2011, 2013, 2014 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 @@ -101,4 +101,10 @@ (pass-if-equal "second line, whitespace, nl" "ISO-8859-1" - (scan-coding "\n; coding: iso-8859-1 \n"))) + (scan-coding "\n; coding: iso-8859-1 \n")) + + (pass-if-equal "http://bugs.gnu.org/16463" + ;; On Guile <= 2.0.9, this would return "ISO-8". + "ISO-8859-1" + (scan-coding (string-append (make-string 485 #\space) + "; coding: ISO-8859-1")))) From d278daca688148f4d1a270e984b054b8ea23cc8a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludovic=20Court=C3=A8s?= Date: Fri, 17 Jan 2014 18:20:09 +0100 Subject: [PATCH 6/7] Thank Sree Harsha. --- THANKS | 1 + 1 file changed, 1 insertion(+) diff --git a/THANKS b/THANKS index 90a4357d1..f16376b59 100644 --- a/THANKS +++ b/THANKS @@ -168,6 +168,7 @@ For fixes or providing information which led to a fix: Rainer Tammer Samuel Thibault Richard Todd + Sree Harsha Totakura Tom Tromey Issac Trotts Greg Troxel From 611563fb05c18ca52f780746e9963ca9735e9bac Mon Sep 17 00:00:00 2001 From: Arne Babenhauserheide Date: Fri, 17 Jan 2014 16:25:16 +0100 Subject: [PATCH 7/7] doc: embedding example more readable. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * doc/ref/guile.texi (A Sample Guile Main Program): Easier to read example code and building split into 2 subsections. Signed-off-by: Ludovic Courtès --- doc/ref/libguile-linking.texi | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/doc/ref/libguile-linking.texi b/doc/ref/libguile-linking.texi index de9076800..433f3b378 100644 --- a/doc/ref/libguile-linking.texi +++ b/doc/ref/libguile-linking.texi @@ -71,24 +71,23 @@ Here is @file{simple-guile.c}, source code for a @code{main} and an interpreter. @example -/* simple-guile.c --- how to start up the Guile - interpreter from C code. */ +/* simple-guile.c --- Start Guile from C. */ -/* Get declarations for all the scm_ functions. */ #include static void inner_main (void *closure, int argc, char **argv) @{ - /* module initializations would go here */ + /* preparation */ scm_shell (argc, argv); + /* after exit */ @} int main (int argc, char **argv) @{ scm_boot_guile (argc, argv, inner_main, 0); - return 0; /* never reached */ + return 0; /* never reached, see inner_main */ @} @end example @@ -97,7 +96,9 @@ Guile, passing it @code{inner_main}. Once @code{scm_boot_guile} is ready, it invokes @code{inner_main}, which calls @code{scm_shell} to process the command-line arguments in the usual way. -Here is a Makefile which you can use to compile the above program. It +@subsection Building the Example with Make + +Here is a Makefile which you can use to compile the example program. It uses @code{pkg-config} to learn about the necessary compiler and linker flags. @example @@ -117,8 +118,10 @@ simple-guile.o: simple-guile.c $@{CC@} -c $@{CFLAGS@} simple-guile.c @end example +@subsection Building the Example with Autoconf + If you are using the GNU Autoconf package to make your application more -portable, Autoconf will settle many of the details in the Makefile above +portable, Autoconf will settle many of the details in the Makefile automatically, making it much simpler and more portable; we recommend using Autoconf with Guile. Here is a @file{configure.ac} file for @code{simple-guile} that uses the standard @code{PKG_CHECK_MODULES}