On Fri, Oct 10, 2008 at 7:48 AM, Chouser <[EMAIL PROTECTED]> wrote:
>
> Of course that means I need to do this for you when printing...

I've attached an updated patch with a new print method, against the
latest SVN 1058.

If you really want to dig into the ugliness, here's a test I've been
using.  Apply the attached patch, rebuild clojure, and then load up
this code:

(import '(java.util.regex Pattern)
        '(java.io PushbackReader StringReader))
(defn test-re [s & [ts]]
  (let [p1 (Pattern/compile s)
        p2 (read (PushbackReader. (StringReader. (prn-str p1))))]
    (println (str "raw str: " s))
    (print   (str "prn1:  " (prn-str p1)))
    (print   (str "prn2:  " (prn-str p2)))
    (println (if (= (prn-str p1) (prn-str p2)) "PASS" "FAIL"))
    (when ts
      (println (str "match1: " (re-find p1 ts)))
      (println (str "match2: " (re-find p2 ts)))
      (println (if (= (re-find p1 ts) (re-find p2 ts)) "PASS" "FAIL")))
    (println)))

You run it by passing in a string to be compiled by Pattern.  This is
essentially the "old format" without the leading # char:

user=> (test-re "foo")
raw str: foo
prn1:  #"foo"
prn2:  #"foo"
PASS

If my print method is correct, prn1 and prn2 should always be the
same, and thus PASS.  Also what you're seeing there is the "new
format".  In this case, both the old and new formats are the same.

If you pass in an optional second string, test-re will try to match it
with both patterns:

user=> (test-re "a \\\"\\w*\\\" please" "a \"word\" please")
raw str: a \"\w*\" please
prn1:  #"a \"\w*\" please"
prn2:  #"a \"\w*\" please"
PASS
match1: a "word" please
match2: a "word" please
PASS

Again, if my patch if my patch is correct, match1 and match2 should be
the same, and thus another PASS.  Here you can see how the new format
(prn1 and prn2) are simpler than the old format, as well as being
identical to what Pattern actually operates on (raw str).

Here's a truly nasty example prompted by Christophe Grand's comment:

user=> (test-re "a\"\\Qb\"c\\d\\Ee\"f" "a\"b\"c\\de\"f")
raw str: a"\Qb"c\d\Ee"f
prn1:  #"a\"\Qb\E\"\Qc\d\Ee\"f"
prn2:  #"a\"\Qb\E\"\Qc\d\Ee\"f"
PASS
match1: a"b"c\de"f
match2: a"b"c\de"f
PASS

If you can find *any* input that produces FAIL, please let me know.

--Chouser

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To post to this group, send email to clojure@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~----------~----~----~----~------~----~------~--~---

diff --git a/src/clj/clojure/boot.clj b/src/clj/clojure/boot.clj
index 7fd1a22..2f95fc4 100644
--- a/src/clj/clojure/boot.clj
+++ b/src/clj/clojure/boot.clj
@@ -3536,6 +3536,24 @@
   (.write w "M"))
 
 (defmethod print-method java.util.regex.Pattern [p #^Writer w]
-  (.append w \#)
-  (print-method (str p) w))
+  (.write w "#\"")
+  (loop [[#^Character c & r :as s] (seq (.pattern #^java.util.regex.Pattern p))
+         qmode false]
+    (when s
+      (cond
+        (= c \\) (let [[#^Character c2 & r2] r]
+                   (.append w \\)
+                   (.append w c2)
+                   (if qmode
+                      (recur r2 (not= c2 \E))
+                      (recur r2 (= c2 \Q))))
+        (= c \") (do
+                   (if qmode
+                     (.write w "\\E\\\"\\Q")
+                     (.write w "\\\""))
+                   (recur r qmode))
+        :else    (do
+                   (.append w c)
+                   (recur r qmode)))))
+  (.append w \"))
 
diff --git a/src/jvm/clojure/lang/LispReader.java b/src/jvm/clojure/lang/LispReader.java
index d4d03f8..b0caf38 100644
--- a/src/jvm/clojure/lang/LispReader.java
+++ b/src/jvm/clojure/lang/LispReader.java
@@ -359,8 +359,22 @@ static class RegexReader extends AFn{
 	static StringReader stringrdr = new StringReader();
 
 	public Object invoke(Object reader, Object doublequote) throws Exception{
-		String str = (String) stringrdr.invoke(reader, doublequote);
-		return Pattern.compile(str);
+		StringBuilder sb = new StringBuilder();
+		Reader r = (Reader) reader;
+		for(int ch = r.read(); ch != '"'; ch = r.read())
+			{
+			if(ch == -1)
+				throw new Exception("EOF while reading regex");
+			sb.append( (char) ch );
+			if(ch == '\\')	//escape
+				{
+				ch = r.read();
+				if(ch == -1)
+					throw new Exception("EOF while reading regex");
+				sb.append( (char) ch ) ;
+				}
+			}
+		return Pattern.compile(sb.toString());
 	}
 }
 

Reply via email to