summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorLudovic Court`es2007-06-07 12:28:53 +0000
committerLudovic Court`es2007-06-07 12:28:53 +0000
commit4de56f3575d36dd0a2c439af4fcc697dafa34dcf (patch)
treef34bd47584adb78d9ed9893ac5dd993b8ddc4093 /src
parente6bda4dce5fa0fdc935484e2a2540953f43b5a2d (diff)
downloadskribilo-4de56f3575d36dd0a2c439af4fcc697dafa34dcf.tar.gz
skribilo-4de56f3575d36dd0a2c439af4fcc697dafa34dcf.tar.lz
skribilo-4de56f3575d36dd0a2c439af4fcc697dafa34dcf.zip
Optimized `make-general-string-replace'.
* src/guile/skribilo/utils/strings.scm (%make-general-string-replace):
  Rewritten in a way that is more efficient with Guile 1.8.

git-archimport-id: lcourtes@laas.fr--2006-libre/skribilo--devo--1.2--patch-66
Diffstat (limited to 'src')
-rw-r--r--src/guile/skribilo/utils/strings.scm52
1 files changed, 22 insertions, 30 deletions
diff --git a/src/guile/skribilo/utils/strings.scm b/src/guile/skribilo/utils/strings.scm
index 756cc8e..9d9ef41 100644
--- a/src/guile/skribilo/utils/strings.scm
+++ b/src/guile/skribilo/utils/strings.scm
@@ -1,7 +1,7 @@
 ;;; strings.scm	-- Convenience functions to manipulate strings.
 ;;;
 ;;; Copyright 2003, 2004  Erick Gallesio - I3S-CNRS/ESSI <eg@unice.fr>
-;;; Copyright 2005, 2006  Ludovic Courtès <ludovic.courtes@laas.fr>
+;;; Copyright 2005, 2006, 2007  Ludovic Courtès <ludovic.courtes@laas.fr>
 ;;;
 ;;; 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
@@ -86,31 +86,10 @@
 ;;; String writing.
 ;;;
 
-;;
-;; (define (%make-html-replace)
-;;   ;; Ad-hoc version for HTML, a little bit faster than the
-;;   ;; make-general-string-replace define later (particularily if there
-;;   ;; is nothing to replace since, it does not allocate a new string
-;;   (let ((specials (string->regexp "&|\"|<|>")))
-;;     (lambda (str)
-;;       (if (regexp-match specials str)
-;;	  (begin
-;;	    (let ((out (open-output-string)))
-;;	      (dotimes (i (string-length str))
-;;		(let ((ch (string-ref str i)))
-;;		  (case ch
-;;		    ((#\") (display "&quot;" out))
-;;		    ((#\&) (display "&amp;" out))
-;;		    ((#\<) (display "&lt;" out))
-;;		    ((#\>) (display "&gt;" out))
-;;		    (else  (write-char ch out)))))
-;;	      (get-output-string out)))
-;;	  str))))
-
-
 (define (%make-general-string-replace lst)
   ;; The general version
-  (let ((chars (make-hash-table 200)))
+  (let ((chars (make-hash-table 200))
+        (set   (apply char-set (map car lst))))
 
     ;; Setup a hash table equivalent to LST.
     (for-each (lambda (chr)
@@ -121,12 +100,25 @@
     (set! lst #f)
 
     (lambda (str)
-      (let ((out (open-output-string)))
-	(string-for-each (lambda (ch)
-                           (display (or (hashq-ref chars ch #f) ch)
-                                    out))
-			 str)
-	(get-output-string out)))))
+      ;; Note: This implementation is optimized for Guile 1.8 where
+      ;; `string-index' is implemented in C and where `string-length' and
+      ;; `string-ref' are O(1).  Consult the repository's history for a more
+      ;; UTF-friendly implementation.
+      (let ((len (string-length str)))
+        (let loop ((pos 0)
+                   (result '()))
+          (if (>= pos len)
+              (string-concatenate (reverse! result))
+              (let ((idx (string-index str set pos)))
+                (if idx
+                    (loop (+ 1 idx)
+                          (cons* (hashq-ref chars (string-ref str idx)
+                                            #f)
+                                 (substring str pos idx)
+                                 result))
+                    (loop len
+                          (cons (substring str pos len)
+                                result))))))))))
 
 (define %html-replacements
   '((#\" "&quot;") (#\& "&amp;") (#\< "&lt;") (#\> "&gt;")))