From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!.POSTED.blaine.gmane.org!not-for-mail From: Mark H Weaver Newsgroups: gmane.lisp.guile.user Subject: Re: string-ports issue on Windows Date: Thu, 18 Apr 2019 17:18:38 -0400 Message-ID: <871s1z3tbq.fsf@netris.org> References: <877ebt7tc0.fsf@netris.org> <87tvew4efa.fsf@netris.org> <875zrb3ydk.fsf@netris.org> Mime-Version: 1.0 Content-Type: text/plain Injection-Info: blaine.gmane.org; posting-host="blaine.gmane.org:195.159.176.226"; logging-data="253533"; mail-complaints-to="usenet@blaine.gmane.org" User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/26.2 (gnu/linux) Cc: guile-user To: Christopher Lam Original-X-From: guile-user-bounces+guile-user=m.gmane.org@gnu.org Thu Apr 18 23:31:41 2019 Return-path: Envelope-to: guile-user@m.gmane.org Original-Received: from lists.gnu.org ([209.51.188.17]) by blaine.gmane.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:256) (Exim 4.89) (envelope-from ) id 1hHEdB-0013qh-N6 for guile-user@m.gmane.org; Thu, 18 Apr 2019 23:31:41 +0200 Original-Received: from localhost ([127.0.0.1]:47728 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1hHEd9-0001qL-Cb for guile-user@m.gmane.org; Thu, 18 Apr 2019 17:31:39 -0400 Original-Received: from eggs.gnu.org ([209.51.188.92]:33870) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1hHESW-000363-So for guile-user@gnu.org; Thu, 18 Apr 2019 17:20:41 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1hHESV-0001DT-SY for guile-user@gnu.org; Thu, 18 Apr 2019 17:20:40 -0400 Original-Received: from world.peace.net ([64.112.178.59]:57042) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1hHESV-0000i2-Oh for guile-user@gnu.org; Thu, 18 Apr 2019 17:20:39 -0400 Original-Received: from mhw by world.peace.net with esmtpsa (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.89) (envelope-from ) id 1hHES6-0004Bf-Jd; Thu, 18 Apr 2019 17:20:14 -0400 In-Reply-To: <875zrb3ydk.fsf@netris.org> (Mark H. Weaver's message of "Thu, 18 Apr 2019 15:29:32 -0400") X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 64.112.178.59 X-BeenThere: guile-user@gnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: General Guile related discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: guile-user-bounces+guile-user=m.gmane.org@gnu.org Original-Sender: "guile-user" Xref: news.gmane.org gmane.lisp.guile.user:15402 Archived-At: Hi again, Earlier, I wrote: > Christopher Lam writes: > >> Hi Mark >> Thank you so much for looking into this. >> I'm reviewing the GnuCash for Windows package (v3.5 released April 2019) >> which contains the following libraries: >> - guile 2.0.14 > > Ah, for some reason I thought you were using Guile 2.2. That explains > the problem. > > In Guile 2.0, string ports internally used the locale encoding by > default, which meant that any characters not supported by the locale > encoding would be munged. > > Guile 2.2 changed the behavior of string ports to always use UTF-8 > internally, which ensures that all valid Guile strings can pass through > unmunged. > > So, this problem would almost certainly be fixed by updating to > Guile 2.2. It's probably a good idea to update to Guile 2.2 anyway, but I'd like to also offer the following workaround, which monkey patches the string port procedures in Guile 2.0 to behave more like Guile 2.2. Note that it only patches the Scheme APIs for string ports, and not the underlying C functions. It might be that some code, possibly within Guile itself, creates a string port using the C functions, and such string ports may still munge characters. Anyway, if you want to try it, arrange for GnuCash to evaluate the code below, after initializing Guile. Mark (when (string=? (effective-version) "2.0") ;; When using Guile 2.0.x, use monkey patching to change the ;; behavior of string ports to use UTF-8 as the internal encoding. ;; Note that this is the default behavior in Guile 2.2 or later. (let* ((mod (resolve-module '(guile))) (orig-open-input-string (module-ref mod 'open-input-string)) (orig-open-output-string (module-ref mod 'open-output-string)) (orig-object->string (module-ref mod 'object->string)) (orig-simple-format (module-ref mod 'simple-format))) (define (open-input-string str) (with-fluids ((%default-port-encoding "UTF-8")) (orig-open-input-string str))) (define (open-output-string) (with-fluids ((%default-port-encoding "UTF-8")) (orig-open-output-string))) (define (object->string . args) (with-fluids ((%default-port-encoding "UTF-8")) (apply orig-object->string args))) (define (simple-format . args) (with-fluids ((%default-port-encoding "UTF-8")) (apply orig-simple-format args))) (define (call-with-input-string str proc) (proc (open-input-string str))) (define (call-with-output-string proc) (let ((port (open-output-string))) (proc port) (get-output-string port))) (module-set! mod 'open-input-string open-input-string) (module-set! mod 'open-output-string open-output-string) (module-set! mod 'object->string object->string) (module-set! mod 'simple-format simple-format) (module-set! mod 'call-with-input-string call-with-input-string) (module-set! mod 'call-with-output-string call-with-output-string) (when (eqv? (module-ref mod 'format) orig-simple-format) (module-set! mod 'format simple-format))))