diff options
author | dnovillo <dnovillo@138bc75d-0d04-0410-961f-82ee72b054a4> | 2003-11-13 02:40:39 +0000 |
---|---|---|
committer | dnovillo <dnovillo@138bc75d-0d04-0410-961f-82ee72b054a4> | 2003-11-13 02:40:39 +0000 |
commit | e66401a7b5672b5f6d55302dc80aac33552e4b87 (patch) | |
tree | fdc8302cdc786b6da0ac882119a21eda4c69c6cf /libjava | |
parent | f3f3f8d60c8bdbeb393ef04d42396e1abab2d771 (diff) |
Mainline merge as of 2003-11-11.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/tree-ssa-20020619-branch@73535 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libjava')
40 files changed, 1864 insertions, 262 deletions
diff --git a/libjava/ChangeLog b/libjava/ChangeLog index d4c19813d11..0d62f8f7e26 100644 --- a/libjava/ChangeLog +++ b/libjava/ChangeLog @@ -1,3 +1,205 @@ +2003-11-10 Gary Benson <gbenson@redhat.com> + + * java/sql/Timestamp.java (valueOf): Correctly handle + nanoseconds. + +2003-11-09 Tom Tromey <tromey@redhat.com> + + * java/net/Inet4Address.java (serialVersionUID): Updated. + +2003-11-08 Jeff Sturm <jsturm@one-point.com> + + * gnu/gcj/runtime/FirstThread.java (Klocale, Kcalendar): + New fields. + +2003-11-08 Jeff Sturm <jsturm@one-point.com> + + * java/io/ByteArrayOutputStream.java (resize): + Fix off-by-one error. + +2003-11-08 Bryce McKinlay <bryce@mckinlay.net.nz> + + * gnu/gcj/xlib/XAnyEvent.java (XAnyEvent): Make constructor + public. + +2003-11-06 Mohan Embar <gnustuff@thisiscool.com> + + PR libgcj/12231 + * java/lang/Win32Process.java (hasExited) Changed from + public to private. + (startProcess): Likewise. + (cleanup): Likewise. + * java/lang/natWin32Process.cc (cleanup) Don't close + input, output and error streams. + (ChildProcessPipe): New helper class. + (startProcess): Refactored to use ChildProcessPipe. + Use CREATE_NO_WINDOW when launching child process. + +2003-11-06 Mohan Embar <gnustuff@thisiscool.com> + + * include/win32.h (_Jv_platform_close_on_exec): Changed + signature and declared extern. + * win32.cc (_Jv_platform_close_on_exec): Implemented. + * gnu/java/net/natPlainDatagramSocketImplWin32.cc + (create): Use new signature of _Jv_platform_close_on_exec. + * gnu/java/net/natPlainSocketImplWin32.cc + (create): Eliminated a few typecasts + Use new signature of _Jv_platform_close_on_exec. + (accept): Eliminated a few typecasts + Use new signature of _Jv_platform_close_on_exec. + * java/io/natFileDescriptorWin32.cc (open): Use + _Jv_platform_close_on_exec. + +2003-11-04 Bryce McKinlay <bryce@mckinlay.net.nz> + + * java/lang/natClass.cc (newInstance): Throw InstantiationException + if class has no null-argument constructor. + +2003-10-30 Mohan Embar <gnustuff@thisiscool.com> + + PR libgcj/12647: + * win32-threads.cc (_Jv_CondWait): Respect mutex's + refcount when releasing and reacquiring it. + +2003-10-30 Mohan Embar <gnustuff@thisiscool.com> + + * win32.cc: (dirExists) Internal helper function to + test for directory existence. + (getUserHome) New helper function refactored out + of _Jv_platform_initProperties. Uses USERPROFILE + instead of HOMEDIR and attempts to support Win9X and NT. + (_Jv_platform_initProperties) Use getUserHome. + +2003-10-30 Mohan Embar <gnustuff@thisiscool.com> + + PR libgcj/11521: + * gnu/java/net/natPlainSocketImplWin32.cc + (bind): Don't use SO_REUSEADDR + +2003-10-30 Mohan Embar <gnustuff@thisiscool.com> + + PR libgcj/6652: + * java/io/natFileWin32.cc (getCanonicalPath): Treat "" like ".". + +2003-10-30 Bryce McKinlay <bryce@mckinlay.net.nz> + + * java/lang/reflect/natMethod.cc (_Jv_CallAnyMethodA): Don't use vtable + dispatch for final methods. + +2003-10-30 Thomas Fitzsimmons <fitzsim@redhat.com> + + * jni/gtk-peer/gnu_java_awt_peer_gtk_GtkTextAreaPeer.c (create): Turn on + word wrapping. + +2003-10-29 Thomas Fitzsimmons <fitzsim@redhat.com> + + * jni/gtk-peer/gnu_java_awt_peer_gtk_GtkListPeer.c (getSize): Return + scrolled window's size request. + +2003-10-29 Sascha Brawer <brawer@dandelis.ch> + + * java/awt/geom/CubicCurve2D.java (contains): Docfix for URL of embedded drawing. + * java/awt/geom/QuadCurve2D.java: Likewise. + +2003-10-29 Sascha Brawer <brawer@dandelis.ch> + + * java/awt/geom/CubicCurve2D.java: Added documentation. + * java/awt/geom/QuadCurve2D.java: Likewise. + + * java/awt/geom/doc-files/QuadCurve2D-4.png, + java/awt/geom/doc-files/QuadCurve2D-5.png, + java/awt/geom/doc-files/CubicCurve2D-4.png, + java/awt/geom/doc-files/Cubicurve2D-5.png: New illustrations. + +2003-10-29 Sascha Brawer <brawer@dandelis.ch> + + * java/awt/geom/CubicCurve2D.java (getFlatnessSq): Implement. + (subdivide(CubicCurve2D, CubicCurve2D)): Avoid useless object allocation. + (subdivide(double[],int,double[],int,double[],int)): Implement. + +2003-10-29 Sascha Brawer <brawer@dandelis.ch> + + * java/awt/geom/doc-files/CubicCurve2D-1.png, + java/awt/geom/doc-files/CubicCurve2D-2.png, + java/awt/geom/doc-files/CubicCurve2D-3.png: New illustrations. + +2003-10-29 Ito Kazumitsu <kaz@maczuka.gcd.org> + + * java/text/DecimalFormat.java + (scanFormat) corrected so that '%' may appear in a pattern. + +2003-10-29 Mark Wielaard <mark@klomp.org> + + From Guilhem Lavaux <guilhem.lavaux@free.fr> + * java/text/DateFormat.java (Field): New public static inner class. + * java/text/Format.java (Field): Likewise. + (formatToCharacterIterator): New method. + * java/text/FormatCharacterIterator.java: New file. + +2003-10-29 Mark Wielaard <mark@klomp.org> + + From Guilhem Lavaux <guilhem.lavaux@free.fr> + * java/util/Currency.java: New file. + +2003-10-29 Michael Koch <konqueror@gmx.de> + + * Makefile.am (ordinary_java_source_files): Added + java/text/FormatCharacterIterator.java and java/util/Currency.java. + * Makefile.in: Regenerated. + +2003-10-29 Dalibor Topic <robilad@kaffe.org> + + * gnu/java/beans/IntrospectionIncubator.java (addMethod): Add public + static methods. + +2003-10-29 Julian Dolby <dolby@us.ibm.com> + + * javax/naming/spi/NamingManager.java (getContinuationContext): Call + getObjectInstance() with Object, Name, Context and environment + Hashtable from exception. Call fillInStackTrace() on exception when + rethrown. + * javax/naming/InitialContext.java (lookup(Name)): When a + CannotProceedException is thrown use the ContinuationContext. + (lookup(String)): Likewise. + (close): Clear myProps and defaultInitCtx. + +2003-10-29 Michael Koch <konqueror@gmx.de> + + * java/net/InetAddress.java + (equals): Remove redundant obj == null check. + * java/net/SocketPermission.java + (equals): Likewise. + * java/net/URL.java + (equals): Likewise. + (getURLStreamHandler): Likewise. + +2003-10-29 Michael Koch <konqueror@gmx.de> + + * gnu/java/net/natPlainDatagramSocketImplPosix.cc + (setOption): Directly return if no error occured. + * gnu/java/net/natPlainSocketImplPosix.cc + (setOption): Likewise. + +2003-10-28 Bryce McKinlay <bryce@mckinlay.net.nz> + + * java/lang/natClass.cc (_Jv_LayoutVTableMethods): Always assign a + vtable slot for final methods. Add FIXME comment. + +2003-10-28 David S. Miller <davem@redhat.com> + + * sysdep/sparc/locks.h (__cas_start_atomic): %g0 --> %%g0. + +2003-10-26 Mark Wielaard <mark@klomp.org> + + Reported by Helmer Kraemer <hkraemer@freenet.de> + * java/util/jar/JarInputStream.java (readManifest): Don't call + closeEntry(). + + * java/util/zip/DeflaterOutputStream.java (inbufWrite): New method. + (finish): Use inbufWrite(). + (write(int)): Likewise. + (write(byte[],int,int)): Likewise. + 2003-10-26 Bryce McKinlay <bryce@mckinlay.net.nz> * java/lang/reflect/AccessibleObject.java (secureSetAccessible): diff --git a/libjava/Makefile.am b/libjava/Makefile.am index 91d1647ff9e..569babb7a0c 100644 --- a/libjava/Makefile.am +++ b/libjava/Makefile.am @@ -1942,6 +1942,7 @@ java/util/Collection.java \ java/util/Collections.java \ java/util/Comparator.java \ java/util/ConcurrentModificationException.java \ +java/util/Currency.java \ java/util/Date.java \ java/util/Dictionary.java \ java/util/EmptyStackException.java \ @@ -2580,6 +2581,7 @@ java/text/DecimalFormat.java \ java/text/DecimalFormatSymbols.java \ java/text/FieldPosition.java \ java/text/Format.java \ +java/text/FormatCharacterIterator.java \ java/text/MessageFormat.java \ java/text/NumberFormat.java \ java/text/ParseException.java \ diff --git a/libjava/Makefile.in b/libjava/Makefile.in index d730fd9c0c6..da479ca9f73 100644 --- a/libjava/Makefile.in +++ b/libjava/Makefile.in @@ -1664,6 +1664,7 @@ java/util/Collection.java \ java/util/Collections.java \ java/util/Comparator.java \ java/util/ConcurrentModificationException.java \ +java/util/Currency.java \ java/util/Date.java \ java/util/Dictionary.java \ java/util/EmptyStackException.java \ @@ -2297,6 +2298,7 @@ java/text/DecimalFormat.java \ java/text/DecimalFormatSymbols.java \ java/text/FieldPosition.java \ java/text/Format.java \ +java/text/FormatCharacterIterator.java \ java/text/MessageFormat.java \ java/text/NumberFormat.java \ java/text/ParseException.java \ @@ -3831,6 +3833,7 @@ DEP_FILES = .deps/$(srcdir)/$(CONVERT_DIR)/gen-from-JIS.P \ .deps/java/text/DateFormat.P .deps/java/text/DateFormatSymbols.P \ .deps/java/text/DecimalFormat.P .deps/java/text/DecimalFormatSymbols.P \ .deps/java/text/FieldPosition.P .deps/java/text/Format.P \ +.deps/java/text/FormatCharacterIterator.P \ .deps/java/text/MessageFormat.P .deps/java/text/NumberFormat.P \ .deps/java/text/ParseException.P .deps/java/text/ParsePosition.P \ .deps/java/text/RuleBasedCollator.P .deps/java/text/SimpleDateFormat.P \ @@ -3842,17 +3845,18 @@ DEP_FILES = .deps/$(srcdir)/$(CONVERT_DIR)/gen-from-JIS.P \ .deps/java/util/Calendar.P .deps/java/util/Collection.P \ .deps/java/util/Collections.P .deps/java/util/Comparator.P \ .deps/java/util/ConcurrentModificationException.P \ -.deps/java/util/Date.P .deps/java/util/Dictionary.P \ -.deps/java/util/EmptyStackException.P .deps/java/util/Enumeration.P \ -.deps/java/util/EventListener.P .deps/java/util/EventListenerProxy.P \ -.deps/java/util/EventObject.P .deps/java/util/GregorianCalendar.P \ -.deps/java/util/HashMap.P .deps/java/util/HashSet.P \ -.deps/java/util/Hashtable.P .deps/java/util/IdentityHashMap.P \ -.deps/java/util/Iterator.P .deps/java/util/LinkedHashMap.P \ -.deps/java/util/LinkedHashSet.P .deps/java/util/LinkedList.P \ -.deps/java/util/List.P .deps/java/util/ListIterator.P \ -.deps/java/util/ListResourceBundle.P .deps/java/util/Locale.P \ -.deps/java/util/Map.P .deps/java/util/MissingResourceException.P \ +.deps/java/util/Currency.P .deps/java/util/Date.P \ +.deps/java/util/Dictionary.P .deps/java/util/EmptyStackException.P \ +.deps/java/util/Enumeration.P .deps/java/util/EventListener.P \ +.deps/java/util/EventListenerProxy.P .deps/java/util/EventObject.P \ +.deps/java/util/GregorianCalendar.P .deps/java/util/HashMap.P \ +.deps/java/util/HashSet.P .deps/java/util/Hashtable.P \ +.deps/java/util/IdentityHashMap.P .deps/java/util/Iterator.P \ +.deps/java/util/LinkedHashMap.P .deps/java/util/LinkedHashSet.P \ +.deps/java/util/LinkedList.P .deps/java/util/List.P \ +.deps/java/util/ListIterator.P .deps/java/util/ListResourceBundle.P \ +.deps/java/util/Locale.P .deps/java/util/Map.P \ +.deps/java/util/MissingResourceException.P \ .deps/java/util/NoSuchElementException.P .deps/java/util/Observable.P \ .deps/java/util/Observer.P .deps/java/util/Properties.P \ .deps/java/util/PropertyPermission.P \ diff --git a/libjava/gnu/gcj/runtime/FirstThread.java b/libjava/gnu/gcj/runtime/FirstThread.java index 90515830cfc..9d4b435bba2 100644 --- a/libjava/gnu/gcj/runtime/FirstThread.java +++ b/libjava/gnu/gcj/runtime/FirstThread.java @@ -89,8 +89,10 @@ final class FirstThread extends Thread // classes are linked in. Otherwise bootstrapping fails. These // classes are only referred to via Class.forName(), so we add an // explicit mention of them here. - static final Class Kcert = java.security.cert.Certificate.class; - static final Class Kfile = gnu.java.net.protocol.file.Handler.class; - static final Class Khttp = gnu.java.net.protocol.http.Handler.class; - static final Class Kjar = gnu.java.net.protocol.jar.Handler.class; + static final Class Kcert = java.security.cert.Certificate.class; + static final Class Kfile = gnu.java.net.protocol.file.Handler.class; + static final Class Khttp = gnu.java.net.protocol.http.Handler.class; + static final Class Kjar = gnu.java.net.protocol.jar.Handler.class; + static final Class Klocale = gnu.java.locale.LocaleInformation.class; + static final Class Kcalendar = gnu.java.locale.Calendar.class; } diff --git a/libjava/gnu/gcj/xlib/XAnyEvent.java b/libjava/gnu/gcj/xlib/XAnyEvent.java index df1ad782d79..061d6137b17 100644 --- a/libjava/gnu/gcj/xlib/XAnyEvent.java +++ b/libjava/gnu/gcj/xlib/XAnyEvent.java @@ -58,7 +58,7 @@ public final class XAnyEvent public final static long MASK_SUBSTRUCTURE_NOTIFY = 1L<<19, MASK_SUBSTRUCTURE_REDIRECT = 1L<<20; - XAnyEvent(Display display) + public XAnyEvent(Display display) { this.display = display; init(); diff --git a/libjava/gnu/java/beans/IntrospectionIncubator.java b/libjava/gnu/java/beans/IntrospectionIncubator.java index c853fd7d7af..1b853971aa4 100644 --- a/libjava/gnu/java/beans/IntrospectionIncubator.java +++ b/libjava/gnu/java/beans/IntrospectionIncubator.java @@ -67,7 +67,7 @@ public class IntrospectionIncubator { /* Paving the way for automatic Introspection */ public void addMethod(Method method) { - if(Modifier.isPublic(method.getModifiers()) && !Modifier.isStatic(method.getModifiers())) { + if(Modifier.isPublic(method.getModifiers())) { String name = ClassHelper.getTruncatedName(method.getName()); Class retType = method.getReturnType(); Class[] params = method.getParameterTypes(); diff --git a/libjava/gnu/java/net/natPlainDatagramSocketImplPosix.cc b/libjava/gnu/java/net/natPlainDatagramSocketImplPosix.cc index 65d083c0970..89c50551b03 100644 --- a/libjava/gnu/java/net/natPlainDatagramSocketImplPosix.cc +++ b/libjava/gnu/java/net/natPlainDatagramSocketImplPosix.cc @@ -516,12 +516,12 @@ gnu::java::net::PlainDatagramSocketImpl::setOption (jint optID, if (::setsockopt (native_fd, SOL_SOCKET, SO_BROADCAST, (char *) &val, val_len) != 0) goto error; - break; + return; case _Jv_SO_OOBINLINE_ : throw new ::java::net::SocketException ( JvNewStringUTF ("SO_OOBINLINE: not valid for UDP")); - break; + return; case _Jv_SO_SNDBUF_ : case _Jv_SO_RCVBUF_ : @@ -590,12 +590,12 @@ gnu::java::net::PlainDatagramSocketImpl::setOption (jint optID, case _Jv_IP_MULTICAST_IF2_ : throw new ::java::net::SocketException ( JvNewStringUTF ("IP_MULTICAST_IF2: not yet implemented")); - break; + return; case _Jv_IP_MULTICAST_LOOP_ : throw new ::java::net::SocketException ( JvNewStringUTF ("IP_MULTICAST_LOOP: not yet implemented")); - break; + return; case _Jv_IP_TOS_ : if (::setsockopt (native_fd, SOL_SOCKET, IP_TOS, (char *) &val, diff --git a/libjava/gnu/java/net/natPlainDatagramSocketImplWin32.cc b/libjava/gnu/java/net/natPlainDatagramSocketImplWin32.cc index 1098e6158a8..4a4ec986c61 100644 --- a/libjava/gnu/java/net/natPlainDatagramSocketImplWin32.cc +++ b/libjava/gnu/java/net/natPlainDatagramSocketImplWin32.cc @@ -69,11 +69,14 @@ gnu::java::net::PlainDatagramSocketImpl::create () _Jv_ThrowSocketException (); } - _Jv_platform_close_on_exec (sock); + // Cast this to a HANDLE so we can make + // it non-inheritable via _Jv_platform_close_on_exec. + HANDLE hSocket = (HANDLE) sock; + _Jv_platform_close_on_exec (hSocket); // We use native_fd in place of fd here. From leaving fd null we avoid // the double close problem in FileDescriptor.finalize. - native_fd = (int) sock; + native_fd = (jint) hSocket; } void diff --git a/libjava/gnu/java/net/natPlainSocketImplPosix.cc b/libjava/gnu/java/net/natPlainSocketImplPosix.cc index 8a09f9af595..9a3f7aff9fb 100644 --- a/libjava/gnu/java/net/natPlainSocketImplPosix.cc +++ b/libjava/gnu/java/net/natPlainSocketImplPosix.cc @@ -622,18 +622,18 @@ gnu::java::net::PlainSocketImpl::setOption (jint optID, ::java::lang::Object *va if (::setsockopt (native_fd, SOL_SOCKET, SO_KEEPALIVE, (char *) &val, val_len) != 0) goto error; - break; + return; case _Jv_SO_BROADCAST_ : throw new ::java::net::SocketException (JvNewStringUTF ("SO_BROADCAST not valid for TCP")); - break; + return; case _Jv_SO_OOBINLINE_ : if (::setsockopt (native_fd, SOL_SOCKET, SO_OOBINLINE, (char *) &val, val_len) != 0) goto error; - break; + return; case _Jv_SO_LINGER_ : #ifdef SO_LINGER @@ -676,18 +676,18 @@ gnu::java::net::PlainSocketImpl::setOption (jint optID, ::java::lang::Object *va case _Jv_IP_MULTICAST_IF2_ : throw new ::java::net::SocketException ( JvNewStringUTF ("IP_MULTICAST_IF2: not valid for TCP")); - break; + return; case _Jv_IP_MULTICAST_LOOP_ : throw new ::java::net::SocketException ( JvNewStringUTF ("IP_MULTICAST_LOOP: not valid for TCP")); - break; + return; case _Jv_IP_TOS_ : if (::setsockopt (native_fd, SOL_SOCKET, IP_TOS, (char *) &val, val_len) != 0) goto error; - break; + return; case _Jv_SO_REUSEADDR_ : throw new ::java::net::SocketException ( diff --git a/libjava/gnu/java/net/natPlainSocketImplWin32.cc b/libjava/gnu/java/net/natPlainSocketImplWin32.cc index 411acfa023a..c1c813ec7ad 100644 --- a/libjava/gnu/java/net/natPlainSocketImplWin32.cc +++ b/libjava/gnu/java/net/natPlainSocketImplWin32.cc @@ -45,18 +45,21 @@ union SockAddr void gnu::java::net::PlainSocketImpl::create (jboolean stream) { - int sock = ::socket (AF_INET, stream ? SOCK_STREAM : SOCK_DGRAM, 0); + SOCKET sock = ::socket (AF_INET, stream ? SOCK_STREAM : SOCK_DGRAM, 0); - if (sock == int(INVALID_SOCKET)) + if (sock == INVALID_SOCKET) { _Jv_ThrowIOException (); } - _Jv_platform_close_on_exec (sock); + // Cast this to a HANDLE so we can make + // it non-inheritable via _Jv_platform_close_on_exec. + HANDLE hSocket = (HANDLE) sock; + _Jv_platform_close_on_exec (hSocket); // We use native_fd in place of fd here. From leaving fd null we avoid // the double close problem in FileDescriptor.finalize. - native_fd = sock; + native_fd = (jint) hSocket; } void @@ -67,7 +70,6 @@ gnu::java::net::PlainSocketImpl::bind (::java::net::InetAddress *host, jint lpor jbyteArray haddress = host->addr; jbyte *bytes = elements (haddress); int len = haddress->length; - int i = 1; if (len == 4) { @@ -93,9 +95,6 @@ gnu::java::net::PlainSocketImpl::bind (::java::net::InetAddress *host, jint lpor else throw new ::java::net::SocketException (JvNewStringUTF ("invalid length")); - // Enable SO_REUSEADDR, so that servers can reuse ports left in TIME_WAIT. - ::setsockopt(native_fd, SOL_SOCKET, SO_REUSEADDR, (char *) &i, sizeof(i)); - if (::bind (native_fd, ptr, len) != SOCKET_ERROR) { address = host; @@ -234,7 +233,8 @@ gnu::java::net::PlainSocketImpl::accept (gnu::java::net::PlainSocketImpl *s) { union SockAddr u; socklen_t addrlen = sizeof(u); - int new_socket = 0; + HANDLE hSocket = 0; + SOCKET new_socket = 0; if (timeout > 0) { @@ -249,7 +249,7 @@ gnu::java::net::PlainSocketImpl::accept (gnu::java::net::PlainSocketImpl *s) { new_socket = ::accept (native_fd, (sockaddr*) &u, &addrlen); - if (new_socket != int(INVALID_SOCKET)) + if (new_socket != INVALID_SOCKET) { // This new child socket is nonblocking because the parent // socket became nonblocking via the WSAEventSelect() call, @@ -288,10 +288,13 @@ gnu::java::net::PlainSocketImpl::accept (gnu::java::net::PlainSocketImpl *s) new_socket = ::accept (native_fd, (sockaddr*) &u, &addrlen); } - if (new_socket == int(INVALID_SOCKET)) + if (new_socket == INVALID_SOCKET) goto error; - _Jv_platform_close_on_exec (new_socket); + // Cast this to a HANDLE so we can make + // it non-inheritable via _Jv_platform_close_on_exec. + hSocket = (HANDLE) new_socket; + _Jv_platform_close_on_exec (hSocket); jbyteArray raddr; jint rport; @@ -312,7 +315,7 @@ gnu::java::net::PlainSocketImpl::accept (gnu::java::net::PlainSocketImpl *s) else throw new ::java::net::SocketException (JvNewStringUTF ("invalid family")); - s->native_fd = new_socket; + s->native_fd = (jint) hSocket; s->localport = localport; s->address = new ::java::net::InetAddress (raddr, NULL); s->port = rport; diff --git a/libjava/include/win32.h b/libjava/include/win32.h index e169adf9b28..479ed53f00e 100644 --- a/libjava/include/win32.h +++ b/libjava/include/win32.h @@ -97,11 +97,8 @@ extern jlong _Jv_platform_gettimeofday (); extern int _Jv_select (int n, fd_set *, fd_set *, fd_set *, struct timeval *); extern int _Jv_pipe (int filedes[2]); -inline void -_Jv_platform_close_on_exec (jint) -{ - // Ignore. -} +extern void +_Jv_platform_close_on_exec (HANDLE h); #ifdef JV_HASH_SYNCHRONIZATION /* Suspends the execution of the current thread for the specified diff --git a/libjava/java/awt/geom/CubicCurve2D.java b/libjava/java/awt/geom/CubicCurve2D.java index 2bc0b358b19..1e38d3ada9a 100644 --- a/libjava/java/awt/geom/CubicCurve2D.java +++ b/libjava/java/awt/geom/CubicCurve2D.java @@ -1,5 +1,5 @@ /* CubicCurve2D.java -- represents a parameterized cubic curve in 2-D space - Copyright (C) 2002 Free Software Foundation + Copyright (C) 2002, 2003 Free Software Foundation This file is part of GNU Classpath. @@ -42,31 +42,168 @@ import java.awt.Rectangle; import java.awt.Shape; import java.util.NoSuchElementException; + /** - * STUBS ONLY - * XXX Implement and document. + * A two-dimensional curve that is parameterized with a cubic + * function. + * + * <p><img src="doc-files/CubicCurve2D-1.png" width="350" height="180" + * alt="A drawing of a CubicCurve2D" /> + * + * @author Eric Blake (ebb9@email.byu.edu) + * @author Graydon Hoare (graydon@redhat.com) + * @author Sascha Brawer (brawer@dandelis.ch) + * + * @since 1.2 */ -public abstract class CubicCurve2D implements Shape, Cloneable +public abstract class CubicCurve2D + implements Shape, Cloneable { + /** + * Constructs a new CubicCurve2D. Typical users will want to + * construct instances of a subclass, such as {@link + * CubicCurve2D.Float} or {@link CubicCurve2D.Double}. + */ protected CubicCurve2D() { } + + /** + * Returns the <i>x</i> coordinate of the curve’s start + * point. + */ public abstract double getX1(); + + + /** + * Returns the <i>y</i> coordinate of the curve’s start + * point. + */ public abstract double getY1(); + + + /** + * Returns the curve’s start point. + */ public abstract Point2D getP1(); + + + /** + * Returns the <i>x</i> coordinate of the curve’s first + * control point. + */ public abstract double getCtrlX1(); + + + /** + * Returns the <i>y</i> coordinate of the curve’s first + * control point. + */ public abstract double getCtrlY1(); + + + /** + * Returns the curve’s first control point. + */ public abstract Point2D getCtrlP1(); + + + /** + * Returns the <i>x</i> coordinate of the curve’s second + * control point. + */ public abstract double getCtrlX2(); + + + /** + * Returns the <i>y</i> coordinate of the curve’s second + * control point. + */ public abstract double getCtrlY2(); + + + /** + * Returns the curve’s second control point. + */ public abstract Point2D getCtrlP2(); + + + /** + * Returns the <i>x</i> coordinate of the curve’s end + * point. + */ public abstract double getX2(); + + + /** + * Returns the <i>y</i> coordinate of the curve’s end + * point. + */ public abstract double getY2(); + + + /** + * Returns the curve’s end point. + */ public abstract Point2D getP2(); + + /** + * Changes the curve geometry, separately specifying each coordinate + * value. + * + * <p><img src="doc-files/CubicCurve2D-1.png" width="350" height="180" + * alt="A drawing of a CubicCurve2D" /> + * + * @param x1 the <i>x</i> coordinate of the curve’s new start + * point. + * + * @param y1 the <i>y</i> coordinate of the curve’s new start + * point. + * + * @param cx1 the <i>x</i> coordinate of the curve’s new + * first control point. + * + * @param cy1 the <i>y</i> coordinate of the curve’s new + * first control point. + * + * @param cx2 the <i>x</i> coordinate of the curve’s new + * second control point. + * + * @param cy2 the <i>y</i> coordinate of the curve’s new + * second control point. + * + * @param x2 the <i>x</i> coordinate of the curve’s new end + * point. + * + * @param y2 the <i>y</i> coordinate of the curve’s new end + * point. + */ public abstract void setCurve(double x1, double y1, double cx1, double cy1, double cx2, double cy2, double x2, double y2); + + + /** + * Changes the curve geometry, specifying coordinate values in an + * array. + * + * @param coords an array containing the new coordinate values. The + * <i>x</i> coordinate of the new start point is located at + * <code>coords[offset]</code>, its <i>y</i> coordinate at + * <code>coords[offset + 1]</code>. The <i>x</i> coordinate of the + * new first control point is located at <code>coords[offset + + * 2]</code>, its <i>y</i> coordinate at <code>coords[offset + + * 3]</code>. The <i>x</i> coordinate of the new second control + * point is located at <code>coords[offset + 4]</code>, its <i>y</i> + * coordinate at <code>coords[offset + 5]</code>. The <i>x</i> + * coordinate of the new end point is located at <code>coords[offset + * + 6]</code>, its <i>y</i> coordinate at <code>coords[offset + + * 7]</code>. + * + * @param offset the offset of the first coordinate value in + * <code>coords</code>. + */ public void setCurve(double[] coords, int offset) { setCurve(coords[offset++], coords[offset++], @@ -74,11 +211,51 @@ public abstract class CubicCurve2D implements Shape, Cloneable coords[offset++], coords[offset++], coords[offset++], coords[offset++]); } + + + /** + * Changes the curve geometry, specifying coordinate values in + * separate Point objects. + * + * <p><img src="doc-files/CubicCurve2D-1.png" width="350" height="180" + * alt="A drawing of a CubicCurve2D" /> + * + * <p>The curve does not keep any reference to the passed point + * objects. Therefore, a later change to <code>p1</code>, + * <code>c1</code>, <code>c2</code> or <code>p2</code> will not + * affect the curve geometry. + * + * @param p1 the new start point. + * @param c1 the new first control point. + * @param c2 the new second control point. + * @param p2 the new end point. + */ public void setCurve(Point2D p1, Point2D c1, Point2D c2, Point2D p2) { setCurve(p1.getX(), p1.getY(), c1.getX(), c1.getY(), c2.getX(), c2.getY(), p2.getX(), p2.getY()); } + + + /** + * Changes the curve geometry, specifying coordinate values in an + * array of Point objects. + * + * <p><img src="doc-files/CubicCurve2D-1.png" width="350" height="180" + * alt="A drawing of a CubicCurve2D" /> + * + * <p>The curve does not keep references to the passed point + * objects. Therefore, a later change to the <code>pts</code> array + * or any of its elements will not affect the curve geometry. + * + * @param pts an array containing the points. The new start point + * is located at <code>pts[offset]</code>, the new first control + * point at <code>pts[offset + 1]</code>, the new second control + * point at <code>pts[offset + 2]</code>, and the new end point + * at <code>pts[offset + 3]</code>. + * + * @param offset the offset of the start point in <code>pts</code>. + */ public void setCurve(Point2D[] pts, int offset) { setCurve(pts[offset].getX(), pts[offset++].getY(), @@ -86,24 +263,115 @@ public abstract class CubicCurve2D implements Shape, Cloneable pts[offset].getX(), pts[offset++].getY(), pts[offset].getX(), pts[offset++].getY()); } + + + /** + * Changes the curve geometry to that of another curve. + * + * @param c the curve whose coordinates will be copied. + */ public void setCurve(CubicCurve2D c) { setCurve(c.getX1(), c.getY1(), c.getCtrlX1(), c.getCtrlY1(), c.getCtrlX2(), c.getCtrlY2(), c.getX2(), c.getY2()); } + + + /** + * Calculates the squared flatness of a cubic curve, directly + * specifying each coordinate value. The flatness is the maximal + * distance of a control point to the line between start and end + * point. + * + * <p><img src="doc-files/CubicCurve2D-4.png" width="350" height="180" + * alt="A drawing that illustrates the flatness" /> + * + * <p>In the above drawing, the straight line connecting start point + * P1 and end point P2 is depicted in gray. In comparison to C1, + * control point C2 is father away from the gray line. Therefore, + * the result will be the square of the distance between C2 and the + * gray line, i.e. the squared length of the red line. + * + * @param x1 the <i>x</i> coordinate of the start point P1. + * @param y1 the <i>y</i> coordinate of the start point P1. + * @param cx1 the <i>x</i> coordinate of the first control point C1. + * @param cy1 the <i>y</i> coordinate of the first control point C1. + * @param cx2 the <i>x</i> coordinate of the second control point C2. + * @param cy2 the <i>y</i> coordinate of the second control point C2. + * @param x2 the <i>x</i> coordinate of the end point P2. + * @param y2 the <i>y</i> coordinate of the end point P2. + */ public static double getFlatnessSq(double x1, double y1, double cx1, double cy1, double cx2, double cy2, double x2, double y2) { - // XXX Implement. - throw new Error("not implemented"); + return Math.max(Line2D.ptSegDistSq(x1, y1, x2, y2, cx1, cy1), + Line2D.ptSegDistSq(x1, y1, x2, y2, cx2, cy2)); } + + + /** + * Calculates the flatness of a cubic curve, directly specifying + * each coordinate value. The flatness is the maximal distance of a + * control point to the line between start and end point. + * + * <p><img src="doc-files/CubicCurve2D-4.png" width="350" height="180" + * alt="A drawing that illustrates the flatness" /> + * + * <p>In the above drawing, the straight line connecting start point + * P1 and end point P2 is depicted in gray. In comparison to C1, + * control point C2 is father away from the gray line. Therefore, + * the result will be the distance between C2 and the gray line, + * i.e. the length of the red line. + * + * @param x1 the <i>x</i> coordinate of the start point P1. + * @param y1 the <i>y</i> coordinate of the start point P1. + * @param cx1 the <i>x</i> coordinate of the first control point C1. + * @param cy1 the <i>y</i> coordinate of the first control point C1. + * @param cx2 the <i>x</i> coordinate of the second control point C2. + * @param cy2 the <i>y</i> coordinate of the second control point C2. + * @param x2 the <i>x</i> coordinate of the end point P2. + * @param y2 the <i>y</i> coordinate of the end point P2. + */ public static double getFlatness(double x1, double y1, double cx1, double cy1, double cx2, double cy2, double x2, double y2) { return Math.sqrt(getFlatnessSq(x1, y1, cx1, cy1, cx2, cy2, x2, y2)); } + + + /** + * Calculates the squared flatness of a cubic curve, specifying the + * coordinate values in an array. The flatness is the maximal + * distance of a control point to the line between start and end + * point. + * + * <p><img src="doc-files/CubicCurve2D-4.png" width="350" height="180" + * alt="A drawing that illustrates the flatness" /> + * + * <p>In the above drawing, the straight line connecting start point + * P1 and end point P2 is depicted in gray. In comparison to C1, + * control point C2 is father away from the gray line. Therefore, + * the result will be the square of the distance between C2 and the + * gray line, i.e. the squared length of the red line. + * + * @param coords an array containing the coordinate values. The + * <i>x</i> coordinate of the start point P1 is located at + * <code>coords[offset]</code>, its <i>y</i> coordinate at + * <code>coords[offset + 1]</code>. The <i>x</i> coordinate of the + * first control point C1 is located at <code>coords[offset + + * 2]</code>, its <i>y</i> coordinate at <code>coords[offset + + * 3]</code>. The <i>x</i> coordinate of the second control point C2 + * is located at <code>coords[offset + 4]</code>, its <i>y</i> + * coordinate at <code>coords[offset + 5]</code>. The <i>x</i> + * coordinate of the end point P2 is located at <code>coords[offset + * + 6]</code>, its <i>y</i> coordinate at <code>coords[offset + + * 7]</code>. + * + * @param offset the offset of the first coordinate value in + * <code>coords</code>. + */ public static double getFlatnessSq(double[] coords, int offset) { return getFlatnessSq(coords[offset++], coords[offset++], @@ -111,6 +379,39 @@ public abstract class CubicCurve2D implements Shape, Cloneable coords[offset++], coords[offset++], coords[offset++], coords[offset++]); } + + + /** + * Calculates the flatness of a cubic curve, specifying the + * coordinate values in an array. The flatness is the maximal + * distance of a control point to the line between start and end + * point. + * + * <p><img src="doc-files/CubicCurve2D-4.png" width="350" height="180" + * alt="A drawing that illustrates the flatness" /> + * + * <p>In the above drawing, the straight line connecting start point + * P1 and end point P2 is depicted in gray. In comparison to C1, + * control point C2 is father away from the gray line. Therefore, + * the result will be the distance between C2 and the gray line, + * i.e. the length of the red line. + * + * @param coords an array containing the coordinate values. The + * <i>x</i> coordinate of the start point P1 is located at + * <code>coords[offset]</code>, its <i>y</i> coordinate at + * <code>coords[offset + 1]</code>. The <i>x</i> coordinate of the + * first control point C1 is located at <code>coords[offset + + * 2]</code>, its <i>y</i> coordinate at <code>coords[offset + + * 3]</code>. The <i>x</i> coordinate of the second control point C2 + * is located at <code>coords[offset + 4]</code>, its <i>y</i> + * coordinate at <code>coords[offset + 5]</code>. The <i>x</i> + * coordinate of the end point P2 is located at <code>coords[offset + * + 6]</code>, its <i>y</i> coordinate at <code>coords[offset + + * 7]</code>. + * + * @param offset the offset of the first coordinate value in + * <code>coords</code>. + */ public static double getFlatness(double[] coords, int offset) { return Math.sqrt(getFlatnessSq(coords[offset++], coords[offset++], @@ -118,11 +419,43 @@ public abstract class CubicCurve2D implements Shape, Cloneable coords[offset++], coords[offset++], coords[offset++], coords[offset++])); } + + + /** + * Calculates the squared flatness of this curve. The flatness is + * the maximal distance of a control point to the line between start + * and end point. + * + * <p><img src="doc-files/CubicCurve2D-4.png" width="350" height="180" + * alt="A drawing that illustrates the flatness" /> + * + * <p>In the above drawing, the straight line connecting start point + * P1 and end point P2 is depicted in gray. In comparison to C1, + * control point C2 is father away from the gray line. Therefore, + * the result will be the square of the distance between C2 and the + * gray line, i.e. the squared length of the red line. + */ public double getFlatnessSq() { return getFlatnessSq(getX1(), getY1(), getCtrlX1(), getCtrlY1(), getCtrlX2(), getCtrlY2(), getX2(), getY2()); } + + + /** + * Calculates the flatness of this curve. The flatness is the + * maximal distance of a control point to the line between start and + * end point. + * + * <p><img src="doc-files/CubicCurve2D-4.png" width="350" height="180" + * alt="A drawing that illustrates the flatness" /> + * + * <p>In the above drawing, the straight line connecting start point + * P1 and end point P2 is depicted in gray. In comparison to C1, + * control point C2 is father away from the gray line. Therefore, + * the result will be the distance between C2 and the gray line, + * i.e. the length of the red line. + */ public double getFlatness() { return Math.sqrt(getFlatnessSq(getX1(), getY1(), getCtrlX1(), @@ -130,75 +463,266 @@ public abstract class CubicCurve2D implements Shape, Cloneable getX2(), getY2())); } - public void subdivide(CubicCurve2D l, CubicCurve2D r) + + /** + * Subdivides this curve into two halves. + * + * <p><img src="doc-files/CubicCurve2D-3.png" width="700" + * height="180" alt="A drawing that illustrates the effects of + * subdividing a CubicCurve2D" /> + * + * @param left a curve whose geometry will be set to the left half + * of this curve, or <code>null</code> if the caller is not + * interested in the left half. + * + * @param right a curve whose geometry will be set to the right half + * of this curve, or <code>null</code> if the caller is not + * interested in the right half. + */ + public void subdivide(CubicCurve2D left, CubicCurve2D right) { - if (l == null) - l = new CubicCurve2D.Double(); - if (r == null) - r = new CubicCurve2D.Double(); // Use empty slots at end to share single array. double[] d = new double[] { getX1(), getY1(), getCtrlX1(), getCtrlY1(), getCtrlX2(), getCtrlY2(), getX2(), getY2(), 0, 0, 0, 0, 0, 0 }; subdivide(d, 0, d, 0, d, 6); - l.setCurve(d, 0); - r.setCurve(d, 6); + if (left != null) + left.setCurve(d, 0); + if (right != null) + right.setCurve(d, 6); } + + + /** + * Subdivides a cubic curve into two halves. + * + * <p><img src="doc-files/CubicCurve2D-3.png" width="700" + * height="180" alt="A drawing that illustrates the effects of + * subdividing a CubicCurve2D" /> + * + * @param src the curve to be subdivided. + * + * @param left a curve whose geometry will be set to the left half + * of <code>src</code>, or <code>null</code> if the caller is not + * interested in the left half. + * + * @param right a curve whose geometry will be set to the right half + * of <code>src</code>, or <code>null</code> if the caller is not + * interested in the right half. + */ public static void subdivide(CubicCurve2D src, - CubicCurve2D l, CubicCurve2D r) + CubicCurve2D left, CubicCurve2D right) { - src.subdivide(l, r); + src.subdivide(left, right); } + + + /** + * Subdivides a cubic curve into two halves, passing all coordinates + * in an array. + * + * <p><img src="doc-files/CubicCurve2D-3.png" width="700" + * height="180" alt="A drawing that illustrates the effects of + * subdividing a CubicCurve2D" /> + * + * <p>The left end point and the right start point will always be + * identical. Memory-concious programmers thus may want to pass the + * same array for both <code>left</code> and <code>right</code>, and + * set <code>rightOff</code> to <code>leftOff + 6</code>. + * + * @param src an array containing the coordinates of the curve to be + * subdivided. The <i>x</i> coordinate of the start point P1 is + * located at <code>src[srcOff]</code>, its <i>y</i> at + * <code>src[srcOff + 1]</code>. The <i>x</i> coordinate of the + * first control point C1 is located at <code>src[srcOff + + * 2]</code>, its <i>y</i> at <code>src[srcOff + 3]</code>. The + * <i>x</i> coordinate of the second control point C2 is located at + * <code>src[srcOff + 4]</code>, its <i>y</i> at <code>src[srcOff + + * 5]</code>. The <i>x</i> coordinate of the end point is located at + * <code>src[srcOff + 6]</code>, its <i>y</i> at <code>src[srcOff + + * 7]</code>. + * + * @param srcOff an offset into <code>src</code>, specifying + * the index of the start point’s <i>x</i> coordinate. + * + * @param left an array that will receive the coordinates of the + * left half of <code>src</code>. It is acceptable to pass + * <code>src</code>. A caller who is not interested in the left half + * can pass <code>null</code>. + * + * @param leftOff an offset into <code>left</code>, specifying the + * index where the start point’s <i>x</i> coordinate will be + * stored. + * + * @param right an array that will receive the coordinates of the + * right half of <code>src</code>. It is acceptable to pass + * <code>src</code> or <code>left</code>. A caller who is not + * interested in the right half can pass <code>null</code>. + * + * @param rightOff an offset into <code>right</code>, specifying the + * index where the start point’s <i>x</i> coordinate will be + * stored. + */ public static void subdivide(double[] src, int srcOff, double[] left, int leftOff, double[] right, int rightOff) { - // XXX Implement. - throw new Error("not implemented"); + // To understand this code, please have a look at the image + // "CubicCurve2D-3.png" in the sub-directory "doc-files". + double src_C1_x, src_C1_y, src_C2_x, src_C2_y; + double left_P1_x, left_P1_y; + double left_C1_x, left_C1_y, left_C2_x, left_C2_y; + double right_C1_x, right_C1_y, right_C2_x, right_C2_y; + double right_P2_x, right_P2_y; + double Mid_x, Mid_y; // Mid = left.P2 = right.P1 + + left_P1_x = src[srcOff]; + left_P1_y = src[srcOff + 1]; + src_C1_x = src[srcOff + 2]; + src_C1_y = src[srcOff + 3]; + src_C2_x = src[srcOff + 4]; + src_C2_y = src[srcOff + 5]; + right_P2_x = src[srcOff + 6]; + right_P2_y = src[srcOff + 7]; + + left_C1_x = (left_P1_x + src_C1_x) / 2; + left_C1_y = (left_P1_y + src_C1_y) / 2; + right_C2_x = (right_P2_x + src_C2_x) / 2; + right_C2_y = (right_P2_y + src_C2_y) / 2; + Mid_x = (src_C1_x + src_C2_x) / 2; + Mid_y = (src_C1_y + src_C2_y) / 2; + left_C2_x = (left_C1_x + Mid_x) / 2; + left_C2_y = (left_C1_y + Mid_y) / 2; + right_C1_x = (Mid_x + right_C2_x) / 2; + right_C1_y = (Mid_y + right_C2_y) / 2; + Mid_x = (left_C2_x + right_C1_x) / 2; + Mid_y = (left_C2_y + right_C1_y) / 2; + + if (left != null) + { + left[leftOff] = left_P1_x; + left[leftOff + 1] = left_P1_y; + left[leftOff + 2] = left_C1_x; + left[leftOff + 3] = left_C1_y; + left[leftOff + 4] = left_C2_x; + left[leftOff + 5] = left_C2_y; + left[leftOff + 6] = Mid_x; + left[leftOff + 7] = Mid_y; + } + + if (right != null) + { + right[rightOff] = Mid_x; + right[rightOff + 1] = Mid_y; + right[rightOff + 2] = right_C1_x; + right[rightOff + 3] = right_C1_y; + right[rightOff + 4] = right_C2_x; + right[rightOff + 5] = right_C2_y; + right[rightOff + 6] = right_P2_x; + right[rightOff + 7] = right_P2_y; + } } + + public static int solveCubic(double[] eqn) { return solveCubic(eqn, eqn); } + + public static int solveCubic(double[] eqn, double[] res) { - if (eqn[3] == 0) + double a, b, c, q, r, Q, R; + + double c3 = eqn[3]; + if (c3 == 0) return QuadCurve2D.solveQuadratic(eqn, res); - // XXX Implement. - throw new Error("not implemented"); + + // Divide the equation by the cubic coefficient. + c = eqn[0] / c3; + b = eqn[1] / c3; + a = eqn[2] / c3; + + // We now need to solve x^3 + ax^2 + bx + c = 0. + throw new Error("not implemented"); // FIXME } + + /** + * Determines whether a position lies inside the area that is bounded + * by the curve and the straight line connecting its end points. + * + * <p><img src="doc-files/CubicCurve2D-5.png" width="350" height="180" + * alt="A drawing of the area spanned by the curve" /> + * + * <p>The above drawing illustrates in which area points are + * considered “contained” in a CubicCurve2D. + */ public boolean contains(double x, double y) { // XXX Implement. throw new Error("not implemented"); } + + + /** + * Determines whether a point lies inside the area that is bounded + * by the curve and the straight line connecting its end points. + * + * <p><img src="doc-files/CubicCurve2D-5.png" width="350" height="180" + * alt="A drawing of the area spanned by the curve" /> + * + * <p>The above drawing illustrates in which area points are + * considered “contained” in a CubicCurve2D. + */ public boolean contains(Point2D p) { return contains(p.getX(), p.getY()); } + + public boolean intersects(double x, double y, double w, double h) { // XXX Implement. throw new Error("not implemented"); } + + public boolean intersects(Rectangle2D r) { return intersects(r.getX(), r.getY(), r.getWidth(), r.getHeight()); } + + public boolean contains(double x, double y, double w, double h) { // XXX Implement. throw new Error("not implemented"); } + + public boolean contains(Rectangle2D r) { return contains(r.getX(), r.getY(), r.getWidth(), r.getHeight()); } + + + /** + * Determines the smallest rectangle that encloses the + * curve’s start, end and control points. As the illustration + * below shows, the invisible control points may cause the bounds to + * be much larger than the area that is actually covered by the + * curve. + * + * <p><img src="doc-files/CubicCurve2D-2.png" width="350" height="180" + * alt="An illustration of the bounds of a CubicCurve2D" /> + */ public Rectangle getBounds() { return getBounds2D().getBounds(); } + + public PathIterator getPathIterator(final AffineTransform at) { return new PathIterator() @@ -276,47 +800,135 @@ public abstract class CubicCurve2D implements Shape, Cloneable } }; } + + public PathIterator getPathIterator(AffineTransform at, double flatness) { return new FlatteningPathIterator(getPathIterator(at), flatness); } + /** - * Create a new curve of the same run-time type with the same contents as - * this one. + * Create a new curve with the same contents as this one. * - * @return the clone + * @return the clone. */ public Object clone() { try - { - return super.clone(); - } + { + return super.clone(); + } catch (CloneNotSupportedException e) - { - throw (Error) new InternalError().initCause(e); // Impossible - } + { + throw (Error) new InternalError().initCause(e); // Impossible + } } + /** - * STUBS ONLY + * A two-dimensional curve that is parameterized with a cubic + * function and stores coordinate values in double-precision + * floating-point format. + * + * @see CubicCurve2D.Float + * + * @author Eric Blake (ebb9@email.byu.edu) + * @author Sascha Brawer (brawer@dandelis.ch) */ - public static class Double extends CubicCurve2D + public static class Double + extends CubicCurve2D { + /** + * The <i>x</i> coordinate of the curve’s start point. + */ public double x1; + + + /** + * The <i>y</i> coordinate of the curve’s start point. + */ public double y1; + + + /** + * The <i>x</i> coordinate of the curve’s first control point. + */ public double ctrlx1; + + + /** + * The <i>y</i> coordinate of the curve’s first control point. + */ public double ctrly1; + + + /** + * The <i>x</i> coordinate of the curve’s second control point. + */ public double ctrlx2; + + + /** + * The <i>y</i> coordinate of the curve’s second control point. + */ public double ctrly2; + + + /** + * The <i>x</i> coordinate of the curve’s end point. + */ public double x2; + + + /** + * The <i>y</i> coordinate of the curve’s end point. + */ public double y2; + + /** + * Constructs a new CubicCurve2D that stores its coordinate values + * in double-precision floating-point format. All points are + * initially at position (0, 0). + */ public Double() { } + + /** + * Constructs a new CubicCurve2D that stores its coordinate values + * in double-precision floating-point format, specifying the + * initial position of each point. + * + * <p><img src="doc-files/CubicCurve2D-1.png" width="350" height="180" + * alt="A drawing of a CubicCurve2D" /> + * + * @param x1 the <i>x</i> coordinate of the curve’s start + * point. + * + * @param y1 the <i>y</i> coordinate of the curve’s start + * point. + * + * @param cx1 the <i>x</i> coordinate of the curve’s first + * control point. + * + * @param cy1 the <i>y</i> coordinate of the curve’s first + * control point. + * + * @param cx2 the <i>x</i> coordinate of the curve’s second + * control point. + * + * @param cy2 the <i>y</i> coordinate of the curve’s second + * control point. + * + * @param x2 the <i>x</i> coordinate of the curve’s end + * point. + * + * @param y2 the <i>y</i> coordinate of the curve’s end + * point. + */ public Double(double x1, double y1, double cx1, double cy1, double cx2, double cy2, double x2, double y2) { @@ -330,58 +942,154 @@ public abstract class CubicCurve2D implements Shape, Cloneable this.y2 = y2; } + + /** + * Returns the <i>x</i> coordinate of the curve’s start + * point. + */ public double getX1() { return x1; } + + + /** + * Returns the <i>y</i> coordinate of the curve’s start + * point. + */ public double getY1() { return y1; } + + + /** + * Returns the curve’s start point. + */ public Point2D getP1() { return new Point2D.Double(x1, y1); } + + /** + * Returns the <i>x</i> coordinate of the curve’s first + * control point. + */ public double getCtrlX1() { return ctrlx1; } + + + /** + * Returns the <i>y</i> coordinate of the curve’s first + * control point. + */ public double getCtrlY1() { return ctrly1; } + + + /** + * Returns the curve’s first control point. + */ public Point2D getCtrlP1() { return new Point2D.Double(ctrlx1, ctrly1); } + + /** + * Returns the <i>x</i> coordinate of the curve’s second + * control point. + */ public double getCtrlX2() { return ctrlx2; } + + + /** + * Returns the <i>y</i> coordinate of the curve’s second + * control point. + */ public double getCtrlY2() { return ctrly2; } + + + /** + * Returns the curve’s second control point. + */ public Point2D getCtrlP2() { return new Point2D.Double(ctrlx2, ctrly2); } + + /** + * Returns the <i>x</i> coordinate of the curve’s end + * point. + */ public double getX2() { return x2; } + + + /** + * Returns the <i>y</i> coordinate of the curve’s end + * point. + */ public double getY2() { return y2; } + + + /** + * Returns the curve’s end point. + */ public Point2D getP2() { return new Point2D.Double(x2, y2); } + + /** + * Changes the curve geometry, separately specifying each coordinate + * value. + * + * <p><img src="doc-files/CubicCurve2D-1.png" width="350" height="180" + * alt="A drawing of a CubicCurve2D" /> + * + * @param x1 the <i>x</i> coordinate of the curve’s new start + * point. + * + * @param y1 the <i>y</i> coordinate of the curve’s new start + * point. + * + * @param cx1 the <i>x</i> coordinate of the curve’s new + * first control point. + * + * @param cy1 the <i>y</i> coordinate of the curve’s new + * first control point. + * + * @param cx2 the <i>x</i> coordinate of the curve’s new + * second control point. + * + * @param cy2 the <i>y</i> coordinate of the curve’s new + * second control point. + * + * @param x2 the <i>x</i> coordinate of the curve’s new end + * point. + * + * @param y2 the <i>y</i> coordinate of the curve’s new end + * point. + */ public void setCurve(double x1, double y1, double cx1, double cy1, double cx2, double cy2, double x2, double y2) { @@ -394,6 +1102,18 @@ public abstract class CubicCurve2D implements Shape, Cloneable this.x2 = x2; this.y2 = y2; } + + + /** + * Determines the smallest rectangle that encloses the + * curve’s start, end and control points. As the + * illustration below shows, the invisible control points may cause + * the bounds to be much larger than the area that is actually + * covered by the curve. + * + * <p><img src="doc-files/CubicCurve2D-2.png" width="350" height="180" + * alt="An illustration of the bounds of a CubicCurve2D" /> + */ public Rectangle2D getBounds2D() { double nx1 = Math.min(Math.min(x1, ctrlx1), Math.min(ctrlx2, x2)); @@ -402,26 +1122,112 @@ public abstract class CubicCurve2D implements Shape, Cloneable double ny2 = Math.max(Math.max(y1, ctrly1), Math.max(ctrly2, y2)); return new Rectangle2D.Double(nx1, ny1, nx2 - nx1, ny2 - ny1); } - } // class Double + } + /** - * STUBS ONLY + * A two-dimensional curve that is parameterized with a cubic + * function and stores coordinate values in single-precision + * floating-point format. + * + * @see CubicCurve2D.Float + * + * @author Eric Blake (ebb9@email.byu.edu) + * @author Sascha Brawer (brawer@dandelis.ch) */ - public static class Float extends CubicCurve2D + public static class Float + extends CubicCurve2D { + /** + * The <i>x</i> coordinate of the curve’s start point. + */ public float x1; + + + /** + * The <i>y</i> coordinate of the curve’s start point. + */ public float y1; + + + /** + * The <i>x</i> coordinate of the curve’s first control point. + */ public float ctrlx1; + + + /** + * The <i>y</i> coordinate of the curve’s first control point. + */ public float ctrly1; + + + /** + * The <i>x</i> coordinate of the curve’s second control point. + */ public float ctrlx2; + + + /** + * The <i>y</i> coordinate of the curve’s second control point. + */ public float ctrly2; + + + /** + * The <i>x</i> coordinate of the curve’s end point. + */ public float x2; + + + /** + * The <i>y</i> coordinate of the curve’s end point. + */ public float y2; + + /** + * Constructs a new CubicCurve2D that stores its coordinate values + * in single-precision floating-point format. All points are + * initially at position (0, 0). + */ public Float() { } + + /** + * Constructs a new CubicCurve2D that stores its coordinate values + * in single-precision floating-point format, specifying the + * initial position of each point. + * + * <p><img src="doc-files/CubicCurve2D-1.png" width="350" height="180" + * alt="A drawing of a CubicCurve2D" /> + * + * @param x1 the <i>x</i> coordinate of the curve’s start + * point. + * + * @param y1 the <i>y</i> coordinate of the curve’s start + * point. + * + * @param cx1 the <i>x</i> coordinate of the curve’s first + * control point. + * + * @param cy1 the <i>y</i> coordinate of the curve’s first + * control point. + * + * @param cx2 the <i>x</i> coordinate of the curve’s second + * control point. + * + * @param cy2 the <i>y</i> coordinate of the curve’s second + * control point. + * + * @param x2 the <i>x</i> coordinate of the curve’s end + * point. + * + * @param y2 the <i>y</i> coordinate of the curve’s end + * point. + */ public Float(float x1, float y1, float cx1, float cy1, float cx2, float cy2, float x2, float y2) { @@ -435,58 +1241,154 @@ public abstract class CubicCurve2D implements Shape, Cloneable this.y2 = y2; } + + /** + * Returns the <i>x</i> coordinate of the curve’s start + * point. + */ public double getX1() { return x1; } + + + /** + * Returns the <i>y</i> coordinate of the curve’s start + * point. + */ public double getY1() { return y1; } + + + /** + * Returns the curve’s start point. + */ public Point2D getP1() { return new Point2D.Float(x1, y1); } + + /** + * Returns the <i>x</i> coordinate of the curve’s first + * control point. + */ public double getCtrlX1() { return ctrlx1; } + + + /** + * Returns the <i>y</i> coordinate of the curve’s first + * control point. + */ public double getCtrlY1() { return ctrly1; } + + + /** + * Returns the curve’s first control point. + */ public Point2D getCtrlP1() { return new Point2D.Float(ctrlx1, ctrly1); } + + /** + * Returns the <i>s</i> coordinate of the curve’s second + * control point. + */ public double getCtrlX2() { return ctrlx2; } + + + /** + * Returns the <i>y</i> coordinate of the curve’s second + * control point. + */ public double getCtrlY2() { return ctrly2; } + + + /** + * Returns the curve’s second control point. + */ public Point2D getCtrlP2() { return new Point2D.Float(ctrlx2, ctrly2); } + + /** + * Returns the <i>x</i> coordinate of the curve’s end + * point. + */ public double getX2() { return x2; } + + + /** + * Returns the <i>y</i> coordinate of the curve’s end + * point. + */ public double getY2() { return y2; } + + + /** + * Returns the curve’s end point. + */ public Point2D getP2() { return new Point2D.Float(x2, y2); } + + /** + * Changes the curve geometry, separately specifying each coordinate + * value as a double-precision floating-point number. + * + * <p><img src="doc-files/CubicCurve2D-1.png" width="350" height="180" + * alt="A drawing of a CubicCurve2D" /> + * + * @param x1 the <i>x</i> coordinate of the curve’s new start + * point. + * + * @param y1 the <i>y</i> coordinate of the curve’s new start + * point. + * + * @param cx1 the <i>x</i> coordinate of the curve’s new + * first control point. + * + * @param cy1 the <i>y</i> coordinate of the curve’s new + * first control point. + * + * @param cx2 the <i>x</i> coordinate of the curve’s new + * second control point. + * + * @param cy2 the <i>y</i> coordinate of the curve’s new + * second control point. + * + * @param x2 the <i>x</i> coordinate of the curve’s new end + * point. + * + * @param y2 the <i>y</i> coordinate of the curve’s new end + * point. + */ public void setCurve(double x1, double y1, double cx1, double cy1, double cx2, double cy2, double x2, double y2) { @@ -499,6 +1401,39 @@ public abstract class CubicCurve2D implements Shape, Cloneable this.x2 = (float) x2; this.y2 = (float) y2; } + + + /** + * Changes the curve geometry, separately specifying each coordinate + * value as a single-precision floating-point number. + * + * <p><img src="doc-files/CubicCurve2D-1.png" width="350" height="180" + * alt="A drawing of a CubicCurve2D" /> + * + * @param x1 the <i>x</i> coordinate of the curve’s new start + * point. + * + * @param y1 the <i>y</i> coordinate of the curve’s new start + * point. + * + * @param cx1 the <i>x</i> coordinate of the curve’s new + * first control point. + * + * @param cy1 the <i>y</i> coordinate of the curve’s new + * first control point. + * + * @param cx2 the <i>x</i> coordinate of the curve’s new + * second control point. + * + * @param cy2 the <i>y</i> coordinate of the curve’s new + * second control point. + * + * @param x2 the <i>x</i> coordinate of the curve’s new end + * point. + * + * @param y2 the <i>y</i> coordinate of the curve’s new end + * point. + */ public void setCurve(float x1, float y1, float cx1, float cy1, float cx2, float cy2, float x2, float y2) { @@ -511,6 +1446,18 @@ public abstract class CubicCurve2D implements Shape, Cloneable this.x2 = x2; this.y2 = y2; } + + + /** + * Determines the smallest rectangle that encloses the + * curve’s start, end and control points. As the + * illustration below shows, the invisible control points may cause + * the bounds to be much larger than the area that is actually + * covered by the curve. + * + * <p><img src="doc-files/CubicCurve2D-2.png" width="350" height="180" + * alt="An illustration of the bounds of a CubicCurve2D" /> + */ public Rectangle2D getBounds2D() { float nx1 = (float) Math.min(Math.min(x1, ctrlx1), Math.min(ctrlx2, x2)); @@ -519,5 +1466,5 @@ public abstract class CubicCurve2D implements Shape, Cloneable float ny2 = (float) Math.max(Math.max(y1, ctrly1), Math.max(ctrly2, y2)); return new Rectangle2D.Float(nx1, ny1, nx2 - nx1, ny2 - ny1); } - } // class Float -} // class CubicCurve2D + } +} diff --git a/libjava/java/awt/geom/QuadCurve2D.java b/libjava/java/awt/geom/QuadCurve2D.java index e737ec1a470..5bc63e6c6cf 100644 --- a/libjava/java/awt/geom/QuadCurve2D.java +++ b/libjava/java/awt/geom/QuadCurve2D.java @@ -51,6 +51,7 @@ import java.util.NoSuchElementException; * alt="A drawing of a QuadCurve2D" /> * * @author Eric Blake (ebb9@email.byu.edu) + * @author Graydon Hoare (graydon@redhat.com) * @author Sascha Brawer (brawer@dandelis.ch) * * @since 1.2 @@ -129,7 +130,8 @@ public abstract class QuadCurve2D /** - * Changes the geometry of the curve. + * Changes the curve geometry, separately specifying each coordinate + * value. * * @param x1 the <i>x</i> coordinate of the curve’s new start * point. @@ -153,6 +155,23 @@ public abstract class QuadCurve2D double x2, double y2); + /** + * Changes the curve geometry, passing coordinate values in an + * array. + * + * @param coords an array containing the new coordinate values. The + * <i>x</i> coordinate of the new start point is located at + * <code>coords[offset]</code>, its <i>y</i> coordinate at + * <code>coords[offset + 1]</code>. The <i>x</i> coordinate of the + * new control point is located at <code>coords[offset + 2]</code>, + * its <i>y</i> coordinate at <code>coords[offset + 3]</code>. The + * <i>x</i> coordinate of the new end point is located at + * <code>coords[offset + 4]</code>, its <i>y</i> coordinate at + * <code>coords[offset + 5]</code>. + * + * @param offset the offset of the first coordinate value in + * <code>coords</code>. + */ public void setCurve(double[] coords, int offset) { setCurve(coords[offset++], coords[offset++], @@ -161,6 +180,22 @@ public abstract class QuadCurve2D } + /** + * Changes the curve geometry, specifying coordinate values in + * separate Point objects. + * + * <p><img src="doc-files/QuadCurve2D-1.png" width="350" height="180" + * alt="A drawing of a QuadCurve2D" /> + * + * <p>The curve does not keep any reference to the passed point + * objects. Therefore, a later change to <code>p1</code>, + * <code>c</code> <code>p2</code> will not affect the curve + * geometry. + * + * @param p1 the new start point. + * @param c the new control point. + * @param p2 the new end point. + */ public void setCurve(Point2D p1, Point2D c, Point2D p2) { setCurve(p1.getX(), p1.getY(), c.getX(), c.getY(), @@ -168,11 +203,29 @@ public abstract class QuadCurve2D } + /** + * Changes the curve geometry, specifying coordinate values in an + * array of Point objects. + * + * <p><img src="doc-files/QuadCurve2D-1.png" width="350" height="180" + * alt="A drawing of a QuadCurve2D" /> + * + * <p>The curve does not keep references to the passed point + * objects. Therefore, a later change to the <code>pts</code> array + * or any of its elements will not affect the curve geometry. + * + * @param pts an array containing the points. The new start point + * is located at <code>pts[offset]</code>, the new control + * point at <code>pts[offset + 1]</code>, and the new end point + * at <code>pts[offset + 2]</code>. + * + * @param offset the offset of the start point in <code>pts</code>. + */ public void setCurve(Point2D[] pts, int offset) { - setCurve(pts[offset].getX(), pts[offset++].getY(), - pts[offset].getX(), pts[offset++].getY(), - pts[offset].getX(), pts[offset++].getY()); + setCurve(pts[offset].getX(), pts[offset].getY(), + pts[offset + 1].getX(), pts[offset + 1].getY(), + pts[offset + 2].getX(), pts[offset + 2].getY()); } @@ -188,6 +241,26 @@ public abstract class QuadCurve2D } + /** + * Calculates the squared flatness of a quadratic curve, directly + * specifying each coordinate value. The flatness is the distance of + * the control point to the line between start and end point. + * + * <p><img src="doc-files/QuadCurve2D-4.png" width="350" height="180" + * alt="A drawing that illustrates the flatness" /> + * + * <p>In the above drawing, the straight line connecting start point + * P1 and end point P2 is depicted in gray. The result will be the + * the square of the distance between C and the gray line, i.e. + * the squared length of the red line. + * + * @param x1 the <i>x</i> coordinate of the start point P1. + * @param y1 the <i>y</i> coordinate of the start point P1. + * @param cx the <i>x</i> coordinate of the control point C. + * @param cy the <i>y</i> coordinate of the control point C. + * @param x2 the <i>x</i> coordinate of the end point P2. + * @param y2 the <i>y</i> coordinate of the end point P2. + */ public static double getFlatnessSq(double x1, double y1, double cx, double cy, double x2, double y2) { @@ -195,6 +268,26 @@ public abstract class QuadCurve2D } + /** + * Calculates the flatness of a quadratic curve, directly specifying + * each coordinate value. The flatness is the distance of the + * control point to the line between start and end point. + * + * <p><img src="doc-files/QuadCurve2D-4.png" width="350" height="180" + * alt="A drawing that illustrates the flatness" /> + * + * <p>In the above drawing, the straight line connecting start point + * P1 and end point P2 is depicted in gray. The result will be the + * the distance between C and the gray line, i.e. the length of + * the red line. + * + * @param x1 the <i>x</i> coordinate of the start point P1. + * @param y1 the <i>y</i> coordinate of the start point P1. + * @param cx the <i>x</i> coordinate of the control point C. + * @param cy the <i>y</i> coordinate of the control point C. + * @param x2 the <i>x</i> coordinate of the end point P2. + * @param y2 the <i>y</i> coordinate of the end point P2. + */ public static double getFlatness(double x1, double y1, double cx, double cy, double x2, double y2) { @@ -202,6 +295,32 @@ public abstract class QuadCurve2D } + /** + * Calculates the squared flatness of a quadratic curve, specifying + * the coordinate values in an array. The flatness is the distance + * of the control point to the line between start and end point. + * + * <p><img src="doc-files/QuadCurve2D-4.png" width="350" height="180" + * alt="A drawing that illustrates the flatness" /> + * + * <p>In the above drawing, the straight line connecting start point + * P1 and end point P2 is depicted in gray. The result will be the + * the square of the distance between C and the gray line, i.e. + * the squared length of the red line. + * + * @param coords an array containing the coordinate values. The + * <i>x</i> coordinate of the start point P1 is located at + * <code>coords[offset]</code>, its <i>y</i> coordinate at + * <code>coords[offset + 1]</code>. The <i>x</i> coordinate of the + * control point C is located at <code>coords[offset + 2]</code>, + * its <i>y</i> coordinate at <code>coords[offset + 3]</code>. The + * <i>x</i> coordinate of the end point P2 is located at + * <code>coords[offset + 4]</code>, its <i>y</i> coordinate at + * <code>coords[offset + 5]</code>. + * + * @param offset the offset of the first coordinate value in + * <code>coords</code>. + */ public static double getFlatnessSq(double[] coords, int offset) { return Line2D.ptSegDistSq(coords[offset], coords[offset + 1], @@ -210,6 +329,32 @@ public abstract class QuadCurve2D } + /** + * Calculates the flatness of a quadratic curve, specifying the + * coordinate values in an array. The flatness is the distance of + * the control point to the line between start and end point. + * + * <p><img src="doc-files/QuadCurve2D-4.png" width="350" height="180" + * alt="A drawing that illustrates the flatness" /> + * + * <p>In the above drawing, the straight line connecting start point + * P1 and end point P2 is depicted in gray. The result will be the + * the the distance between C and the gray line, i.e. the length of + * the red line. + * + * @param coords an array containing the coordinate values. The + * <i>x</i> coordinate of the start point P1 is located at + * <code>coords[offset]</code>, its <i>y</i> coordinate at + * <code>coords[offset + 1]</code>. The <i>x</i> coordinate of the + * control point C is located at <code>coords[offset + 2]</code>, + * its <i>y</i> coordinate at <code>coords[offset + 3]</code>. The + * <i>x</i> coordinate of the end point P2 is located at + * <code>coords[offset + 4]</code>, its <i>y</i> coordinate at + * <code>coords[offset + 5]</code>. + * + * @param offset the offset of the first coordinate value in + * <code>coords</code>. + */ public static double getFlatness(double[] coords, int offset) { return Line2D.ptSegDist(coords[offset], coords[offset + 1], @@ -218,6 +363,19 @@ public abstract class QuadCurve2D } + /** + * Calculates the squared flatness of this curve. The flatness is + * the distance of the control point to the line between start and + * end point. + * + * <p><img src="doc-files/QuadCurve2D-4.png" width="350" height="180" + * alt="A drawing that illustrates the flatness" /> + * + * <p>In the above drawing, the straight line connecting start point + * P1 and end point P2 is depicted in gray. The result will be the + * the square of the distance between C and the gray line, i.e. the + * squared length of the red line. + */ public double getFlatnessSq() { return Line2D.ptSegDistSq(getX1(), getY1(), @@ -226,6 +384,19 @@ public abstract class QuadCurve2D } + /** + * Calculates the flatness of this curve. The flatness is the + * distance of the control point to the line between start and end + * point. + * + * <p><img src="doc-files/QuadCurve2D-4.png" width="350" height="180" + * alt="A drawing that illustrates the flatness" /> + * + * <p>In the above drawing, the straight line connecting start point + * P1 and end point P2 is depicted in gray. The result will be the + * the distance between C and the gray line, i.e. the length of the + * red line. + */ public double getFlatness() { return Line2D.ptSegDist(getX1(), getY1(), @@ -417,6 +588,16 @@ public abstract class QuadCurve2D } + /** + * Determines whether a point lies inside the area that is bounded + * by the curve and the straight line connecting its end points. + * + * <p><img src="doc-files/QuadCurve2D-5.png" width="350" height="180" + * alt="A drawing of the area spanned by the curve" /> + * + * <p>The above drawing illustrates in which area points are + * considered “contained” in a QuadCurve2D. + */ public boolean contains(double x, double y) { // XXX Implement. @@ -424,6 +605,16 @@ public abstract class QuadCurve2D } + /** + * Determines whether a point lies inside the area that is bounded + * by the curve and the straight line connecting its end points. + * + * <p><img src="doc-files/QuadCurve2D-5.png" width="350" height="180" + * alt="A drawing of the area spanned by the curve" /> + * + * <p>The above drawing illustrates in which area points are + * considered “contained” in a QuadCurve2D. + */ public boolean contains(Point2D p) { return contains(p.getX(), p.getY()); @@ -563,8 +754,7 @@ public abstract class QuadCurve2D /** - * Creates a new curve with the same contents as - * this one. + * Creates a new curve with the same contents as this one. * * @return the clone. */ diff --git a/libjava/java/io/ByteArrayOutputStream.java b/libjava/java/io/ByteArrayOutputStream.java index 3e3e0c20018..2e89cf5ee0a 100644 --- a/libjava/java/io/ByteArrayOutputStream.java +++ b/libjava/java/io/ByteArrayOutputStream.java @@ -198,7 +198,7 @@ public class ByteArrayOutputStream extends OutputStream // Resize buffer to accommodate new bytes. private void resize (int add) { - if (count + add >= buf.length) + if (count + add > buf.length) { int newlen = buf.length * 2; if (count + add > newlen) diff --git a/libjava/java/io/natFileDescriptorWin32.cc b/libjava/java/io/natFileDescriptorWin32.cc index 1891bf78e42..465d7557992 100644 --- a/libjava/java/io/natFileDescriptorWin32.cc +++ b/libjava/java/io/natFileDescriptorWin32.cc @@ -133,7 +133,13 @@ java::io::FileDescriptor::open (jstring path, jint jflags) { throw new FileNotFoundException (_Jv_WinStrError (cpath, dwErrorCode)); } } - return (jint)handle; + + // Make this handle non-inheritable so that child + // processes don't inadvertently prevent us from + // closing this file. + _Jv_platform_close_on_exec (handle); + + return (jint) handle; } void diff --git a/libjava/java/io/natFileWin32.cc b/libjava/java/io/natFileWin32.cc index cee6b00ae1f..1559043e7ac 100644 --- a/libjava/java/io/natFileWin32.cc +++ b/libjava/java/io/natFileWin32.cc @@ -109,10 +109,15 @@ jstring java::io::File::getCanonicalPath (void) { JV_TEMP_UTF_STRING (cpath, path); + + // If the filename is blank, use the current directory. + const char* thepath = cpath.buf(); + if (*thepath == '\0') + thepath = "."; LPTSTR unused; char buf2[MAX_PATH]; - if(!GetFullPathName(cpath, MAX_PATH, buf2, &unused)) + if(!GetFullPathName(thepath, MAX_PATH, buf2, &unused)) throw new IOException (JvNewStringLatin1 ("GetFullPathName failed")); // FIXME: what encoding to assume for file names? This affects many diff --git a/libjava/java/lang/Win32Process.java b/libjava/java/lang/Win32Process.java index 7a5872705b8..b0ef487c204 100644 --- a/libjava/java/lang/Win32Process.java +++ b/libjava/java/lang/Win32Process.java @@ -28,8 +28,6 @@ final class ConcreteProcess extends Process { public native void destroy (); - public native boolean hasExited (); - public int exitValue () { if (! hasExited ()) @@ -55,13 +53,6 @@ final class ConcreteProcess extends Process public native int waitFor () throws InterruptedException; - public native void startProcess (String[] progarray, - String[] envp, - File dir) - throws IOException; - - public native void cleanup (); - public ConcreteProcess (String[] progarray, String[] envp, File dir) @@ -89,4 +80,11 @@ final class ConcreteProcess extends Process // Exit code of the child if it has exited. private int exitCode; + + private native boolean hasExited (); + private native void startProcess (String[] progarray, + String[] envp, + File dir) + throws IOException; + private native void cleanup (); } diff --git a/libjava/java/lang/natClass.cc b/libjava/java/lang/natClass.cc index ffac2c1ff53..f7793a56d56 100644 --- a/libjava/java/lang/natClass.cc +++ b/libjava/java/lang/natClass.cc @@ -688,7 +688,7 @@ java::lang::Class::newInstance (void) _Jv_Method *meth = _Jv_GetMethodLocal (this, init_name, void_signature); if (! meth) - throw new java::lang::NoSuchMethodException (_Jv_NewStringUtf8Const (init_name)); + throw new java::lang::InstantiationException (getName()); jobject r = JvAllocObject (this); ((void (*) (jobject)) meth->ncode) (r); @@ -1835,6 +1835,12 @@ _Jv_LayoutVTableMethods (jclass klass) if (! _Jv_isVirtualMethod (meth)) continue; + // FIXME: Must check that we don't override: + // - Package-private method where superclass is in different package. + // - Final or less-accessible declaration in superclass (check binary + // spec, do we allocate new vtable entry or put throw node in vtable?) + // - Static or private method in superclass. + if (superclass != NULL) { super_meth = _Jv_LookupDeclaredMethod (superclass, meth->name, @@ -1843,8 +1849,7 @@ _Jv_LayoutVTableMethods (jclass klass) if (super_meth) meth->index = super_meth->index; - else if (! (meth->accflags & java::lang::reflect::Modifier::FINAL) - && ! (klass->accflags & java::lang::reflect::Modifier::FINAL)) + else meth->index = index++; } diff --git a/libjava/java/lang/natWin32Process.cc b/libjava/java/lang/natWin32Process.cc index 49fa853a398..b687a0e0abe 100644 --- a/libjava/java/lang/natWin32Process.cc +++ b/libjava/java/lang/natWin32Process.cc @@ -29,23 +29,29 @@ details. */ void java::lang::ConcreteProcess::cleanup (void) { - if (inputStream != NULL) - { - inputStream->close (); - inputStream = NULL; - } - - if (outputStream != NULL) - { - outputStream->close (); - outputStream = NULL; - } - - if (errorStream != NULL) - { - errorStream->close (); - errorStream = NULL; - } + // FIXME: + // We used to close the input, output and + // error streams here, but we can't do that + // because the caller also has the right + // to close these and FileInputStream and FileOutputStream + // scream if you attempt to close() them twice. Presently, + // we use _Jv_platform_close_on_exec, which is similar + // to the POSIX approach. + // + // What I wanted to do is have private nested + // classes in ConcreteProcess which extend FileInputStream + // and FileOutputStream, respectively, but override + // close() to permit multiple calls to close(). This + // led to class header and platform configury issues + // that I didn't feel like dealing with. However, + // this approach could conceivably be a good multiplatform + // one since delaying the pipe close until process + // termination could be wasteful if many child processes + // are spawned within the parent process' lifetime. + inputStream = NULL; + outputStream = NULL; + errorStream = NULL; + if (procHandle) { CloseHandle((HANDLE) procHandle); @@ -129,6 +135,76 @@ java::lang::ConcreteProcess::waitFor (void) return exitCode; } + +// Helper class for creating and managing the pipes +// used for I/O redirection for child processes. +class ChildProcessPipe +{ +public: + // Indicates from the child process' point of view + // whether the pipe is for reading or writing. + enum EType {INPUT, OUTPUT}; + + ChildProcessPipe(EType eType); + ~ChildProcessPipe(); + + // Returns a pipe handle suitable for use by the parent process + HANDLE getParentHandle(); + + // Returns a pipe handle suitable for use by the child process. + HANDLE getChildHandle(); + +private: + EType m_eType; + HANDLE m_hRead, m_hWrite; +}; + +ChildProcessPipe::ChildProcessPipe(EType eType): + m_eType(eType) +{ + SECURITY_ATTRIBUTES sAttrs; + + // Explicitly allow the handles to the pipes to be inherited. + sAttrs.nLength = sizeof (SECURITY_ATTRIBUTES); + sAttrs.bInheritHandle = 1; + sAttrs.lpSecurityDescriptor = NULL; + + if (CreatePipe (&m_hRead, &m_hWrite, &sAttrs, 0) == 0) + { + DWORD dwErrorCode = GetLastError (); + throw new java::io::IOException ( + _Jv_WinStrError ("Error creating pipe", dwErrorCode)); + } + + // If this is the read end of the child, we need + // to make the parent write end non-inheritable. Similarly, + // if this is the write end of the child, we need to make + // the parent read end non-inheritable. If we didn't + // do this, the child would inherit these ends and we wouldn't + // be able to close them from our end. For full details, + // do a Google search on "Q190351". + HANDLE& rhStd = m_eType==INPUT ? m_hWrite : m_hRead; + _Jv_platform_close_on_exec (rhStd); +} + +ChildProcessPipe::~ChildProcessPipe() +{ + // Close the parent end of the pipe. This + // destructor is called after the child process + // has been spawned. + CloseHandle(getChildHandle()); +} + +HANDLE ChildProcessPipe::getParentHandle() +{ + return m_eType==INPUT ? m_hWrite : m_hRead; +} + +HANDLE ChildProcessPipe::getChildHandle() +{ + return m_eType==INPUT ? m_hRead : m_hWrite; +} + void java::lang::ConcreteProcess::startProcess (jstringArray progarray, jstringArray envp, @@ -197,46 +273,16 @@ java::lang::ConcreteProcess::startProcess (jstringArray progarray, { // We create anonymous pipes to communicate with the child // on each of standard streams. + ChildProcessPipe aChildStdIn(ChildProcessPipe::INPUT); + ChildProcessPipe aChildStdOut(ChildProcessPipe::OUTPUT); + ChildProcessPipe aChildStdErr(ChildProcessPipe::OUTPUT); - HANDLE cldStdInRd, cldStdInWr; - HANDLE cldStdOutRd, cldStdOutWr; - HANDLE cldStdErrRd, cldStdErrWr; - - SECURITY_ATTRIBUTES sAttrs; - - // Explicitly allow the handles to the pipes to be inherited. - sAttrs.nLength = sizeof (SECURITY_ATTRIBUTES); - sAttrs.bInheritHandle = 1; - sAttrs.lpSecurityDescriptor = NULL; - - - if (CreatePipe (&cldStdInRd, &cldStdInWr, &sAttrs, 0) == 0) - { - DWORD dwErrorCode = GetLastError (); - throw new IOException (_Jv_WinStrError ("Error creating stdin pipe", - dwErrorCode)); - } - - if (CreatePipe (&cldStdOutRd, &cldStdOutWr, &sAttrs, 0) == 0) - { - DWORD dwErrorCode = GetLastError (); - throw new IOException (_Jv_WinStrError ("Error creating stdout pipe", - dwErrorCode)); - } - - if (CreatePipe (&cldStdErrRd, &cldStdErrWr, &sAttrs, 0) == 0) - { - DWORD dwErrorCode = GetLastError (); - throw new IOException (_Jv_WinStrError ("Error creating stderr pipe", - dwErrorCode)); - } - - outputStream = new FileOutputStream - (new FileDescriptor ((jint) cldStdInWr)); - inputStream = new FileInputStream - (new FileDescriptor ((jint) cldStdOutRd)); - errorStream = new FileInputStream - (new FileDescriptor ((jint) cldStdErrRd)); + outputStream = new FileOutputStream (new FileDescriptor ( + (jint) aChildStdIn.getParentHandle ())); + inputStream = new FileInputStream (new FileDescriptor ( + (jint) aChildStdOut.getParentHandle ())); + errorStream = new FileInputStream (new FileDescriptor ( + (jint) aChildStdErr.getParentHandle ())); // Now create the child process. PROCESS_INFORMATION pi; @@ -250,16 +296,20 @@ java::lang::ConcreteProcess::startProcess (jstringArray progarray, // Explicitly specify the handles to the standard streams. si.dwFlags |= STARTF_USESTDHANDLES; - si.hStdInput = cldStdInRd; - si.hStdOutput = cldStdOutWr; - si.hStdError = cldStdErrWr; + si.hStdInput = aChildStdIn.getChildHandle(); + si.hStdOutput = aChildStdOut.getChildHandle(); + si.hStdError = aChildStdErr.getChildHandle(); + // Spawn the process. CREATE_NO_WINDOW only applies when + // starting a console application; it suppresses the + // creation of a console window. This flag is ignored on + // Win9X. if (CreateProcess (NULL, cmdLine, NULL, NULL, 1, - 0, + CREATE_NO_WINDOW, env, wdir, &si, @@ -272,11 +322,6 @@ java::lang::ConcreteProcess::startProcess (jstringArray progarray, procHandle = (jint ) pi.hProcess; - // Close the wrong ends (for the parent) of the pipes. - CloseHandle (cldStdInRd); - CloseHandle (cldStdOutWr); - CloseHandle (cldStdErrWr); - _Jv_Free (cmdLine); if (env != NULL) _Jv_Free (env); diff --git a/libjava/java/lang/reflect/natMethod.cc b/libjava/java/lang/reflect/natMethod.cc index 525a4a0e9c9..ed122ea2441 100644 --- a/libjava/java/lang/reflect/natMethod.cc +++ b/libjava/java/lang/reflect/natMethod.cc @@ -343,6 +343,8 @@ _Jv_CallAnyMethodA (jobject obj, jvalue *result, jboolean is_jni_call) { + using namespace java::lang::reflect; + #ifdef USE_LIBFFI JvAssert (! is_constructor || ! obj); JvAssert (! is_constructor || return_type); @@ -351,7 +353,7 @@ _Jv_CallAnyMethodA (jobject obj, // constructor does need a `this' argument, but it is one we create. jboolean needs_this = false; if (is_constructor - || ! java::lang::reflect::Modifier::isStatic(meth->accflags)) + || ! Modifier::isStatic(meth->accflags)) needs_this = true; int param_count = parameter_types->length; @@ -464,7 +466,7 @@ _Jv_CallAnyMethodA (jobject obj, void *ncode; - if (is_virtual_call) + if (is_virtual_call && ! Modifier::isFinal (meth->accflags)) { _Jv_VTable *vtable = *(_Jv_VTable **) obj; ncode = vtable->get_method (meth->index); diff --git a/libjava/java/net/Inet4Address.java b/libjava/java/net/Inet4Address.java index 25d296f995a..3b18f6fdd10 100644 --- a/libjava/java/net/Inet4Address.java +++ b/libjava/java/net/Inet4Address.java @@ -56,7 +56,7 @@ import java.util.Arrays; public final class Inet4Address extends InetAddress { - static final long serialVersionUID = 7615067291688066509L; + static final long serialVersionUID = 3286316764910316507L; /** * needed for serialization diff --git a/libjava/java/net/InetAddress.java b/libjava/java/net/InetAddress.java index 6d72d627c64..8d09827655d 100644 --- a/libjava/java/net/InetAddress.java +++ b/libjava/java/net/InetAddress.java @@ -476,8 +476,7 @@ public class InetAddress implements Serializable */ public boolean equals (Object obj) { - if (obj == null - || ! (obj instanceof InetAddress)) + if (! (obj instanceof InetAddress)) return false; // "The Java Class Libraries" 2nd edition says "If a machine has diff --git a/libjava/java/net/SocketPermission.java b/libjava/java/net/SocketPermission.java index dea04e2432a..35006173828 100644 --- a/libjava/java/net/SocketPermission.java +++ b/libjava/java/net/SocketPermission.java @@ -147,9 +147,6 @@ public final class SocketPermission extends Permission */ public boolean equals(Object obj) { - if (obj == null) - return (false); - if (!(obj instanceof SocketPermission)) return (false); diff --git a/libjava/java/net/URL.java b/libjava/java/net/URL.java index dd1ea4f0855..0fd22b1cb99 100644 --- a/libjava/java/net/URL.java +++ b/libjava/java/net/URL.java @@ -451,7 +451,7 @@ public final class URL implements Serializable */ public boolean equals (Object obj) { - if (obj == null || ! (obj instanceof URL)) + if (! (obj instanceof URL)) return false; return ph.equals (this, (URL) obj); @@ -829,8 +829,7 @@ public final class URL implements Serializable // Can't instantiate; handler still null, go on to next element. } } - while ((ph == null || - !(ph instanceof URLStreamHandler)) + while ((! (ph instanceof URLStreamHandler)) && pkgPrefix.hasMoreTokens()); } diff --git a/libjava/java/net/URLStreamHandler.java b/libjava/java/net/URLStreamHandler.java index 61b466cce6d..9198370d7ad 100644 --- a/libjava/java/net/URLStreamHandler.java +++ b/libjava/java/net/URLStreamHandler.java @@ -480,12 +480,8 @@ public abstract class URLStreamHandler if (host.length() != 0) sb.append("//").append(host); - // Note that this produces different results from JDK 1.2 as JDK 1.2 - // ignores a non-default port if host is null or "". That is inconsistent - // with the spec since the result of this method is spec'ed so it can be - // used to construct a new URL that is equivalent to the original. - boolean port_needed = port > 0 && port != getDefaultPort(); - if (port_needed) + // Append port if port was in URL spec. + if (port != -1) sb.append(':').append(port); sb.append(file); diff --git a/libjava/java/sql/Timestamp.java b/libjava/java/sql/Timestamp.java index be0aa4dcd02..5ec75da61c1 100644 --- a/libjava/java/sql/Timestamp.java +++ b/libjava/java/sql/Timestamp.java @@ -58,11 +58,7 @@ public class Timestamp extends java.util.Date /** * Used for parsing and formatting this date. */ - // Millisecond will have to be close enough for now. - private static SimpleDateFormat parse_sdf = - new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSSS"); - - private static SimpleDateFormat format_sdf = + private static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); /** @@ -79,14 +75,35 @@ public class Timestamp extends java.util.Date */ public static Timestamp valueOf(String str) { + int nanos = 0; + int dot = str.indexOf('.'); + if (dot != -1) + { + if (str.lastIndexOf('.') != dot) + throw new IllegalArgumentException(str); + + int len = str.length() - dot - 1; + if (len < 1 || len > 9) + throw new IllegalArgumentException(str); + + nanos = Integer.parseInt(str.substring(dot + 1)); + for (int i = len; i < 9; i++) + nanos *= 10; + + str = str.substring(0, dot); + + } + try { - java.util.Date d = (java.util.Date)parse_sdf.parseObject(str); + java.util.Date d = (java.util.Date)sdf.parseObject(str); if (d == null) throw new IllegalArgumentException(str); - else - return new Timestamp(d.getTime()); + + Timestamp ts = new Timestamp(d.getTime() + nanos / 1000000); + ts.nanos = nanos; + return ts; } catch (ParseException e) { @@ -133,7 +150,7 @@ public class Timestamp extends java.util.Date */ public String toString() { - return format_sdf.format(this) + "." + getNanos(); + return sdf.format(this) + "." + getNanos(); } /** diff --git a/libjava/java/text/DateFormat.java b/libjava/java/text/DateFormat.java index 76bf535577a..bf4c2c8d6e0 100644 --- a/libjava/java/text/DateFormat.java +++ b/libjava/java/text/DateFormat.java @@ -1,5 +1,5 @@ /* DateFormat.java -- Class for formatting/parsing date/times - Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc. + Copyright (C) 1998, 1999, 2000, 2001, 2003 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -39,6 +39,7 @@ exception statement from your version. */ package java.text; import java.util.*; +import java.io.InvalidObjectException; /** * @author Per Bothner <bothner@cygnus.com> @@ -86,6 +87,97 @@ public abstract class DateFormat extends Format implements Cloneable public static final int HOUR0_FIELD = 16; public static final int TIMEZONE_FIELD = 17; + + public static class Field extends Format.Field + { + static final long serialVersionUID = 7441350119349544720L; + + private int calendarField; + + public static final DateFormat.Field ERA + = new Field("era", Calendar.ERA); + public static final DateFormat.Field YEAR + = new Field("year", Calendar.YEAR); + public static final DateFormat.Field MONTH + = new Field("month", Calendar.MONTH); + public static final DateFormat.Field DAY_OF_MONTH + = new Field("day of month", Calendar.DAY_OF_MONTH); + public static final DateFormat.Field HOUR_OF_DAY1 + = new Field("hour of day 1", Calendar.HOUR_OF_DAY); + public static final DateFormat.Field HOUR_OF_DAY0 + = new Field("hour of day 0", Calendar.HOUR_OF_DAY); + public static final DateFormat.Field MINUTE + = new Field("minute", Calendar.MINUTE); + public static final DateFormat.Field SECOND + = new Field("second", Calendar.SECOND); + public static final DateFormat.Field MILLISECOND + = new Field("millisecond", Calendar.MILLISECOND); + public static final DateFormat.Field DAY_OF_WEEK + = new Field("day of week", Calendar.DAY_OF_WEEK); + public static final DateFormat.Field DAY_OF_YEAR + = new Field("day of year", Calendar.DAY_OF_YEAR); + public static final DateFormat.Field DAY_OF_WEEK_IN_MONTH + = new Field("day of week in month", Calendar.DAY_OF_WEEK_IN_MONTH); + public static final DateFormat.Field WEEK_OF_YEAR + = new Field("week of year", Calendar.WEEK_OF_YEAR); + public static final DateFormat.Field WEEK_OF_MONTH + = new Field("week of month", Calendar.WEEK_OF_MONTH); + public static final DateFormat.Field AM_PM + = new Field("am/pm", Calendar.AM_PM); + public static final DateFormat.Field HOUR1 + = new Field("hour1", Calendar.HOUR); + public static final DateFormat.Field HOUR0 + = new Field("hour0", Calendar.HOUR); + public static final DateFormat.Field TIME_ZONE + = new Field("timezone", Calendar.ZONE_OFFSET); + + public static final DateFormat.Field[] allFields = + { + ERA, YEAR, MONTH, DAY_OF_MONTH, HOUR_OF_DAY1, + HOUR_OF_DAY0, MINUTE, SECOND, MILLISECOND, + DAY_OF_WEEK, DAY_OF_YEAR, DAY_OF_WEEK_IN_MONTH, + WEEK_OF_YEAR, WEEK_OF_MONTH, AM_PM, HOUR1, HOUR0, + TIME_ZONE + }; + + // For deserialization + private Field() + { + super(""); + } + + protected Field(String name, int calendarField) + { + super(name); + this.calendarField = calendarField; + } + + public int getCalendarField() + { + return calendarField; + } + + public static Field ofCalendarField(int calendarField) + { + if (calendarField >= allFields.length || calendarField < 0) + throw new IllegalArgumentException("no such calendar field (" + + calendarField + ")"); + + return allFields[calendarField]; + } + + protected Object readResolve() throws InvalidObjectException + { + String s = getName(); + + for (int i=0;i<allFields.length;i++) + if (s.equals(allFields[i].getName())) + return allFields[i]; + + throw new InvalidObjectException("no such DateFormat field called " + s); + } + } + /** * This method initializes a new instance of <code>DateFormat</code>. */ @@ -152,7 +244,9 @@ public abstract class DateFormat extends Format implements Cloneable if (obj instanceof Number) obj = new Date(((Number) obj).longValue()); else if (! (obj instanceof Date)) - throw new IllegalArgumentException ("Cannot format given Object as a Date"); + throw new IllegalArgumentException + ("Cannot format given Object as a Date"); + return format ((Date) obj, buf, pos); } diff --git a/libjava/java/text/DecimalFormat.java b/libjava/java/text/DecimalFormat.java index 7c5d5b0ba7b..8dae1872fd3 100644 --- a/libjava/java/text/DecimalFormat.java +++ b/libjava/java/text/DecimalFormat.java @@ -202,6 +202,8 @@ public class DecimalFormat extends NumberFormat } else if (c != syms.getExponential() && c != syms.getPatternSeparator() + && c != syms.getPercent() + && c != syms.getPerMill() && patChars.indexOf(c) != -1) throw new IllegalArgumentException ("unexpected special " + "character - index: " + index); diff --git a/libjava/java/text/Format.java b/libjava/java/text/Format.java index ab61f28ae30..ba32cae25bc 100644 --- a/libjava/java/text/Format.java +++ b/libjava/java/text/Format.java @@ -38,6 +38,10 @@ exception statement from your version. */ package java.text; +import java.util.Set; +import java.util.Map; +import java.util.HashSet; +import java.util.HashMap; import java.io.Serializable; /** @@ -61,6 +65,16 @@ public abstract class Format implements Serializable, Cloneable { static final long serialVersionUID = 4479235611355683992L; + public static class Field extends AttributedCharacterIterator.Attribute + { + static final long serialVersionUID = 276966692217360283L; + + public Field(String name) + { + super(name); + } + } + /** * This method initializes a new instance of <code>Format</code>. * It performs no actions, but acts as a default constructor for @@ -142,6 +156,11 @@ public abstract class Format implements Serializable, Cloneable */ public abstract Object parseObject (String str, ParsePosition pos); + public AttributedCharacterIterator formatToCharacterIterator(Object obj) + { + return new FormatCharacterIterator(format(obj), null, null); + } + /** * Creates a copy of this object. * diff --git a/libjava/java/util/jar/JarInputStream.java b/libjava/java/util/jar/JarInputStream.java index 9c295f372e6..daf935fa70a 100644 --- a/libjava/java/util/jar/JarInputStream.java +++ b/libjava/java/util/jar/JarInputStream.java @@ -116,7 +116,6 @@ public class JarInputStream extends ZipInputStream } firstEntry = (JarEntry) super.getNextEntry(); } - closeEntry(); if (verify) { diff --git a/libjava/java/util/zip/DeflaterOutputStream.java b/libjava/java/util/zip/DeflaterOutputStream.java index ff66b080f9e..6a4fa95886b 100644 --- a/libjava/java/util/zip/DeflaterOutputStream.java +++ b/libjava/java/util/zip/DeflaterOutputStream.java @@ -127,12 +127,7 @@ public class DeflaterOutputStream extends FilterOutputStream */ public void finish () throws IOException { - if (inbufLength > 0) - { - def.setInput (inbuf, 0, inbufLength); - deflate (); - inbufLength = 0; - } + inbufWrite(); def.finish(); while (! def.finished ()) { @@ -145,28 +140,27 @@ public class DeflaterOutputStream extends FilterOutputStream public void write (int bval) throws IOException { if (inbuf == null) - { - inbuf = new byte[128]; - } + inbuf = new byte[128]; else if (inbufLength == inbuf.length) - { - def.setInput (inbuf, 0, inbufLength); - deflate (); - inbufLength = 0; - } + inbufWrite (); inbuf[inbufLength++] = (byte) bval; } public void write (byte[] buf, int off, int len) throws IOException { + inbufWrite (); + def.setInput (buf, off, len); + deflate (); + } + + private void inbufWrite () throws IOException + { if (inbufLength > 0) { - def.setInput (inbuf, 0, inbufLength); - deflate (); + int size = inbufLength; inbufLength = 0; + write (inbuf, 0, size); } - def.setInput (buf, off, len); - deflate (); } // Used, if needed, for write(int). diff --git a/libjava/javax/naming/InitialContext.java b/libjava/javax/naming/InitialContext.java index 715f30ad5cd..e2a1ac6b63f 100644 --- a/libjava/javax/naming/InitialContext.java +++ b/libjava/javax/naming/InitialContext.java @@ -240,12 +240,28 @@ public class InitialContext implements Context public Object lookup (Name name) throws NamingException { - return getURLOrDefaultInitCtx (name).lookup (name); + try + { + return getURLOrDefaultInitCtx (name).lookup (name); + } + catch (CannotProceedException cpe) + { + Context ctx = NamingManager.getContinuationContext (cpe); + return ctx.lookup (cpe.getRemainingName()); + } } public Object lookup (String name) throws NamingException { - return getURLOrDefaultInitCtx (name).lookup (name); + try + { + return getURLOrDefaultInitCtx (name).lookup (name); + } + catch (CannotProceedException cpe) + { + Context ctx = NamingManager.getContinuationContext (cpe); + return ctx.lookup (cpe.getRemainingName()); + } } public void rebind (Name name, Object obj) throws NamingException @@ -367,7 +383,8 @@ public class InitialContext implements Context public void close () throws NamingException { - throw new OperationNotSupportedException (); + myProps = null; + defaultInitCtx = null; } public String getNameInNamespace () throws NamingException diff --git a/libjava/javax/naming/spi/NamingManager.java b/libjava/javax/naming/spi/NamingManager.java index 65ce2d23c23..af9ddc36ca7 100644 --- a/libjava/javax/naming/spi/NamingManager.java +++ b/libjava/javax/naming/spi/NamingManager.java @@ -324,8 +324,10 @@ public class NamingManager // It is really unclear to me if this is right. try { - Object obj = getObjectInstance (null, cpe.getAltName (), - cpe.getAltNameCtx (), env); + Object obj = getObjectInstance (cpe.getResolvedObj(), + cpe.getAltName (), + cpe.getAltNameCtx (), + env); if (obj != null) return (Context) obj; } @@ -333,6 +335,9 @@ public class NamingManager { } + // fix stack trace for re-thrown exception (message confusing otherwise) + cpe.fillInStackTrace(); + throw cpe; } diff --git a/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkListPeer.c b/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkListPeer.c index 944bc213945..6c37aeb82e2 100644 --- a/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkListPeer.c +++ b/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkListPeer.c @@ -228,7 +228,6 @@ Java_gnu_java_awt_peer_gtk_GtkListPeer_deselect gdk_threads_leave (); } -/* FIXME: magic mojo (that doesn't seem to do anything) */ JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GtkListPeer_getSize (JNIEnv *env, jobject obj, jint rows, jintArray jdims) @@ -251,7 +250,7 @@ Java_gnu_java_awt_peer_gtk_GtkListPeer_getSize list = GTK_WIDGET (CLIST_FROM_SW (ptr)); sw = GTK_SCROLLED_WINDOW (ptr); - gtk_widget_size_request(list, &myreq); + gtk_widget_size_request(GTK_WIDGET(sw), &myreq); dims[1]=myreq.height; dims[0]=myreq.width; diff --git a/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkTextAreaPeer.c b/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkTextAreaPeer.c index 2964dc37701..a87be723cb3 100644 --- a/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkTextAreaPeer.c +++ b/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkTextAreaPeer.c @@ -64,6 +64,8 @@ Java_gnu_java_awt_peer_gtk_GtkTextAreaPeer_create || scroll == AWT_TEXTAREA_SCROLLBARS_VERTICAL_ONLY) ? GTK_POLICY_ALWAYS : GTK_POLICY_NEVER); + gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW(text), GTK_WRAP_WORD); + gdk_threads_leave (); NSA_SET_PTR (env, obj, sw); diff --git a/libjava/sysdep/sparc/locks.h b/libjava/sysdep/sparc/locks.h index 503417c98a6..7339567d7d4 100644 --- a/libjava/sysdep/sparc/locks.h +++ b/libjava/sysdep/sparc/locks.h @@ -54,11 +54,11 @@ __cas_start_atomic(void) unsigned int tmp; __asm__ __volatile__( "1: ldstub [%1], %0\n" -" orcc %0, 0x0, %g0\n" +" orcc %0, 0x0, %%g0\n" " be 3f\n" " nop\n" "2: ldub [%1], %0\n" -" orcc %0, 0x0, %g0\n" +" orcc %0, 0x0, %%g0\n" " bne 2b\n" " nop\n" "3:" : "=&r" (tmp) diff --git a/libjava/testsuite/ChangeLog b/libjava/testsuite/ChangeLog index 74e4a64e351..6ee2f060512 100644 --- a/libjava/testsuite/ChangeLog +++ b/libjava/testsuite/ChangeLog @@ -1,3 +1,21 @@ +2003-11-10 Tom Tromey <tromey@redhat.com> + + For PR java/12996: + * libjava.jar/simple.jar: New file. + * libjava.jar/simple.xfail: New file. + * libjava.jar/simple.out: New file. + * libjava.jar/simple.java: New file. + * libjava.jar/jar.exp: New file. + +2003-11-08 Tom Tromey <tromey@redhat.com> + + * libjava.jacks/jacks.xfail: Updated. + +2003-11-03 Jeff Sturm <jsturm@one-point.com> + + PR java/12866: + * libjava.compile/InnerExcept.java: New File. + 2003-10-22 Tom Tromey <tromey@redhat.com> PR libgcj/12416: diff --git a/libjava/testsuite/libjava.jacks/jacks.xfail b/libjava/testsuite/libjava.jacks/jacks.xfail index 9087d5f0fe0..1e0429da21b 100644 --- a/libjava/testsuite/libjava.jacks/jacks.xfail +++ b/libjava/testsuite/libjava.jacks/jacks.xfail @@ -128,7 +128,6 @@ 8.1.3-object-3 8.1.3-superclass-5 8.1.3-superclass-6 -8.2-accessibility-inherited-member-5 8.8.5.1-example-1 8.8.5.1-example-3 8.8.5.1-qualified-1 @@ -225,10 +224,6 @@ 8.7-abrupt-1 8.7-complete-1 8.7-complete-3 -5.1.3-dti-1 -5.1.3-dti-2 -5.1.3-fti-1 -5.1.3-fti-2 5.1.2-bts-1 5.1.2-bts-2 5.1.2-bts-3 diff --git a/libjava/win32-threads.cc b/libjava/win32-threads.cc index 1f3d0c57b22..9e3981db3dd 100644 --- a/libjava/win32-threads.cc +++ b/libjava/win32-threads.cc @@ -126,7 +126,18 @@ _Jv_CondWait(_Jv_ConditionVariable_t *cv, _Jv_Mutex_t *mu, jlong millis, jint na else if (millis == 0) time = INFINITE; else time = millis; - _Jv_MutexUnlock (mu); + // Record the current lock depth, so it can be restored + // when we reacquire it. + int count = mu->refcount; + int curcount = count; + + // Call _Jv_MutexUnlock repeatedly until this thread + // has completely released the monitor. + while (curcount > 0) + { + _Jv_MutexUnlock (mu); + --curcount; + } // Set up our array of three events: // - the auto-reset event (for notify()) @@ -164,7 +175,13 @@ _Jv_CondWait(_Jv_ConditionVariable_t *cv, _Jv_Mutex_t *mu, jlong millis, jint na if (last_waiter) ResetEvent (cv->ev[1]); - _Jv_MutexLock (mu); + // Call _Jv_MutexLock repeatedly until the mutex's refcount is the + // same as before we originally released it. + while (curcount < count) + { + _Jv_MutexLock (mu); + ++curcount; + } return interrupted ? _JV_INTERRUPTED : 0; } diff --git a/libjava/win32.cc b/libjava/win32.cc index e44b7b28729..dfed8c43660 100644 --- a/libjava/win32.cc +++ b/libjava/win32.cc @@ -177,6 +177,43 @@ __mingwthr_key_dtor (DWORD, void (*) (void *)) return 0; } +static bool dirExists (const char* dir) +{ + DWORD dwAttrs = ::GetFileAttributes (dir); + return dwAttrs != 0xFFFFFFFF && + (dwAttrs & FILE_ATTRIBUTE_DIRECTORY) != 0; +} + +static void getUserHome(char* userHome, const char* userId) +{ + char* uh = ::getenv ("USERPROFILE"); + if (uh) + { + strcpy(userHome, uh); + } + else + { + // Make a half-hearted attempt to support this + // legacy version of Windows. Try %WINDIR%\Profiles\%USERNAME% + // and failing this, use %WINDIR%. + // + // See:http://java.sun.com/docs/books/tutorial/security1.2/summary/files.html#UserPolicy + // + // To do this correctly, we'd have to factor in the + // Windows version, but if we did that, then this attempt + // wouldn't be half-hearted. + char userHomePath[MAX_PATH], winHome[MAX_PATH]; + ::GetWindowsDirectory(winHome, MAX_PATH); + // assume this call always succeeds + + sprintf(userHomePath, "%s\\Profiles\\%s", winHome, userId); + if (dirExists (userHomePath)) + strcpy(userHome, userHomePath); + else + strcpy(userHome, winHome); + } +} + // Set platform-specific System properties. void _Jv_platform_initProperties (java::util::Properties* newprops) @@ -205,37 +242,14 @@ _Jv_platform_initProperties (java::util::Properties* newprops) // Use GetUserName to set 'user.name'. buflen = 257; // UNLEN + 1 - buffer = (char *) _Jv_MallocUnchecked (buflen); - if (buffer != NULL) - { - if (GetUserName (buffer, &buflen)) - SET ("user.name", buffer); - _Jv_Free (buffer); - } + char userName[buflen]; + if (GetUserName (userName, &buflen)) + SET ("user.name", userName); - // According to the api documentation for 'GetWindowsDirectory()', the - // environmental variable HOMEPATH always specifies the user's home - // directory or a default directory. On the 3 windows machines I checked - // only 1 had it set. If it's not set, JDK1.3.1 seems to set it to - // the windows directory, so we'll do the same. - char *userHome = NULL; - if ((userHome = ::getenv ("HOMEPATH")) == NULL ) - { - // Check HOME since it's what I use. - if ((userHome = ::getenv ("HOME")) == NULL ) - { - // Not found - use the windows directory like JDK1.3.1 does. - char *winHome = (char *) _Jv_MallocUnchecked (MAX_PATH); - if (winHome != NULL) - { - if (GetWindowsDirectory (winHome, MAX_PATH)) - SET ("user.home", winHome); - _Jv_Free (winHome); - } - } - } - if (userHome != NULL) - SET ("user.home", userHome); + // Set user.home + char userHome[MAX_PATH]; + getUserHome(userHome, userName); + SET ("user.home", userHome); // Get and set some OS info. OSVERSIONINFO osvi; @@ -349,3 +363,11 @@ _Jv_pipe (int filedes[2]) { return _pipe (filedes, 4096, _O_BINARY); } + +void +_Jv_platform_close_on_exec (HANDLE h) +{ + // Mark the handle as non-inheritable. This has + // no effect under Win9X. + SetHandleInformation (h, HANDLE_FLAG_INHERIT, 0); +} |