bug#26058: utf16->string and utf32->string don't conform to R6RS

2017-03-16 Thread Taylan Ulrich Bayırlı/Kammer
Andy Wingo  writes:

> Adopting the behavior is more or less fine.  If it can be done while
> relying on the existing behavior, that is better than something ad-hoc
> in a module.

You mean somehow leveraging the existing BOM handling code of Guile
(found in the ports code) would be preferable to reimplementing it like
in this patch, correct?

In that light, I had this attempt:

(define r6rs-utf16->string
  (case-lambda
((bv default-endianness)
 (let* ((binary-port (open-bytevector-input-port bv))
(transcoder (make-transcoder (utf-16-codec)))
(utf16-port (transcoded-port binary-port transcoder)))
   ;; XXX how to set default-endianness for a port?
   (get-string-all utf16-port)))
((bv endianness endianness-mandatory?)
 (if endianness-mandatory?
 (utf16->string bv endianness)
 (r6rs-utf16->string bv endianness)

As commented in the first branch of the case-lambda, this does not yet
make use of the 'default-endianness' parameter to tell the port
transcoder (or whoever) what to do in case no BOM is found in the
stream.

>From what I can tell, Guile is currently hardcoded to *transparently*
default to big-endian in ports.c, port_clear_stream_start_for_bom_read.

Is there a way to detect when Guile was unable to find a BOM?  (In that
case one could set the endianness explicitly to the desired default.)

Or do you see another way to implement this?

Thanks for the feedback!
Taylan


P.S.: Huge congrats on the big release. :-)





bug#26058: utf16->string and utf32->string don't conform to R6RS

2017-03-14 Thread Taylan Ulrich Bayırlı/Kammer
Andy Wingo  writes:

> On Mon 13 Mar 2017 19:10, taylanbayi...@gmail.com (Taylan Ulrich 
> "Bayırlı/Kammer") writes:
>
>> If I do binary I/O, the following situations are possible:
>>
>> 1. I'm guaranteed to get any possible bytes that happen to form a valid
>>BOM at the start of the stream as-is in the returned bytevector; the
>>binary I/O interface doesn't see such bytes as anything special, as
>>it could simply be coincidence that the stream starts with such
>>bytes.
>
> (1).  But I thought this bug was about using a bytevector as a source
> and then doing textual I/O on it, no?

I have a feeling we're somehow talking past each other. :-) As far as
I'm concerned, the bug is just that the procedures don't conform to the
specification.

It would of course be good if the behavior of these procedures was
somehow in harmony with the behavior of I/O operations, but I don't see
any issues arising from adopting the R6RS behavior of the procedures
utf16->string and utf32->string.  Do you?

Taylan





bug#26058: utf16->string and utf32->string don't conform to R6RS

2017-03-13 Thread Taylan Ulrich Bayırlı/Kammer
Andy Wingo  writes:

> Hi,
>
> this is a tricky area that is not so amenable to quick patches :) Have
> you looked into what Guile already does for byte-order marks?  Can you
> explain how the R6RS specification relates to this?
>
>   https://www.gnu.org/software/guile/manual/html_node/BOM-Handling.html
>
> Andy

Hmm, interesting.  I noticed the utf{16,32}->string procedures ignoring
a BOM at the start of the given bytevector, but didn't look at it from a
ports perspective.

TL;DR of the below though: the R6RS semantics offer a strict enrichment
of the feature-set of the utfX->string procedures relative to the Guile
semantics, so at most we would end up with spurious features.  (The
optional ability to handle any possible BOM at the start of the
bytevector, with a fall-back endianness in case none is found.)


That said, let's see...

If I do a textual read from a port, I already get a string and not a
bytevector, so the behavior of utfX->string operations is irrelevant.

If I do binary I/O, the following situations are possible:

1. I'm guaranteed to get any possible bytes that happen to form a valid
   BOM at the start of the stream as-is in the returned bytevector; the
   binary I/O interface doesn't see such bytes as anything special, as
   it could simply be coincidence that the stream starts with such
   bytes.

2. I'm guaranteed *not* to get bytes that form a BOM at the start of the
   stream; instead they're consumed to set the port encoding for any
   future text I/O.

3. The behavior is unspecified and either of the above may happen.

In the case of #1, it's probably good for utfX->string procedures to be
able to handle BOMs, but also allow explicitly ignoring any possible
BOM.  The R6RS semantics cover this.

In the case of #2, the utfX->string procedures don't need to be able to
handle BOMs as far as we're talking about passing them bytevectors
returned by port I/O, but it also doesn't hurt if they optionally
support it.  The R6RS semantics are fine here as well I think.

As for #3... first of all it's bad IMO; the behavior ought to be
specified. :-) But in any case, the additional features of the R6RS
semantics won't hurt.

WDYT?  As far as I understand the page you linked, Guile currently
implements #3, which I think is unfortunate but can kinda understand
too.  In any case, the additional R6RS features won't hurt, right?

Taylan





bug#26059: Sorry about the duplicate.

2017-03-11 Thread Taylan Ulrich Bayırlı/Kammer
Please ignore this, as it's a duplicate of #26058.





bug#26059: utf16->string and utf32->string don't conform to R6RS

2017-03-11 Thread "Taylan Ulrich Bayırlı/Kammer"
See the R6RS Libraries document page 10.  The differences:

- R6RS supports reading a BOM.

- R6RS mandates an endianness argument to specify the behavior at the
  absence of a BOM.

- R6RS allows an optional third argument 'endianness-mandatory' to
  explicitly ignore any possible BOM.

Here's a quick patch on top of master to implement the R6RS procedures
in terms of the Guile procedures and export them with a rename from
(rnrs bytevectors).


===File
/home/taylan/src/guile/guile-master/0001-Fix-R6RS-utf16-string-and-utf32-string.patch===
>From f51cd1d4884caafb1ed0072cd77c0e3145f34576 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Taylan=20Ulrich=20Bay=C4=B1rl=C4=B1/Kammer?=
 
Date: Fri, 10 Mar 2017 22:36:55 +0100
Subject: [PATCH] Fix R6RS utf16->string and utf32->string.

* module/rnrs/bytevectors.scm (read-bom16, read-bom32): New procedures.
(r6rs-utf16->string, r6rs-utf32->string): Ditto.
---
 module/rnrs/bytevectors.scm | 52 -
 1 file changed, 51 insertions(+), 1 deletion(-)

diff --git a/module/rnrs/bytevectors.scm b/module/rnrs/bytevectors.scm
index 9744359f0..997a8c9cb 100644
--- a/module/rnrs/bytevectors.scm
+++ b/module/rnrs/bytevectors.scm
@@ -69,7 +69,9 @@
bytevector-ieee-double-native-set!
 
string->utf8 string->utf16 string->utf32
-   utf8->string utf16->string utf32->string))
+   utf8->string
+   (r6rs-utf16->string . utf16->string)
+   (r6rs-utf32->string . utf32->string)))
 
 
 (load-extension (string-append "libguile-" (effective-version))
@@ -80,4 +82,52 @@
   `(quote ,sym)
   (error "unsupported endianness" sym)))
 
+(define (read-bom16 bv)
+  (let ((c0 (bytevector-u8-ref bv 0))
+(c1 (bytevector-u8-ref bv 1)))
+(cond
+ ((and (= c0 #xFE) (= c1 #xFF))
+  'big)
+ ((and (= c0 #xFF) (= c1 #xFE))
+  'little)
+ (else
+  #f
+
+(define r6rs-utf16->string
+  (case-lambda
+((bv default-endianness)
+ (let ((bom-endianness (read-bom16 bv)))
+   (if (not bom-endianness)
+   (utf16->string bv default-endianness)
+   (substring/shared (utf16->string bv bom-endianness) 1
+((bv endianness endianness-mandatory?)
+ (if endianness-mandatory?
+ (utf16->string bv endianness)
+ (r6rs-utf16->string bv endianness)
+
+(define (read-bom32 bv)
+  (let ((c0 (bytevector-u8-ref bv 0))
+(c1 (bytevector-u8-ref bv 1))
+(c2 (bytevector-u8-ref bv 2))
+(c3 (bytevector-u8-ref bv 3)))
+(cond
+ ((and (= c0 #x00) (= c1 #x00) (= c2 #xFE) (= c3 #xFF))
+  'big)
+ ((and (= c0 #xFF) (= c1 #xFE) (= c2 #x00) (= c3 #x00))
+  'little)
+ (else
+  #f
+
+(define r6rs-utf32->string
+  (case-lambda
+((bv default-endianness)
+ (let ((bom-endianness (read-bom32 bv)))
+   (if (not bom-endianness)
+   (utf32->string bv default-endianness)
+   (substring/shared (utf32->string bv bom-endianness) 1
+((bv endianness endianness-mandatory?)
+ (if endianness-mandatory?
+ (utf32->string bv endianness)
+ (r6rs-utf32->string bv endianness)
+
 ;;; bytevector.scm ends here
-- 
2.11.0







bug#26058: utf16->string and utf32->string don't conform to R6RS

2017-03-11 Thread "Taylan Ulrich Bayırlı/Kammer"
See the R6RS Libraries document page 10.  The differences:

- R6RS supports reading a BOM.

- R6RS mandates an endianness argument to specify the behavior at the
  absence of a BOM.

- R6RS allows an optional third argument 'endianness-mandatory' to
  explicitly ignore any possible BOM.

Here's a quick patch on top of master.  I didn't test it thoroughly...


===File
/home/taylan/src/guile/guile-master/0001-Fix-R6RS-utf16-string-and-utf32-string.patch===
>From f51cd1d4884caafb1ed0072cd77c0e3145f34576 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Taylan=20Ulrich=20Bay=C4=B1rl=C4=B1/Kammer?=
 
Date: Fri, 10 Mar 2017 22:36:55 +0100
Subject: [PATCH] Fix R6RS utf16->string and utf32->string.

* module/rnrs/bytevectors.scm (read-bom16, read-bom32): New procedures.
(r6rs-utf16->string, r6rs-utf32->string): Ditto.
---
 module/rnrs/bytevectors.scm | 52 -
 1 file changed, 51 insertions(+), 1 deletion(-)

diff --git a/module/rnrs/bytevectors.scm b/module/rnrs/bytevectors.scm
index 9744359f0..997a8c9cb 100644
--- a/module/rnrs/bytevectors.scm
+++ b/module/rnrs/bytevectors.scm
@@ -69,7 +69,9 @@
bytevector-ieee-double-native-set!
 
string->utf8 string->utf16 string->utf32
-   utf8->string utf16->string utf32->string))
+   utf8->string
+   (r6rs-utf16->string . utf16->string)
+   (r6rs-utf32->string . utf32->string)))
 
 
 (load-extension (string-append "libguile-" (effective-version))
@@ -80,4 +82,52 @@
   `(quote ,sym)
   (error "unsupported endianness" sym)))
 
+(define (read-bom16 bv)
+  (let ((c0 (bytevector-u8-ref bv 0))
+(c1 (bytevector-u8-ref bv 1)))
+(cond
+ ((and (= c0 #xFE) (= c1 #xFF))
+  'big)
+ ((and (= c0 #xFF) (= c1 #xFE))
+  'little)
+ (else
+  #f
+
+(define r6rs-utf16->string
+  (case-lambda
+((bv default-endianness)
+ (let ((bom-endianness (read-bom16 bv)))
+   (if (not bom-endianness)
+   (utf16->string bv default-endianness)
+   (substring/shared (utf16->string bv bom-endianness) 1
+((bv endianness endianness-mandatory?)
+ (if endianness-mandatory?
+ (utf16->string bv endianness)
+ (r6rs-utf16->string bv endianness)
+
+(define (read-bom32 bv)
+  (let ((c0 (bytevector-u8-ref bv 0))
+(c1 (bytevector-u8-ref bv 1))
+(c2 (bytevector-u8-ref bv 2))
+(c3 (bytevector-u8-ref bv 3)))
+(cond
+ ((and (= c0 #x00) (= c1 #x00) (= c2 #xFE) (= c3 #xFF))
+  'big)
+ ((and (= c0 #xFF) (= c1 #xFE) (= c2 #x00) (= c3 #x00))
+  'little)
+ (else
+  #f
+
+(define r6rs-utf32->string
+  (case-lambda
+((bv default-endianness)
+ (let ((bom-endianness (read-bom32 bv)))
+   (if (not bom-endianness)
+   (utf32->string bv default-endianness)
+   (substring/shared (utf32->string bv bom-endianness) 1
+((bv endianness endianness-mandatory?)
+ (if endianness-mandatory?
+ (utf32->string bv endianness)
+ (r6rs-utf32->string bv endianness)
+
 ;;; bytevector.scm ends here
-- 
2.11.0







bug#21887: 'monitor' form broken

2016-06-25 Thread Taylan Ulrich Bayırlı/Kammer
Here's a patch, tested minimally by running

(par-for-each (lambda (x)
(monitor
  (sleep 1)
  (display "foo\n")))
  (iota 10))

on a quad-core.  Previously it would print the "foo"s in groups of four
with a second between each group; now it prints them one by one with a
second between each, as should be.

>From 08c7f4cd98c86fbb6551c7c0b6f17262c67e7b23 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Taylan=20Ulrich=20Bay=C4=B1rl=C4=B1/Kammer?=
 
Date: Sat, 25 Jun 2016 16:43:36 +0200
Subject: [PATCH] Fix 'monitor' macro.

* module/ice-9/threads.scm (monitor-mutex-table)
(monitor-mutex-table-mutex, monitor-mutex-with-id): New variables.
(monitor): Fix it.
---
 module/ice-9/threads.scm | 21 ++---
 1 file changed, 18 insertions(+), 3 deletions(-)

diff --git a/module/ice-9/threads.scm b/module/ice-9/threads.scm
index 9f9e1bf..14da113 100644
--- a/module/ice-9/threads.scm
+++ b/module/ice-9/threads.scm
@@ -85,9 +85,24 @@
   (lambda () (begin e0 e1 ...))
   (lambda () (unlock-mutex x)
 
-(define-syntax-rule (monitor first rest ...)
-  (with-mutex (make-mutex)
-first rest ...))
+(define monitor-mutex-table (make-hash-table))
+
+(define monitor-mutex-table-mutex (make-mutex))
+
+(define (monitor-mutex-with-id id)
+  (with-mutex monitor-mutex-table-mutex
+(or (hashq-ref monitor-mutex-table id)
+(let ((mutex (make-mutex)))
+  (hashq-set! monitor-mutex-table id mutex)
+  mutex
+
+(define-syntax monitor
+  (lambda (stx)
+(syntax-case stx ()
+  ((_ body body* ...)
+   (let ((id (datum->syntax #'body (gensym
+ #`(with-mutex (monitor-mutex-with-id '#,id)
+ body body* ...))
 
 (define (par-mapper mapper cons)
   (lambda (proc . lists)
-- 
2.8.4



bug#21613: Include messes up when compiling file in load path

2016-06-21 Thread Taylan Ulrich Bayırlı/Kammer
Ping with CC to Andy. :-)





bug#22447: (rnrs hashtables): Mutation of immutable hashtable ignored

2016-06-20 Thread Taylan Ulrich Bayırlı/Kammer
Pinging this thread with a (very slightly) updated patch. :-)

>From 7f35d515d711e255bba5a89a013d9d92034edf41 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Taylan=20Ulrich=20Bay=C4=B1rl=C4=B1/Kammer?=
 
Date: Tue, 21 Jun 2016 00:25:19 +0200
Subject: [PATCH] Hashtable-set! errors on immutable hashtable.

* module/rnrs/hashtables.scm (hashtable-set!): Raise an assertion
  violation error when the hashtable is immutable.
* test-suite/tests/r6rs-hashtables.test: Fix accordingly.
---
 module/rnrs/hashtables.scm| 5 +++--
 test-suite/tests/r6rs-hashtables.test | 6 --
 2 files changed, 7 insertions(+), 4 deletions(-)

diff --git a/module/rnrs/hashtables.scm b/module/rnrs/hashtables.scm
index 08f37e2..22bae7f 100644
--- a/module/rnrs/hashtables.scm
+++ b/module/rnrs/hashtables.scm
@@ -127,8 +127,9 @@
 
   (define (hashtable-set! hashtable key obj)
 (if (r6rs:hashtable-mutable? hashtable)
-	(hash-table-set! (r6rs:hashtable-wrapped-table hashtable) key obj))
-*unspecified*)
+(hash-table-set! (r6rs:hashtable-wrapped-table hashtable) key obj)
+(assertion-violation
+ 'hashtable-set! "Hashtable is immutable." hashtable)))
 
   (define (hashtable-delete! hashtable key)
 (if (r6rs:hashtable-mutable? hashtable)
diff --git a/test-suite/tests/r6rs-hashtables.test b/test-suite/tests/r6rs-hashtables.test
index fbc50c9..e2cbc2a 100644
--- a/test-suite/tests/r6rs-hashtables.test
+++ b/test-suite/tests/r6rs-hashtables.test
@@ -20,6 +20,7 @@
 (define-module (test-suite test-rnrs-hashtable)
   :use-module (ice-9 receive)
   :use-module ((rnrs hashtables) :version (6))
+  :use-module ((rnrs exceptions) :version (6))
   :use-module (srfi srfi-1)
   :use-module (test-suite lib))
 
@@ -130,8 +131,9 @@
 
   (pass-if "hashtable-copy with mutability #f produces immutable copy"
 (let ((copied-table (hashtable-copy (make-eq-hashtable) #f)))
-  (hashtable-set! copied-table 'foo 1)
-  (not (hashtable-ref copied-table 'foo #f)  
+  (guard (exc (else #t))
+(hashtable-set! copied-table 'foo 1)
+#f
 
 (with-test-prefix "hashtable-clear!"
   (pass-if "hashtable-clear! removes all values from hashtable"
-- 
2.8.4



bug#22446: (rnrs hashtables): Hash functions of eq? and eqv? hashtables

2016-06-20 Thread Taylan Ulrich Bayırlı/Kammer
Also pinging this thread with a (very slightly) updated patch. :-)

>From 17599f6ce7ba0beb100e80455ff99af07333d871 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Taylan=20Ulrich=20Bay=C4=B1rl=C4=B1/Kammer?=
 
Date: Tue, 21 Jun 2016 00:23:29 +0200
Subject: [PATCH] Hashtable-hash-function returns #f on eq and eqv tables.

* module/rnrs/hashtables.scm (r6rs:hashtable)[type]: New field.
(r6rs:hashtable-type): New procedure.
* test-suite/tests/r6rs-hashtables.test: Add related tests.
---
 module/rnrs/hashtables.scm| 22 +++---
 test-suite/tests/r6rs-hashtables.test |  6 +-
 2 files changed, 20 insertions(+), 8 deletions(-)

diff --git a/module/rnrs/hashtables.scm b/module/rnrs/hashtables.scm
index 98d2d76..08f37e2 100644
--- a/module/rnrs/hashtables.scm
+++ b/module/rnrs/hashtables.scm
@@ -74,8 +74,9 @@
 (make-record-type-descriptor 
  'r6rs:hashtable #f #f #t #t 
  '#((mutable wrapped-table)
-	(immutable orig-hash-function)
-	(immutable mutable
+(immutable orig-hash-function)
+(immutable mutable)
+(immutable type
 
   (define hashtable? (record-predicate r6rs:hashtable))
   (define make-r6rs-hashtable 
@@ -85,6 +86,7 @@
   (define r6rs:hashtable-set-wrapped-table! (record-mutator r6rs:hashtable 0))
   (define r6rs:hashtable-orig-hash-function (record-accessor r6rs:hashtable 1))
   (define r6rs:hashtable-mutable? (record-accessor r6rs:hashtable 2))
+  (define r6rs:hashtable-type (record-accessor r6rs:hashtable 3))
 
   (define hashtable-mutable? r6rs:hashtable-mutable?)
 
@@ -96,13 +98,15 @@
 (make-r6rs-hashtable 
  (if k (make-hash-table eq? hashq k) (make-hash-table eq? symbol-hash))
  symbol-hash
- #t))
+ #t
+ 'eq))
 
   (define* (make-eqv-hashtable #:optional k)
 (make-r6rs-hashtable 
  (if k (make-hash-table eqv? hashv k) (make-hash-table eqv? hash-by-value))
  hash-by-value
- #t))
+ #t
+ 'eqv))
 
   (define* (make-hashtable hash-function equiv #:optional k)
 (let ((wrapped-hash-function (wrap-hash-function hash-function)))
@@ -111,7 +115,8 @@
 	   (make-hash-table equiv wrapped-hash-function k)
 	   (make-hash-table equiv wrapped-hash-function))
hash-function
-   #t)))
+   #t
+   'custom)))
  
   (define (hashtable-size hashtable)
 (hash-table-size (r6rs:hashtable-wrapped-table hashtable)))
@@ -143,7 +148,8 @@
 (make-r6rs-hashtable 
  (hash-table-copy (r6rs:hashtable-wrapped-table hashtable))
  (r6rs:hashtable-orig-hash-function hashtable)
- (and mutable #t)))
+ (and mutable #t)
+ (r6rs:hashtable-type hashtable)))
 
   (define* (hashtable-clear! hashtable #:optional k)
 (if (r6rs:hashtable-mutable? hashtable)
@@ -178,4 +184,6 @@
 (hash-table-equivalence-function (r6rs:hashtable-wrapped-table hashtable)))
 
   (define (hashtable-hash-function hashtable)
-(r6rs:hashtable-orig-hash-function hashtable)))
+(case (r6rs:hashtable-type hashtable)
+  ((eq eqv) #f)
+  (else (r6rs:hashtable-orig-hash-function hashtable)
diff --git a/test-suite/tests/r6rs-hashtables.test b/test-suite/tests/r6rs-hashtables.test
index c7812c5..fbc50c9 100644
--- a/test-suite/tests/r6rs-hashtables.test
+++ b/test-suite/tests/r6rs-hashtables.test
@@ -174,7 +174,11 @@
 (with-test-prefix "hashtable-hash-function"
   (pass-if "hashtable-hash-function returns hash function"
 (let ((abs-hashtable (make-hashtable abs eqv?)))
-  (eq? (hashtable-hash-function abs-hashtable) abs
+  (eq? (hashtable-hash-function abs-hashtable) abs)))
+  (pass-if "hashtable-hash-function returns #f on eq table"
+(eq? #f (hashtable-hash-function (make-eq-hashtable
+  (pass-if "hashtable-hash-function returns #f on eqv table"
+(eq? #f (hashtable-hash-function (make-eqv-hashtable)
 
 (with-test-prefix "hashtable-mutable?"
   (pass-if "hashtable-mutable? is #t on mutable hashtables"
-- 
2.8.4



bug#22446: (rnrs hashtables): Hash functions of eq? and eqv? hashtables

2016-01-24 Thread Taylan Ulrich Bayırlı/Kammer
Here's a patch to fix this.

>From a3e5a705aaea725fd75280a27b971d8e45e3 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Taylan=20Ulrich=20Bay=C4=B1rl=C4=B1/Kammer?=
 
Date: Sun, 24 Jan 2016 12:23:34 +0100
Subject: [PATCH] Hashtable-hash-function returns #f on eq and eqv tables.

* module/rnrs/hashtables.scm (r6rs:hashtable)[type]: New field.
(r6rs:hashtable-type): New procedure.
---
 module/rnrs/hashtables.scm| 22 +++---
 test-suite/tests/r6rs-hashtables.test |  6 +-
 2 files changed, 20 insertions(+), 8 deletions(-)

diff --git a/module/rnrs/hashtables.scm b/module/rnrs/hashtables.scm
index 5773eb1..22bae7f 100644
--- a/module/rnrs/hashtables.scm
+++ b/module/rnrs/hashtables.scm
@@ -74,8 +74,9 @@
 (make-record-type-descriptor 
  'r6rs:hashtable #f #f #t #t 
  '#((mutable wrapped-table)
-	(immutable orig-hash-function)
-	(immutable mutable
+(immutable orig-hash-function)
+(immutable mutable)
+(immutable type
 
   (define hashtable? (record-predicate r6rs:hashtable))
   (define make-r6rs-hashtable 
@@ -85,6 +86,7 @@
   (define r6rs:hashtable-set-wrapped-table! (record-mutator r6rs:hashtable 0))
   (define r6rs:hashtable-orig-hash-function (record-accessor r6rs:hashtable 1))
   (define r6rs:hashtable-mutable? (record-accessor r6rs:hashtable 2))
+  (define r6rs:hashtable-type (record-accessor r6rs:hashtable 3))
 
   (define hashtable-mutable? r6rs:hashtable-mutable?)
 
@@ -96,13 +98,15 @@
 (make-r6rs-hashtable 
  (if k (make-hash-table eq? hashq k) (make-hash-table eq? symbol-hash))
  symbol-hash
- #t))
+ #t
+ 'eq))
 
   (define* (make-eqv-hashtable #:optional k)
 (make-r6rs-hashtable 
  (if k (make-hash-table eqv? hashv k) (make-hash-table eqv? hash-by-value))
  hash-by-value
- #t))
+ #t
+ 'eqv))
 
   (define* (make-hashtable hash-function equiv #:optional k)
 (let ((wrapped-hash-function (wrap-hash-function hash-function)))
@@ -111,7 +115,8 @@
 	   (make-hash-table equiv wrapped-hash-function k)
 	   (make-hash-table equiv wrapped-hash-function))
hash-function
-   #t)))
+   #t
+   'custom)))
  
   (define (hashtable-size hashtable)
 (hash-table-size (r6rs:hashtable-wrapped-table hashtable)))
@@ -144,7 +149,8 @@
 (make-r6rs-hashtable 
  (hash-table-copy (r6rs:hashtable-wrapped-table hashtable))
  (r6rs:hashtable-orig-hash-function hashtable)
- (and mutable #t)))
+ (and mutable #t)
+ (r6rs:hashtable-type hashtable)))
 
   (define* (hashtable-clear! hashtable #:optional k)
 (if (r6rs:hashtable-mutable? hashtable)
@@ -179,4 +185,6 @@
 (hash-table-equivalence-function (r6rs:hashtable-wrapped-table hashtable)))
 
   (define (hashtable-hash-function hashtable)
-(r6rs:hashtable-orig-hash-function hashtable)))
+(case (r6rs:hashtable-type hashtable)
+  ((eq eqv) #f)
+  (else (r6rs:hashtable-orig-hash-function hashtable)
diff --git a/test-suite/tests/r6rs-hashtables.test b/test-suite/tests/r6rs-hashtables.test
index dbf6859..5c48579 100644
--- a/test-suite/tests/r6rs-hashtables.test
+++ b/test-suite/tests/r6rs-hashtables.test
@@ -176,7 +176,11 @@
 (with-test-prefix "hashtable-hash-function"
   (pass-if "hashtable-hash-function returns hash function"
 (let ((abs-hashtable (make-hashtable abs eqv?)))
-  (eq? (hashtable-hash-function abs-hashtable) abs
+  (eq? (hashtable-hash-function abs-hashtable) abs)))
+  (pass-if "hashtable-hash-function returns #f on eq table"
+(eq? #f (hashtable-hash-function (make-eq-hashtable
+  (pass-if "hashtable-hash-function returns hash function"
+(eq? #f (hashtable-hash-function (make-eqv-hashtable)
 
 (with-test-prefix "hashtable-mutable?"
   (pass-if "hashtable-mutable? is #t on mutable hashtables"
-- 
2.6.3



bug#22447: (rnrs hashtables): Mutation of immutable hashtable ignored

2016-01-24 Thread Taylan Ulrich Bayırlı/Kammer
I forgot to change the test suite accordingly.  Here's an updated patch.

>From 7483d98cf1e5439ac62ee8da3e216a413853b40c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Taylan=20Ulrich=20Bay=C4=B1rl=C4=B1/Kammer?=
 
Date: Sat, 23 Jan 2016 22:35:24 +0100
Subject: [PATCH 1/2] Hashtable-set! errors on immutable hashtable.

* module/rnrs/hashtables.scm (hashtable-set!): Raise an assertion
  violation error when the hashtable is immutable.
---
 module/rnrs/hashtables.scm| 5 +++--
 test-suite/tests/r6rs-hashtables.test | 6 --
 2 files changed, 7 insertions(+), 4 deletions(-)

diff --git a/module/rnrs/hashtables.scm b/module/rnrs/hashtables.scm
index 98d2d76..5773eb1 100644
--- a/module/rnrs/hashtables.scm
+++ b/module/rnrs/hashtables.scm
@@ -122,8 +122,9 @@
 
   (define (hashtable-set! hashtable key obj)
 (if (r6rs:hashtable-mutable? hashtable)
-	(hash-table-set! (r6rs:hashtable-wrapped-table hashtable) key obj))
-*unspecified*)
+(hash-table-set! (r6rs:hashtable-wrapped-table hashtable) key obj)
+(assertion-violation
+ 'hashtable-set! "Hashtable is immutable." hashtable)))
 
   (define (hashtable-delete! hashtable key)
 (if (r6rs:hashtable-mutable? hashtable)
diff --git a/test-suite/tests/r6rs-hashtables.test b/test-suite/tests/r6rs-hashtables.test
index c7812c5..dbf6859 100644
--- a/test-suite/tests/r6rs-hashtables.test
+++ b/test-suite/tests/r6rs-hashtables.test
@@ -20,6 +20,7 @@
 (define-module (test-suite test-rnrs-hashtable)
   :use-module (ice-9 receive)
   :use-module ((rnrs hashtables) :version (6))
+  :use-module ((rnrs exceptions) :version (6))
   :use-module (srfi srfi-1)
   :use-module (test-suite lib))
 
@@ -130,8 +131,9 @@
 
   (pass-if "hashtable-copy with mutability #f produces immutable copy"
 (let ((copied-table (hashtable-copy (make-eq-hashtable) #f)))
-  (hashtable-set! copied-table 'foo 1)
-  (not (hashtable-ref copied-table 'foo #f)  
+  (guard (exc (else #t))
+(hashtable-set! copied-table 'foo 1)
+#f
 
 (with-test-prefix "hashtable-clear!"
   (pass-if "hashtable-clear! removes all values from hashtable"
-- 
2.6.3



bug#22447: (rnrs hashtables): Mutation of immutable hashtable ignored

2016-01-23 Thread Taylan Ulrich Bayırlı/Kammer
Sorry about the duplicate bug report; I merged it into this one.

Here's the patch again.  (Merged report seemed invisible in the web
interface.)

>From dd6c4bbbe85a57fcbb08bdc7847075bddc1f0d87 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Taylan=20Ulrich=20Bay=C4=B1rl=C4=B1/Kammer?=
 
Date: Sat, 23 Jan 2016 22:35:24 +0100
Subject: [PATCH] Hashtable-set! errors on immutable hashtable.

* module/rnrs/hashtables.scm (hashtable-set!): Raise an assertion
  violation error when the hashtable is immutable.
---
 module/rnrs/hashtables.scm | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/module/rnrs/hashtables.scm b/module/rnrs/hashtables.scm
index 98d2d76..5773eb1 100644
--- a/module/rnrs/hashtables.scm
+++ b/module/rnrs/hashtables.scm
@@ -122,8 +122,9 @@
 
   (define (hashtable-set! hashtable key obj)
 (if (r6rs:hashtable-mutable? hashtable)
-	(hash-table-set! (r6rs:hashtable-wrapped-table hashtable) key obj))
-*unspecified*)
+(hash-table-set! (r6rs:hashtable-wrapped-table hashtable) key obj)
+(assertion-violation
+ 'hashtable-set! "Hashtable is immutable." hashtable)))
 
   (define (hashtable-delete! hashtable key)
 (if (r6rs:hashtable-mutable? hashtable)
-- 
2.6.3



bug#22449: (rnrs hashtables): Mutation of immutable hashtable ignored

2016-01-23 Thread "Taylan Ulrich Bayırlı/Kammer"
I couldn't find explicit wording in R6RS on what should happen, but I
would generally expect an attempt to mutate an immutable object to
raise an error.  In Guile,

(hashtable-set! (hashtable-copy (make-eq-hashtable)) 'foo 'bar)

is silently ignored.

Attached is a simple patch that raises an assertion violation when the
hashtable is immutable.

Taylan

===File
/home/taylan/src/guile/guile-stable-2.0/0001-Hashtable-set-errors-on-immutable-hashtable.patch===
>From dd6c4bbbe85a57fcbb08bdc7847075bddc1f0d87 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Taylan=20Ulrich=20Bay=C4=B1rl=C4=B1/Kammer?=
 
Date: Sat, 23 Jan 2016 22:35:24 +0100
Subject: [PATCH] Hashtable-set! errors on immutable hashtable.

* module/rnrs/hashtables.scm (hashtable-set!): Raise an assertion
  violation error when the hashtable is immutable.
---
 module/rnrs/hashtables.scm | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/module/rnrs/hashtables.scm b/module/rnrs/hashtables.scm
index 98d2d76..5773eb1 100644
--- a/module/rnrs/hashtables.scm
+++ b/module/rnrs/hashtables.scm
@@ -122,8 +122,9 @@
 
   (define (hashtable-set! hashtable key obj)
 (if (r6rs:hashtable-mutable? hashtable)
-   (hash-table-set! (r6rs:hashtable-wrapped-table hashtable) key obj))
-*unspecified*)
+(hash-table-set! (r6rs:hashtable-wrapped-table hashtable) key obj)
+(assertion-violation
+ 'hashtable-set! "Hashtable is immutable." hashtable)))
 
   (define (hashtable-delete! hashtable key)
 (if (r6rs:hashtable-mutable? hashtable)
-- 
2.6.3







bug#22447: (rnrs hashtables): Mutation of immutable hashtable ignored

2016-01-23 Thread "Taylan Ulrich Bayırlı/Kammer"
I couldn't find explicit wording in R6RS on what should happen, but I
would generally expect an attempt to mutate an immutable object to
raise an error.  In Guile,

(hashtable-set! (hashtable-copy (make-eq-hashtable)) 'foo 'bar)

is silently ignored.

Taylan





bug#22446: (rnrs hashtables): Hash functions of eq? and eqv? hashtables

2016-01-23 Thread "Taylan Ulrich Bayırlı/Kammer"
Per R6RS, the following forms should return #f:

(hashtable-hash-function (make-eq-hashtable))

(hashtable-hash-function (make-eqv-hashtable))

but in Guile they return procedures.

Taylan





bug#21887: 'monitor' form broken

2015-11-12 Thread Taylan Ulrich Bayırlı/Kammer
It seems that the 'monitor' form is currently a no-op.  The form

(par-for-each (lambda (x)
(monitor
  (foo)))
  xs)

should be functionally equivalent to

(let ((mutex (make-mutex)))
  (par-for-each (lambda (x)
  (with-mutex mutex
(foo)))
xs))

but currently becomes

(par-for-each (lambda (x)
(let ((mutex (make-mutex)))
  (with-mutex mutex
(foo
  xs)

which is ineffective.

I don't know what's the best way to fix this.  The simplest thing that
comes to my mind is something along the lines of:

(define-syntax monitor
  (lambda (stx)
(syntax-case stx ()
  ((_ body body* ...)
   (let ((uuid (generate-uuid)))
 #`(with-mutex (mutex-with-uuid #,uuid)
 body body* ...))

where mutex-with-uuid looks it up from a hash table at run-time and
instantiates it when it doesn't exist, this operation also being
synchronized across threads, like:

(define mutex-table (make-hash-table))

(define mutex-table-mutex (make-mutex))

(define (mutex-with-uuid uuid)
  (with-mutex mutex-table-mutex
(or (hash-ref mutex-table uuid)
(let ((mutex (make-mutex)))
  (hash-set! mutex-table uuid mutex)
  mutex

If that looks OK, I can try to make a proper patch from it.  I'm not
sure what I'd use in place of `generate-uuid' though.  Would `gensym' be
good enough?


Shameless advertisement: with SRFI-126, the (or (hash-ref ...) ...) bit
would have been just:

(hashtable-intern! mutex-table uuid make-mutex)

It's borrowed from MIT/GNU Scheme.  Seems pretty useful.

Taylan





bug#15602: Possible work-around

2015-11-06 Thread Taylan Ulrich Bayırlı/Kammer
A possible work-around seems to be to use 'load' or 'load-compiled' on a
module file after compiling it.

As far as I understand, the problem is that Guile somehow ends up with a
"degenerate" version of the module in the run-time after it's compiled
but not fully loaded, so we alleviate that by explicitly loading it.  I
know near to nothing about the deeper mechanisms at play here though, so
I might be off.  In any case, changing

  guile --no-auto-compile -L . -c \
'(use-modules (system base compile))
 (for-each compile-file (list "one.scm" "three.scm" "two.scm"))'

to

  guile --no-auto-compile -L . -c \
'(use-modules (system base compile))
 (for-each (lambda (file)
 (compile-file file)
 (load file))
   (list "one.scm" "three.scm" "two.scm"))'

alleviates the unbound variable error in this case.

Related thread:
https://lists.gnu.org/archive/html/guix-devel/2015-11/msg00143.html

Taylan





bug#21613: Include messes up when compiling file in load path

2015-10-04 Thread Taylan Ulrich Bayırlı/Kammer
taylanbayi...@gmail.com (Taylan Ulrich "Bayırlı/Kammer") writes:

> This seems to be related to 'compile-file' setting
> '%file-port-name-canonicalization' to 'relative', but I don't know
> what the correct fix is.

With the following trivial patch changing 'relative' to 'absolute',
Guile's test suite passes and the bug seems to be fixed, but I still
don't know whether this is the right fix...

>From 3e508926631a6fe3d81f6a584352562afc0e96ee Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Taylan=20Ulrich=20Bay=C4=B1rl=C4=B1/Kammer?=
 
Date: Mon, 5 Oct 2015 00:15:56 +0200
Subject: [PATCH] Fix 'include' for files in load path.

Fixes <http://debbugs.gnu.org/21613>.

* module/system/base/compile.scm (compile-file): Set
  %file-port-name-canonicalization to 'absolute by default.
(compile-and-load): Ditto.
---
 module/system/base/compile.scm | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/module/system/base/compile.scm b/module/system/base/compile.scm
index c522b74..66eec44 100644
--- a/module/system/base/compile.scm
+++ b/module/system/base/compile.scm
@@ -136,7 +136,7 @@
(to 'objcode)
(env (default-environment from))
(opts '())
-   (canonicalization 'relative))
+   (canonicalization 'absolute))
   (with-fluids ((%file-port-name-canonicalization canonicalization))
 (let* ((comp (or output-file (compiled-file-name file)
  (error "failed to create path for auto-compiled file"
@@ -157,7 +157,7 @@
 
 (define* (compile-and-load file #:key (from (current-language)) (to 'value)
(env (current-module)) (opts '())
-   (canonicalization 'relative))
+   (canonicalization 'absolute))
   (with-fluids ((%file-port-name-canonicalization canonicalization))
 (read-and-compile (open-input-file file)
   #:from from #:to to #:opts opts
-- 
2.5.0



bug#21613: Include messes up when compiling file in load path

2015-10-04 Thread Taylan Ulrich Bayırlı/Kammer
When a file to be compiled, A.scm, contains (include "B.scm"), the
compiler fails to find B.scm if the directory containing A and B are in
Guile's load path.

Here's a shell transcript showcasing the bug:

--- snip ---
$ mkdir test
$ echo '(include "test2.scm")' > test/test1.scm
$ echo '(display "foo\n")' > test/test2.scm
$ pwd
/home/taylan
$ export GUILE_LOAD_PATH=/home/taylan/test
$ unset GUILE_LOAD_COMPILED_PATH
$ guile -q
GNU Guile 2.0.11
Copyright (C) 1995-2014 Free Software Foundation, Inc.

Guile comes with ABSOLUTELY NO WARRANTY; for details type `,show w'.
This program is free software, and you are welcome to redistribute it
under certain conditions; type `,show c' for details.

Enter `,help' for help.
scheme@(guile-user)> (compile-file "/home/taylan/test/test1.scm")
ice-9/boot-9.scm:106:20: In procedure #:
ice-9/boot-9.scm:106:20: In procedure open-file: No such file or directory: 
"./test2.scm"

Entering a new prompt.  Type `,bt' for a backtrace or `,q' to continue.
scheme@(#{ g269}#) [1]>
--- snip ---

This seems to be related to 'compile-file' setting
'%file-port-name-canonicalization' to 'relative', but I don't know what
the correct fix is.

Taylan





bug#21379: datum->syntax chokes on lists of syntax objects

2015-09-02 Thread Taylan Ulrich Bayırlı/Kammer
Mark H Weaver  writes:

> How about changing the first formal argument name to 'template-id' and
> changing the words "syntax object" to "identifier"?
>
>  Thanks!
>Mark

Sure, updated patch attached.

Taylan

>From 2ba9474dc8e2a56524d8c6c2f640fb3fb35b2d14 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Taylan=20Ulrich=20Bay=C4=B1rl=C4=B1/Kammer?=
 
Date: Sun, 30 Aug 2015 10:24:52 +0200
Subject: [PATCH] Amend datum->syntax documentation.

* doc/ref/api-macros.texi (Syntax Case): Make it clear that the first
  argument to datum->syntax must be an identifier.
---
 doc/ref/api-macros.texi | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/doc/ref/api-macros.texi b/doc/ref/api-macros.texi
index c2910a4..a828258 100644
--- a/doc/ref/api-macros.texi
+++ b/doc/ref/api-macros.texi
@@ -616,9 +616,9 @@ won't have access to the binding of @code{it}.
 
 But they can, if we explicitly introduce a binding via @code{datum->syntax}.
 
-@deffn {Scheme Procedure} datum->syntax for-syntax datum
+@deffn {Scheme Procedure} datum->syntax template-id datum
 Create a syntax object that wraps @var{datum}, within the lexical context
-corresponding to the syntax object @var{for-syntax}.
+corresponding to the identifier @var{template-id}.
 @end deffn
 
 For completeness, we should mention that it is possible to strip the metadata
-- 
2.5.0



bug#21378: R6RS guard's else chokes on multiple expressions

2015-08-30 Thread Taylan Ulrich Bayırlı/Kammer
Please ignore this bug report, since it was my fault.  I had a foreign
(rnrs exceptions) library in my load-path that took precedence.

Sorry about the noise.

Taylan





bug#21379: datum->syntax chokes on lists of syntax objects

2015-08-30 Thread Taylan Ulrich Bayırlı/Kammer
Apparently there's two ways to represent a list syntax object:

(datum->syntax #'x '(a b c))
=> #(syntax-object (a b c) ((top)) (hygiene guile-user))

i.e. a syntax object vector with a list payload, and

#'(a b c)
=> (#(syntax-object a ((top)) (hygiene guile-user))
#(syntax-object b ((top)) (hygiene guile-user))
#(syntax-object c ((top)) (hygiene guile-user)))

i.e. a list of the elements as syntax objects.

Syntax-case and syntax->datum work fine with both.  But when the latter
form is used as the first argument to a datum->syntax call, it leads to
an error:

--- snip
scheme@(guile-user)> (datum->syntax #'(x) '(a b c))
ice-9/psyntax.scm:467:4: In procedure datum->syntax:
ice-9/psyntax.scm:467:4: In procedure vector-ref: Wrong type argument in 
position 1 (expecting vector): (#(syntax-object x ((top)) (hygiene guile-user)))

Entering a new prompt.  Type `,bt' for a backtrace or `,q' to continue.
scheme@(guile-user) [1]>
--- snip

I think I understand the problem: in case of a list of syntax objects,
it's ambiguous which one's environment should be used for the newly
created syntax object, so it requires it to be an "immediately wrapped"
syntax object instead.  (By the way, the psyntax sources actually call
that argument 'id', hinting that perhaps it's expected to be an
identifier, though the other representation works fine.)

I have no clue what's the best way to solve this, but if my
understanding is correct, it's a fundamental issue with datum->syntax
and not a bug, so here's a documentation patch that tries to explain the
limitation.

>From 9578ee36ef005f0b96c1d5b120f11c178e341775 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Taylan=20Ulrich=20Bay=C4=B1rl=C4=B1/Kammer?=
 
Date: Sun, 30 Aug 2015 10:24:52 +0200
Subject: [PATCH] Amend datum->syntax documentation.

* doc/ref/api-macros.texi (Syntax Case): Mention that the first argument
  to datum->syntax is invalid if it's a compound syntax object, except
  when also created with datum->syntax.
---
 doc/ref/api-macros.texi | 7 ++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/doc/ref/api-macros.texi b/doc/ref/api-macros.texi
index c2910a4..9c1f023 100644
--- a/doc/ref/api-macros.texi
+++ b/doc/ref/api-macros.texi
@@ -618,7 +618,12 @@ But they can, if we explicitly introduce a binding via @code{datum->syntax}.
 
 @deffn {Scheme Procedure} datum->syntax for-syntax datum
 Create a syntax object that wraps @var{datum}, within the lexical context
-corresponding to the syntax object @var{for-syntax}.
+corresponding to the syntax object @var{for-syntax}.  @var{for-syntax} must
+either be an identifier, or a syntax object that was also created with
+@var{datum->syntax}; other compound syntax objects may be rejected because they
+contain identifiers from different lexical contexts, in which case it would be
+ambiguous which one's environment should be used for the newly created syntax
+object.
 @end deffn
 
 For completeness, we should mention that it is possible to strip the metadata
-- 
2.5.0



bug#21378: R6RS guard's else chokes on multiple expressions

2015-08-29 Thread Taylan Ulrich Bayırlı/Kammer
It seems that whatever macro tries to match the guard expression's
else-clause, fails to do so when the clause contains more than one
expression, and so adds a default "else re-raise" clause after the
existing else clause.

I couldn't figure out where this happens.  I grepped the whole
source tree for 're-raise' and only found it twice in a comment.

Transcript showcasing bug:

taylan@T420:~$ guile
GNU Guile 2.0.11
Copyright (C) 1995-2014 Free Software Foundation, Inc.

Guile comes with ABSOLUTELY NO WARRANTY; for details type `,show w'.
This program is free software, and you are welcome to redistribute it
under certain conditions; type `,show c' for details.

Enter `,help' for help.
scheme@(guile-user)> ,use (rnrs exceptions)
scheme@(guile-user)> (guard (exc (else #f #f)) #f)
While compiling expression:
ERROR: Syntax error:
unknown file:3:12: cond: else must be the last clause in subform (else #f #f) 
of (cond (else #f #f) (else (re-raise)))
scheme@(guile-user)>

Taylan





bug#21347: include-from-path and relative paths in load-path

2015-08-25 Thread Taylan Ulrich Bayırlı/Kammer
When there are relative paths in the load-path, `include-from-path'
seems to always interpret them relative to the directory of the file in
which the `include-from-path' is called, instead of relative to the
current working directory in effect when Guile is started.

Transcript:

--- SNIP ---
taylan@T420:~$ unset GUILE_LOAD_COMPILED_PATH
taylan@T420:~$ unset GUILE_LOAD_PATH
taylan@T420:~$ echo '(display "foo\n")' > display.scm
taylan@T420:~$ mkdir test
taylan@T420:~$ echo '(include-from-path "display.scm")' > test/test.scm
taylan@T420:~$ guile -q -L .
GNU Guile 2.0.11
Copyright (C) 1995-2014 Free Software Foundation, Inc.

Guile comes with ABSOLUTELY NO WARRANTY; for details type `,show w'.
This program is free software, and you are welcome to redistribute it
under certain conditions; type `,show c' for details.

Enter `,help' for help.
scheme@(guile-user)> (load "test/test.scm")
;;; note: auto-compilation is enabled, set GUILE_AUTO_COMPILE=0
;;;   or pass the --no-auto-compile argument to disable.
;;; compiling /home/taylan/test/test.scm
;;; WARNING: compilation of /home/taylan/test/test.scm failed:
;;; ERROR: In procedure open-file: No such file or directory: 
"/home/taylan/test/./display.scm"
ERROR: In procedure open-file:
ERROR: In procedure open-file: No such file or directory: 
"/home/taylan/test/./display.scm"

Entering a new prompt.  Type `,bt' for a backtrace or `,q' to continue.
scheme@(guile-user) [1]>
--- SNIP ---

Is this behavior desired?  I would say not, because when passing "-L ."
to guile, one expects the current directory to be added to the load
path, not some symbolic "current directory" whose true value changes
dynamically.  (Well, I could understand if there were an explicit
`chdir' call, though even then I think the "."  would ideally be
evaluated once at startup, if possible.)

Taylan





bug#18932: string->number errors on e.g. "1e400xyz"

2014-11-03 Thread &quot;Taylan Ulrich Bayırlı/Kammer"
When string->number is given a number in scientific notation with a
very high exponent, it errors with "value out of range."

I don't know if that is acceptable, but what seems unacceptable is
that it errors even if the string contains further characters and is
thus not a valid number; R5RS says that #f should be returned when the
string does not contain a syntactically valid number, and R7RS adds
explicitly that string->number never signals an error due to the
contents of the given string.

Apparently MIT/GNU Scheme has the same bug, as reported by 'ecraven'
on #scheme.  From other systems I tested, Racket, Gauche, Gambit, and
Chibi return +inf.0 for numbers with a too high exponent; I'm told
Chicken also does so when the "numbers egg" is loaded.

Taylan





bug#18914: 2.0.11 REPL server listens on 127.0.0.1 but not "localhost"

2014-11-02 Thread Taylan Ulrich Bayırlı/Kammer
 writes:

> Seems to work fine on master

I just built from the master branch to be sure and can still reproduce.

> Maybe try strace, possibly limiting it with -e connect, to reveal what
> it's actually doing.

Not sure what I should be looking for, but there is no connect() call,
no occurrence of "localhost" in the whole output, but the following
snippet at some point:

...
socket(PF_INET, SOCK_STREAM, IPPROTO_IP) = 8
fcntl(8, F_GETFL)   = 0x2 (flags O_RDWR)
lseek(8, 0, SEEK_CUR)   = -1 ESPIPE (Illegal seek)
setsockopt(8, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
bind(8, {sa_family=AF_INET, sin_port=htons(37146), 
sin_addr=inet_addr("127.0.0.1")}, 16) = 0
mmap(NULL, 8720384, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_STACK, 
-1, 0) = 0x7f35aaf81000
mprotect(0x7f35aaf81000, 4096, PROT_NONE) = 0
clone(child_stack=0x7f35ab7d0ff0, 
flags=CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_THREAD|CLONE_SYSVSEM|CLONE_SETTLS|CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID,
 parent_tidptr=0x7f35ab7d19d0, tls=0x7f35ab7d1700, child_tidptr=0x7f35ab7d19d0) 
= 2099
futex(0x7fffd27a33fc, FUTEX_WAIT_PRIVATE, 1, NULL) = 0
...

which is also the sole occurrence of '127.0.0.1'.  Seems to come from
`make-tcp-server-socket' in module/system/repl/server.scm where it
passes INADDR_LOOPBACK, an integer whose value is 127.0.0.1 as a uint32,
to bind().  I don't know at what point it's normally supposed to make
the association with "localhost".

Any further help in how to debug this is appreciated.  I have little
knowledge of the POSIX networking API.

Taylan





bug#18914: 2.0.11 REPL server listens on 127.0.0.1 but not "localhost"

2014-10-31 Thread Taylan Ulrich Bayırlı/Kammer
 writes:

> I wonder, could localhost be resolving to your ethernet IP address?
> Or maybe resolving to an IPv6 address?

tub@taylan:~$ nslookup localhost
Server: 127.0.0.1
Address:127.0.0.1#53

Name:   localhost
Address: 127.0.0.1

tub@taylan:~$

The local DNS server is dnsmasq.

> What does /etc/hosts say?

tub@taylan:~$ cat /etc/hosts
127.0.0.1   localhost
127.0.1.1   taylan.uni.cx   taylan

# The following lines are desirable for IPv6 capable hosts
::1 localhost ip6-localhost ip6-loopback
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
tub@taylan:~$

This is on Debian and I don't remember manually mucking with the file.

Were you not able to reproduce the bug?

Taylan





bug#18914: 2.0.11 REPL server listens on 127.0.0.1 but not "localhost"

2014-10-31 Thread &quot;Taylan Ulrich Bayırlı/Kammer"
After starting 'guile --listen', I can connect to it via 127.0.0.1 but
not "localhost": "Ncat: Connection refused."  I don't know if
listening on "localhost" by default has any security implications?


Shell 1:

tub@taylan:~$ guile --listen
GNU Guile 2.0.11
Copyright (C) 1995-2014 Free Software Foundation, Inc.

Guile comes with ABSOLUTELY NO WARRANTY; for details type `,show w'.
This program is free software, and you are welcome to redistribute it
under certain conditions; type `,show c' for details.

Enter `,help' for help.
scheme@(guile-user)>


Shell 2:

tub@taylan:~$ ncat localhost 37146
Ncat: Connection refused.
tub@taylan:~$ ncat 127.0.0.1 37146
GNU Guile 2.0.11
Copyright (C) 1995-2014 Free Software Foundation, Inc.

Guile comes with ABSOLUTELY NO WARRANTY; for details type `,show w'.
This program is free software, and you are welcome to redistribute it
under certain conditions; type `,show c' for details.

Enter `,help' for help.
scheme@(guile-user)>


Taylan