2003/11/13 05:04:23
authormegacz <megacz@xwt.org>
Fri, 30 Jan 2004 07:41:14 +0000 (07:41 +0000)
committermegacz <megacz@xwt.org>
Fri, 30 Jan 2004 07:41:14 +0000 (07:41 +0000)
darcs-hash:20040130074114-2ba56-a363dff767469d49fef57a08b9668bb8a2885a76.gz

14 files changed:
src/org/xwt/js/Regexp.java [deleted file]
src/org/xwt/js/ScopeImpl.java [deleted file]
src/org/xwt/plat/AWT.java
src/org/xwt/plat/Darwin.java
src/org/xwt/plat/OpenGL.java
src/org/xwt/plat/Win32.java
src/org/xwt/plat/X11.java
src/org/xwt/translators/HTML.java
src/org/xwt/translators/MSPack.java
src/org/xwt/util/Cache.java
src/org/xwt/util/Hash.java
src/org/xwt/util/Log.java
src/org/xwt/util/Preprocessor.java
src/org/xwt/util/XML.java

diff --git a/src/org/xwt/js/Regexp.java b/src/org/xwt/js/Regexp.java
deleted file mode 100644 (file)
index 834a425..0000000
+++ /dev/null
@@ -1,361 +0,0 @@
-package org.xwt.js;
-
-import gnu.regexp.*;
-
-public class Regexp extends JS.Obj {
-    private boolean global;
-    private RE re;
-    private int lastIndex;
-    
-    public Regexp(Object arg0, Object arg1) throws JS.Exn {
-        if(arg0 instanceof Regexp) {
-            Regexp r = (Regexp) arg0;
-            this.global = r.global;
-            this.re = r.re;
-            this.lastIndex = r.lastIndex;
-        } else {
-            String pattern = arg0.toString();
-            String sFlags = null;
-            int flags = 0;
-            if(arg1 != null) sFlags = (String)arg1;
-            if(sFlags == null) sFlags = "";
-            for(int i=0;i<sFlags.length();i++) {
-                switch(sFlags.charAt(i)) {
-                    case 'i': flags |= RE.REG_ICASE; break;
-                    case 'm': flags |= RE.REG_MULTILINE; break;
-                    case 'g': global = true; break;
-                    default: throw new JS.Exn("Invalid flag in regexp \"" + sFlags.charAt(i) + "\"");
-                }
-            }
-            re = newRE(pattern,flags);
-            _put("source",pattern);
-            _put("global",wrapBool(global));
-            _put("ignoreCase",wrapBool(flags & RE.REG_ICASE));
-            _put("multiline",wrapBool(flags & RE.REG_MULTILINE));
-        }
-    }
-
-    public Object callMethod(Object method, Array args, boolean checkOnly) throws JS.Exn {
-        if (method.equals("exec")) {
-            if (checkOnly) return Boolean.TRUE;
-            return exec(args);
-        } else if (method.equals("test")) {
-            if (checkOnly) return Boolean.TRUE;
-            return test(args);
-        } else if (method.equals("toString")) {
-            if (checkOnly) return Boolean.TRUE;
-            return toString();
-        }
-        if (checkOnly) return Boolean.FALSE;
-        return null;
-    }
-    
-    // gcj bug...
-    public Object get(Object key) { return _get(key); }
-    public Object put(Object key,Object value) { _put(key,value); return null; }
-
-    public Object _get(Object key) {
-        if(key.equals("lastIndex")) return new Integer(lastIndex);
-        return super.get(key);
-    }
-    
-    public void _put(Object key, Object value) {
-        if(key.equals("lastIndex")) lastIndex = JS.toNumber(value).intValue();
-        super.put(key,value);
-    }
-    
-    private Object exec(String s) throws JS.Exn  {
-        int start = global ? lastIndex : 0;
-        if(start < 0 || start >= s.length()) {
-            lastIndex = 0;
-            return null;
-        }
-        
-        REMatch match = re.getMatch(s,start);
-        if(global)
-            lastIndex = match == null ? s.length() : match.getEndIndex();
-        if(match == null)
-            return null;
-        else
-            return matchToExecResult(match,re,s);
-    }
-    
-    private static Object matchToExecResult(REMatch match, RE re, String s) {
-        JS.Obj ret = new JS.Obj();
-        ret.put("index",new Integer(match.getStartIndex()));
-        ret.put("input",s);
-        int n = re.getNumSubs();
-        ret.put("length",new Integer(n+1));
-        ret.put("0",match.toString());
-        for(int i=1;i<=n;i++)
-            ret.put(Integer.toString(i),match.toString(i));
-        return ret;
-    }
-    
-    
-    private Object exec(JS.Array args) throws JS.Exn  {
-        if(args.length() < 1) throw new JS.Exn("Not enough args to exec");
-        String s = args.elementAt(0).toString();
-        return exec(s);
-    }
-    
-    private Object test(JS.Array args)  throws JS.Exn {
-        if(args.length() < 1) throw new JS.Exn("Not enough args to match");
-        String s = args.elementAt(0).toString();
-        
-        if(global) {
-            int start = global ? lastIndex : 0;
-            if(start < 0 || start >= s.length()) {
-                lastIndex = 0;
-                return null;
-            }
-        
-            REMatch match = re.getMatch(s,start);
-            lastIndex = match != null ? s.length() : match.getEndIndex();
-            return wrapBool(match != null);
-        } else {
-            return wrapBool(re.getMatch(s) != null);
-        }
-    }
-    
-    public String toString() {
-        StringBuffer sb = new StringBuffer();
-        sb.append('/');
-        sb.append(_get("source"));
-        sb.append('/');
-        if(global) sb.append('g');
-        if(Boolean.TRUE.equals(_get("ignoreCase"))) sb.append('i');
-        if(Boolean.TRUE.equals(_get("multiline"))) sb.append('m');
-        return sb.toString();
-    }
-    
-    public static Object stringMatch(Object o, JS.Array args) throws JS.Exn {
-        if(args.length() < 1) throw new JS.Exn("not enough args to match");
-        Object arg0 = args.elementAt(0);
-        String s = o.toString();
-        RE re;
-        Regexp regexp = null;
-        if(arg0 instanceof Regexp) {
-            regexp = (Regexp) arg0;
-            re = regexp.re;
-        } else {
-            re = newRE(arg0.toString(),0);
-        }
-        
-        if(regexp == null) {
-            REMatch match = re.getMatch(s);
-            return matchToExecResult(match,re,s);
-        }
-        if(!regexp.global)
-            return regexp.exec(s);
-        
-        JS.Array ret = new JS.Array();
-        REMatch[] matches = re.getAllMatches(s);
-        for(int i=0;i<matches.length;i++)
-            ret.addElement(matches[i].toString());
-        if(matches.length > 0)
-            regexp.lastIndex = matches[matches.length-1].getEndIndex();
-        else
-            regexp.lastIndex = s.length();
-        return ret;
-    }
-    
-    public static Object stringSearch(Object o, JS.Array args) throws JS.Exn  {
-        if(args.length() < 1) throw new JS.Exn("not enough args to match");
-        Object arg0 = args.elementAt(0);
-        String s = o.toString();
-        RE re;
-        if(arg0 instanceof Regexp)
-            re = ((Regexp)arg0).re;
-        else
-            re = newRE(arg0.toString(),0);
-        REMatch match = re.getMatch(s);
-        if(match == null) return new Integer(-1);
-        return new Integer(match.getStartIndex());
-    }
-    
-    public static Object stringReplace(Object o, JS.Array args) throws JS.Exn {
-        if(args.length() < 2) throw new JS.Exn("not enough args to replace");
-        Object arg0 = args.elementAt(0);
-        Object arg1 = args.elementAt(1);
-        String s = o.toString();
-        RE re;
-        JS.Callable replaceFunc = null;
-        String replaceString = null;
-        Regexp regexp = null;
-        if(arg0 instanceof Regexp) {
-            regexp = (Regexp) arg0;
-            re = regexp.re;
-        } else {
-            re = newRE(arg0.toString(),0);
-        }
-        if(arg1 instanceof JS.Callable)
-            replaceFunc = (JS.Callable) arg1;
-        else
-            replaceString = arg1.toString();
-        REMatch[] matches;
-        if(regexp != null && regexp.global) {
-            matches = re.getAllMatches(s);
-            if(regexp != null) {
-                if(matches.length > 0)
-                    regexp.lastIndex = matches[matches.length-1].getEndIndex();
-                else
-                    regexp.lastIndex = s.length();
-            }
-        } else {
-            REMatch match = re.getMatch(s);
-            if(match != null)
-                matches = new REMatch[]{ match };
-            else
-                matches = new REMatch[0];
-        }
-        
-        StringBuffer sb = new StringBuffer(s.length());
-        int pos = 0;
-        char[] sa = s.toCharArray();
-        for(int i=0;i<matches.length;i++) {
-            REMatch match = matches[i];
-            sb.append(sa,pos,match.getStartIndex()-pos);
-            pos = match.getEndIndex();
-            if(replaceFunc != null) {
-                JS.Array a = new JS.Array();
-                a.addElement(match.toString());
-                if(regexp != null) {
-                    int n = re.getNumSubs();
-                    for(int j=1;j<=n;j++)
-                        a.addElement(match.toString(j));
-                }
-                a.addElement(new Integer(match.getStartIndex()));
-                a.addElement(s);
-                Object ret = replaceFunc.call(a);
-                sb.append(ret.toString());
-            } else {
-                sb.append(mySubstitute(match,replaceString,s));
-            }
-        }
-        int end = matches.length == 0 ? 0 : matches[matches.length-1].getEndIndex();
-        sb.append(sa,end,sa.length-end);
-        return sb.toString();
-    }
-    
-    private static String mySubstitute(REMatch match, String s, String source) {
-        StringBuffer sb = new StringBuffer();
-        int i,n;
-        char c,c2;
-        for(i=0;i<s.length()-1;i++) {
-           c = s.charAt(i);
-            if(c != '$') {
-                sb.append(c);
-                continue;
-            }
-            i++;
-            c = s.charAt(i);
-            switch(c) {
-                case '0': case '1': case '2': case '3': case '4':
-                case '5': case '6': case '7': case '8': case '9':
-                    if(i < s.length()-1 && (c2 = s.charAt(i+1)) >= '0' && c2 <= '9') {
-                        n = (c - '0') * 10 + (c2 - '0');
-                        i++;
-                    } else {
-                        n = c - '0';
-                    }
-                    if(n > 0)
-                        sb.append(match.toString(n));
-                    break;
-                case '$':
-                    sb.append('$'); break;
-                case '&':
-                    sb.append(match.toString()); break;
-                case '`':
-                    sb.append(source.substring(0,match.getStartIndex())); break;
-                case '\'':
-                    sb.append(source.substring(match.getEndIndex())); break;
-                default:
-                    sb.append('$');
-                    sb.append(c);
-            }
-        }
-        if(i < s.length()) sb.append(s.charAt(i));
-        return sb.toString();
-    }
-                    
-    
-    public static Object stringSplit(Object o,JS.Array args) {
-        String s = o.toString();
-        if(args.length() < 1 || args.elementAt(0) == null || s.length() == 0) {
-            JS.Array ret = new JS.Array();
-            ret.addElement(s);
-            return ret;
-        }
-        Object arg0 = args.elementAt(0);
-        
-        int limit = args.length() < 2 ? Integer.MAX_VALUE : JS.toInt(args.elementAt(1));
-        if(limit < 0) limit = Integer.MAX_VALUE;
-        if(limit == 0) return new JS.Array();
-        
-        RE re = null;
-        Regexp regexp = null;
-        String sep = null;
-        JS.Array ret = new JS.Array();
-        int p = 0;
-        
-        if(arg0 instanceof Regexp) {
-            regexp = (Regexp) arg0;
-            re = regexp.re;
-        } else {
-            sep = arg0.toString();
-        }
-        
-        // special case this for speed. additionally, the code below doesn't properly handle
-        // zero length strings
-        if(sep != null && sep.length()==0) {
-            int len = s.length();
-            for(int i=0;i<len;i++)
-                ret.addElement(s.substring(i,i+1));
-            return ret;
-        }
-        
-        OUTER: while(p < s.length()) {
-            if(re != null) {
-                REMatch m = re.getMatch(s,p);
-                if(m == null) break OUTER;
-                boolean zeroLength = m.getStartIndex() == m.getEndIndex();
-                ret.addElement(s.substring(p,zeroLength ? m.getStartIndex()+1 : m.getStartIndex()));
-                p = zeroLength ? p + 1 : m.getEndIndex();
-                if(!zeroLength) {
-                    for(int i=1;i<=re.getNumSubs();i++) {
-                        ret.addElement(m.toString(i));
-                        if(ret.length() == limit) break OUTER;
-                    }
-                }
-            } else {
-                int x = s.indexOf(sep,p);
-                if(x == -1) break OUTER;
-                ret.addElement(s.substring(p,x));
-                p = x + sep.length();
-            }
-            if(ret.length() == limit) break;
-        }
-        if(p < s.length() && ret.length() != limit)
-            ret.addElement(s.substring(p));
-        return ret;
-    }
-    
-    public static RE newRE(String pattern, int flags) throws JS.Exn {
-        try {
-            return new RE(pattern,flags,RESyntax.RE_SYNTAX_PERL5);
-        } catch(REException e) {
-            throw new JS.Exn(e.toString());
-        }
-    }
-    
-    private static Boolean wrapBool(boolean b) {
-        return b ? Boolean.TRUE : Boolean.FALSE;
-    }
-    
-    private static Boolean wrapBool(int n) {
-        return wrapBool(n != 0);
-    }
-    
-    public String typeName() { return "regexp"; }
-}
diff --git a/src/org/xwt/js/ScopeImpl.java b/src/org/xwt/js/ScopeImpl.java
deleted file mode 100644 (file)
index a01b3bb..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-// Copyright 2003 Adam Megacz, see the COPYING file for licensing [GPL] 
-
-package org.xwt.js; 
-import org.xwt.util.*; 
-import java.io.*;
-import java.util.*;
-
-/** Implementation of a JavaScript Scope */
-class ScopeImpl extends JS.Obj { 
-    private JS.Scope parentScope;
-    private static final Object NULL_PLACEHOLDER = new Object();
-    public ScopeImpl(JS.Scope parentScope, boolean sealed) {
-        super(sealed);
-        if (parentScope == this) throw new Error("can't make a scope its own parent!");
-        this.parentScope = parentScope;
-    }
-    public Object[] keys() { throw new Error("you can't enumerate the properties of a Scope"); }
-    public boolean has(Object key) { return super.get(key) != null; }
-    // we use _get instead of get solely to work around a GCJ bug
-    public Object _get(Object key) {
-        Object o = super.get(key);
-        if (o != null) return o == NULL_PLACEHOLDER ? null : o;
-        else return parentScope == null ? null : parentScope.get(key);
-    }
-    // we use _put instead of put solely to work around a GCJ bug
-    public void _put(Object key, Object val) {
-        if (parentScope != null && !has(key)) parentScope.put(key, val);
-        else super.put(key, val == null ? NULL_PLACEHOLDER : val);
-    }
-    public boolean isTransparent() { return false; }
-    public void declare(String s) { super.put(s, NULL_PLACEHOLDER); }
-    public Scope getParentScope() { return parentScope; }
-}
-
index fd9703b..cca1209 100644 (file)
@@ -193,7 +193,7 @@ public class AWT extends JVM {
         }
 
         // FIXME: try to use os acceleration
-        public void fillTrapezoid(int x1, int x2, int y1, int x3, int x4, int y2, int argb) {
+        public void fillJSTrapezoid(int x1, int x2, int y1, int x3, int x4, int y2, int argb) {
             g.setColor(new Color((argb & 0x00FF0000) >> 16, (argb & 0x0000FF00) >> 8, (argb & 0x000000FF)));
             if (x1 == x3 && x2 == x4) {
                 g.fillRect(x1, y1, x4 - x1, y2 - y1);
index 44d0ec2..907b937 100644 (file)
@@ -98,20 +98,20 @@ public class Darwin extends POSIX {
     
     private final class CarbonOpenGL extends OpenGL {
         public RawData rawPixelFormat;
-        public RawData rawSharedContext;
+        public RawData rawSharedJSContext;
         public int maxAglSurfaceTexSize;
         public int maxSurfaceWidth;
         public int maxSurfaceHeight;
         
         private native boolean initPixelFormat();
-        private native void initSharedContext();
+        private native void initSharedJSContext();
         
         public CarbonOpenGL() throws NotSupportedException {
             if(!jaguar)
                 throw new NotSupportedException("OpenGL requires Mac OS X 10.2 or greater");
             if(!initPixelFormat())
                 throw new NotSupportedException("Couldn't get an acceptable pixel format");
-            initSharedContext();
+            initSharedJSContext();
         }
         
         public void init() throws NotSupportedException {
@@ -123,7 +123,7 @@ public class Darwin extends POSIX {
             }
             maxSurfaceWidth = maxSurfaceHeight = maxAglSurfaceTexSize;
         }
-        protected native void activateSharedContext();
+        protected native void activateSharedJSContext();
     }
     
     static abstract class CarbonSurface extends Surface.DoubleBufferedSurface {  
@@ -216,7 +216,7 @@ public class Darwin extends POSIX {
             CarbonMessage.add(new CarbonMessage() { public void perform() { GLCarbonPixelBuffer.this.natInit(); sem.release(); } });
             sem.block();
         }
-        public native void activateContext();
+        public native void activateJSContext();
         protected void finalize() {
             CarbonMessage.add(new CarbonMessage() { public void perform() { natCleanup(rawWindowRef,rawCTX); } });
             gl.deleteTexture(textureName);
index d4bbe1e..8ed60c2 100644 (file)
@@ -28,7 +28,7 @@ abstract class OpenGL {
         }
     }
     
-    // This MUST be called after OpenGL is instansiated (and activateSharedContext is functioning)
+    // This MUST be called after OpenGL is instansiated (and activateSharedJSContext is functioning)
     public void init() throws NotSupportedException {
         natInit();
         glVersion = parseVersion(version);
@@ -46,7 +46,7 @@ abstract class OpenGL {
         Log.log(this,"Max rectangular texture size: " + maxRectTexSize);
     }
     
-    protected abstract void activateSharedContext();
+    protected abstract void activateSharedJSContext();
 
     public static class NotSupportedException extends Exception {
         public NotSupportedException(String s) { super(s); }
@@ -66,7 +66,7 @@ abstract class OpenGL {
         }
         
         // This should activate the drawing context and prepare the double buffer for drawing
-        protected abstract void activateContext();
+        protected abstract void activateJSContext();
         
         protected static native void drawableInit(int w, int h);
         
@@ -74,7 +74,7 @@ abstract class OpenGL {
         
         public native void setClip(int x, int y, int x2, int y2);
         public native void resetClip();
-        public native void fillTrapezoid(int x1, int x2, int y1, int x3, int x4, int y2, int color);
+        public native void fillJSTrapezoid(int x1, int x2, int y1, int x3, int x4, int y2, int color);
             
         public void drawString(String font, String text, int x, int y, int color) {
             //System.out.println("drawString(): " + text);
@@ -88,7 +88,7 @@ abstract class OpenGL {
         }
 
         private void drawPicture_(Picture source, int dx, int dy, int cx1, int cy1, int cx2, int cy2, int color) {
-            activateContext();
+            activateJSContext();
             setColor(color);
             GLPicture p = (GLPicture) source;
             p.draw(dx,dy,cx1,cy1,cx2,cy2);
index 1689ef6..100da9b 100644 (file)
@@ -92,8 +92,8 @@ public class Win32 extends GCJ {
 
         HTTP.Proxy ret = new HTTP.Proxy();
         if (container[2] != null) {
-            ret.proxyAutoConfigFunction = HTTP.Proxy.getProxyAutoConfigFunction(container[2]);
-            if (ret.proxyAutoConfigFunction != null) return ret;
+            ret.proxyAutoConfigJSFunction = HTTP.Proxy.getProxyAutoConfigJSFunction(container[2]);
+            if (ret.proxyAutoConfigJSFunction != null) return ret;
         }
 
         if (container[0] == null) return null;
@@ -274,7 +274,7 @@ public class Win32 extends GCJ {
         public native void finalize();
 
         // FIXME: try to use os acceleration
-        public void fillTrapezoid(int x1, int x2, int y1, int x3, int x4, int y2, int argb) {
+        public void fillJSTrapezoid(int x1, int x2, int y1, int x3, int x4, int y2, int argb) {
             if (x1 == x3 && x2 == x4) {
                 fillRect(x1, y1, x4, y2, argb);
             } else for(int y=y1; y<y2; y++) {
index 72751bd..0347c54 100644 (file)
@@ -155,8 +155,8 @@ public class X11 extends POSIX {
         RawData fake_ximage = null;    // a 'fake' XImage corresponding to the shared pixmap; gives us the address and depth parameters
         RawData shm_segment = null;    // XShmSegmentInfo
 
-        RawData gc;                    // Graphics Context on pm (never changes, so it's fast)
-        RawData clipped_gc;            // Graphics Context on pm, use this one if you need a clip/stipple
+        RawData gc;                    // Graphics JSContext on pm (never changes, so it's fast)
+        RawData clipped_gc;            // Graphics JSContext on pm, use this one if you need a clip/stipple
 
         /** PixelBuffer mode */
         public X11PixelBuffer(int w, int h) { this(w, h, true); }
@@ -201,7 +201,7 @@ public class X11 extends POSIX {
         public native void finalize();
 
         // FIXME: try to use os acceleration
-        public void fillTrapezoid(int x1, int x2, int y1, int x3, int x4, int y2, int argb) {
+        public void fillJSTrapezoid(int x1, int x2, int y1, int x3, int x4, int y2, int argb) {
             if (x1 == x3 && x2 == x4) {
                 fillRect(x1, y1, x4, y2, argb);
             } else for(int y=y1; y<y2; y++) {
index bd6f350..055a1c3 100644 (file)
@@ -52,7 +52,7 @@ public class HTML {
 
     public static synchronized JS parseReader(Reader r) throws IOException {
         CharStream cs = new CharStream(r);
-        JS.Obj h = new JS.Obj();
+        JSObj h = new JSObj();
 
         withinLI = false;
         h.put("$name", "html");
@@ -63,13 +63,14 @@ public class HTML {
             // continue until we get an EOFException
         }
         
+        /* FIXME
         Object[] ids = h.keys();
         for(int i=0; i<ids.length; i++) {
             Object el = h.get((String)ids[i]);
             if (el instanceof JS && "html".equals(((JS)el).get("$name")))
                 return (JS)el;
         }
-        
+        */        
         return h;
     }
 
@@ -162,7 +163,7 @@ public class HTML {
             try {
                 // scan subelement
                 if (cs.peek() != '/') {
-                    JS kid = new JS.Obj();
+                    JS kid = new JSObj();
                     closetag = parseElement(cs, kid);
                     h.put(String.valueOf(length), kid); 
                     h.put("$numchildren", new Integer(++length));
index c9482eb..b34231c 100644 (file)
@@ -66,7 +66,9 @@ public class MSPack {
     
     public String[] getFileNames() { return fileNames; }
     public int[] getLengths() { return lengths; }
-    public InputStream getInputStream(int index) { return new ByteArrayInputStream(data[index]); }
+    public InputStream getInputStream(int index) {
+        return new KnownLength.KnownLengthInputStream(ByteArrayInputStream(data[index]), data[index].length);
+    }
     public InputStream getInputStream(String fileName) {
         for(int i=0;i<fileNames.length;i++) {
             if(fileName.equalsIgnoreCase(fileNames[i])) return getInputStream(i);
index 2822555..1f94414 100644 (file)
@@ -13,10 +13,19 @@ public class Cache extends Hash {
     Node mru = null;
     Node lru = null;
 
+    private int maxSize;
+    private Cache() { }
+    public Cache(int maxSize) {
+        super(maxSize * 2, 3);
+        this.maxSize = maxSize;
+    }
+
     /** A doubly-linked list */
     private class Node {
         final Object val;
-        public Node(Object val) { this.val = val; }
+        final Object k1;
+        final Object k2;
+        public Node(Object k1, Object k2, Object val) { this.k1 = k1; this.k2 = k2; this.val = val; }
         Node next = null;
         Node prev = null;
         void remove() {
@@ -65,7 +74,7 @@ public class Cache extends Hash {
     }
 
     public void put(Object k1, Object k2, Object v) {
-        Node n = new Node(v);
+        Node n = new Node(k1, k2, v);
         if (lru == null) {
             lru = mru = n;
         } else {
@@ -74,6 +83,7 @@ public class Cache extends Hash {
         }
         if (super.get(k1, k2) != null) remove(k1, k2);
         super.put(k1, k2, n);
+        if (size > maxSize) remove(lru.k1, lru.k2);
     }
 
 }
index 30d07ed..8256152 100644 (file)
@@ -50,13 +50,9 @@ public class Hash {
     }
 
     /** returns all the primary keys in the table */
-    public Object[] keys() {
-        int howmany = 0;
-        for(int i=0; i<vals.length; i++) if (keys1[i] != null) howmany++;
-        Object[] ret = new Object[howmany];
-        int where = 0;
-        for(int i=0; i<vals.length; i++) if (keys1[i] != null) ret[where++] = keys1[i];
-        return ret;
+    public Enumeration keys() {
+        // FIXME!!!
+        return null;
     }
 
     public Hash() { this(25, 3); }
index dd390d0..424e056 100644 (file)
@@ -1,6 +1,6 @@
 // Copyright 2003 Adam Megacz, see the COPYING file for licensing [LGPL]
 package org.xwt.util;
-import org.xwt.js.JS;
+import org.xwt.js.*;
 import java.io.*;
 import java.util.*;
 
@@ -17,14 +17,7 @@ public class Log {
 
     /** log a message with the current JavaScript sourceName/line */
     public static void logJS(Object o, Object message) { logJS(message); }
-    public static void logJS(Object message) {
-        JS.Context current = org.xwt.js.JS.Context.current();
-        if (current == null) {
-            log("<none>", message);
-        } else {
-            log(current.getSourceName() + ":" + current.getLine(), message);
-        }
-    }
+    public static void logJS(Object message) { log(JSContext.getSource() + ":" + JSContext.getLine(), message); }
 
     /** message can be a String or a Throwable */
     public static synchronized void log(Object o, Object message) {
@@ -75,4 +68,33 @@ public class Log {
         }
     }
 
+    public static void recurseiveLog(String indent, String name, Object o) {
+        if (!name.equals("")) name += " : ";
+
+        if (o == null) {
+            Log.logJS(indent + name + "<null>");
+
+        } else if (o instanceof JSArray) {
+            Log.logJS(indent + name + "<array>");
+            JSArray na = (JSArray)o;
+            for(int i=0; i<na.length(); i++)
+                recurse(indent + "  ", i + "", na.elementAt(i));
+
+        } else if (o instanceof JS) {
+            Log.logJS(indent + name + "<object>");
+            JS s = (JS)o;
+            Enumeration e = s.keys();
+            while(e.hasMoreElements()) {
+                Object key = e.nextElement();
+                if (key != null)
+                    recurse(indent + "  ", key.toString(),
+                            (key instanceof Integer) ?
+                            s.get(((Integer)key)) : s.get(key.toString()));
+            }
+        } else {
+            Log.logJS(indent + name + o);
+
+        }
+    }
+
 }
index 2309257..47c3134 100644 (file)
@@ -37,13 +37,34 @@ public class Preprocessor {
             String trimmed = s.trim();
             if (trimmed.startsWith("//#define ")) {
                 trimmed = trimmed.substring(10).trim();
-                String key = trimmed.substring(0, trimmed.indexOf(' '));
-                String val = trimmed.substring(trimmed.indexOf(' ')).trim();
-                replace.put(key, val);
+                if (trimmed.indexOf('(') >= 0 && trimmed.indexOf('(') < trimmed.indexOf(' ')) {
+                    JSFunctionMacro fm = new JSFunctionMacro();
+                    String key = trimmed.substring(0, trimmed.indexOf('('));
+                    String unbound = trimmed.substring(trimmed.indexOf('(') + 1, trimmed.indexOf(')'));
+                    if (unbound.indexOf(',') == -1) {
+                        fm.unbound1 = unbound;
+                    } else {
+                        fm.unbound1 = unbound.substring(0, unbound.indexOf(','));
+                        fm.unbound2 = unbound.substring(unbound.indexOf(',') + 1);
+                    }
+                    fm.expression = trimmed.substring(trimmed.indexOf(')')+1).trim();
+                    replace.put(key, fm);
+                } else {
+                    String key = trimmed.substring(0, trimmed.indexOf(' '));
+                    String val = trimmed.substring(trimmed.indexOf(' ')).trim();
+                    replace.put(key, val);
+                }
                 System.out.println(); // preserve line numbers
                 
             } else if (trimmed.startsWith("//#repeat ")) {
-                StringTokenizer st = new StringTokenizer(trimmed.substring(9), " ");
+                trimmed = trimmed.substring(9);
+                while(trimmed.charAt(trimmed.length() - 1) == '\\') {
+                    String s2 = br.readLine().trim();
+                    if (s2.startsWith("//")) s2 = s2.substring(2).trim();
+                    trimmed += s2;
+                    System.out.println();  // preserve line numbers
+                }
+                StringTokenizer st = new StringTokenizer(trimmed, " ");
                 repeatreplace = (Hashtable)replace.clone();
                 while (st.hasMoreTokens()) {
                     String tok = st.nextToken().trim();
@@ -58,7 +79,7 @@ public class Preprocessor {
                 Hashtable save = replace;
                 replace = repeatreplace;
                 System.out.println();
-                for(int i=0; i<sinceLastRepeat.size() - 1; i++) processLine((String)sinceLastRepeat.elementAt(i), true);
+                for(int i=0; i<sinceLastRepeat.size() - 1; i++) System.out.print(processLine((String)sinceLastRepeat.elementAt(i), true));
                 sinceLastRepeat = null;
                 replace = save;
 
@@ -67,8 +88,12 @@ public class Preprocessor {
                 System.out.println("final String neverUseThis = (String)("+expr+"); switch(neverUseThis.length()) {");
                 Hashtable[] byLength = new Hashtable[255];
                 String key = null;
+                String Default = null;
                 for(trimmed = br.readLine().trim(); !trimmed.startsWith("//#end"); trimmed = br.readLine().trim()) {
-                    // FIXME: default
+                    if (trimmed.startsWith("default:")) {
+                        Default = processLine(trimmed.substring(8), false);
+                        continue;
+                    }
                     if (trimmed.startsWith("case ")) {
                         trimmed = trimmed.substring(trimmed.indexOf('\"') + 1);
                         key = trimmed.substring(0, trimmed.indexOf('\"'));
@@ -80,9 +105,10 @@ public class Preprocessor {
                     }
                     if (key != null) {
                         Hashtable hash = byLength[key.length()];
-                        hash.put(key, (String)hash.get(key) + trimmed + "\n");
+                        hash.put(key, (String)hash.get(key) + processLine(trimmed, false) + "\n");
+                    } else {
+                        System.out.print(processLine(trimmed, false));
                     }
-                    else System.out.println(trimmed);
                 }
 
                 for(int i=0; i<255; i++) {
@@ -91,10 +117,11 @@ public class Preprocessor {
                     buildTrie("", byLength[i]);
                     System.out.println("}; break; }");
                 }
+                if (Default != null) System.out.println("default: { " + Default + " }");
                 System.out.println("} //switch");
 
             } else {
-                processLine(s, false);
+                System.out.print(processLine(s, false));
             }
            
         }
@@ -129,12 +156,13 @@ public class Preprocessor {
             }
         }
 
-    static void processLine(String s, boolean deleteLineEndings) throws IOException {
+    static String processLine(String s, boolean deleteLineEndings) throws IOException {
         if (deleteLineEndings && s.indexOf("//") != -1) s = s.substring(0, s.indexOf("//"));
+        String ret = "";
         for(int i=0; i<s.length(); i++) {
             char c = s.charAt(i);
             if (!Character.isLetter(c) && !Character.isDigit(c) && c != '_') {
-                System.out.print(c);
+                ret += c;
                 continue;
             }
             int j;
@@ -143,12 +171,39 @@ public class Preprocessor {
                 if (!Character.isLetter(c) && !Character.isDigit(c) && c != '_') break;
             }
             String tok = s.substring(i, j);
-            String val = (String)replace.get(tok);
-            if (val != null) System.out.print(val);
-            else System.out.print(tok);
-            i = j - 1;
+            Object val = replace.get(tok);
+            if (val == null) {
+                ret += tok;
+                i = j - 1;
+            } else if (val instanceof JSFunctionMacro) {
+                if (s.charAt(j) != '(') System.err.println("open paren must follow macro binding for macro " + tok);
+                ret += ((JSFunctionMacro)val).process(s.substring(j+1, s.indexOf(')', j)));
+                i = s.indexOf(')', j);
+            } else {
+                ret += val;
+                i = j - 1;
+            }
+        }
+        if (!deleteLineEndings) ret += "\n";
+        return ret;
+    }
+
+    public static class JSFunctionMacro {
+        public String unbound1 = null;
+        public String unbound2 = null;
+        public String expression = null;
+        public String process(String args) {
+            String bound1 = null;
+            String bound2 = null;
+            if (unbound2 == null) {
+                bound1 = args;
+                return expression.replaceAll(unbound1, bound1);
+            } else {
+                bound1 = args.substring(0, args.indexOf(','));
+                bound2 = args.substring(args.indexOf(',') + 1);
+                return (expression.replaceAll(unbound1, bound1).replaceAll(unbound2, bound2));
+            }
         }
-        if (!deleteLineEndings) System.out.println();
     }
 }
 
index 5750ea2..41f91ea 100644 (file)
@@ -894,7 +894,7 @@ public abstract class XML
 
 
     /////////////////////////////////////////////////////////////////////////////////////////////
-    // Static Support Functions for the XML Specification 
+    // Static Support JSFunctions for the XML Specification 
     /////////////////////////////////////////////////////////////////////////////////////////////
  
     // attempt to avoid these functions unless you *expect* the input to fall in the given range.