diff options
Diffstat (limited to 'libjava/java')
-rw-r--r-- | libjava/java/io/BufferedInputStream.java | 100 | ||||
-rw-r--r-- | libjava/java/io/InputStreamReader.java | 2 | ||||
-rw-r--r-- | libjava/java/io/PipedInputStream.java | 23 | ||||
-rw-r--r-- | libjava/java/lang/Class.h | 6 | ||||
-rw-r--r-- | libjava/java/lang/ClassLoader.java | 32 | ||||
-rw-r--r-- | libjava/java/lang/VMCompiler.java | 33 | ||||
-rw-r--r-- | libjava/java/lang/natClassLoader.cc | 7 | ||||
-rw-r--r-- | libjava/java/lang/natDouble.cc | 19 | ||||
-rw-r--r-- | libjava/java/lang/natRuntime.cc | 35 | ||||
-rw-r--r-- | libjava/java/lang/natVMClassLoader.cc | 2 | ||||
-rw-r--r-- | libjava/java/net/URL.java | 2 | ||||
-rw-r--r-- | libjava/java/net/URLClassLoader.java | 36 | ||||
-rw-r--r-- | libjava/java/nio/DirectByteBufferImpl.java | 2 | ||||
-rw-r--r-- | libjava/java/text/SimpleDateFormat.java | 12 | ||||
-rw-r--r-- | libjava/java/util/Calendar.java | 6 | ||||
-rw-r--r-- | libjava/java/util/GregorianCalendar.java | 45 | ||||
-rw-r--r-- | libjava/java/util/Timer.java | 5 |
17 files changed, 200 insertions, 167 deletions
diff --git a/libjava/java/io/BufferedInputStream.java b/libjava/java/io/BufferedInputStream.java index 5343f0762b6..ce166b337f4 100644 --- a/libjava/java/io/BufferedInputStream.java +++ b/libjava/java/io/BufferedInputStream.java @@ -65,6 +65,7 @@ package java.io; */ public class BufferedInputStream extends FilterInputStream { + /** * This is the default buffer size */ @@ -103,17 +104,11 @@ public class BufferedInputStream extends FilterInputStream protected int marklimit; /** - * This is the maximum size we have to allocate for the mark buffer. - * This number may be huge (Integer.MAX_VALUE). The class will continue - * to allocate new chunks (specified by <code>CHUNKSIZE</code>) until the - * the size specified by this field is achieved. - */ - private int marktarget = 0; - - /** - * This is the number of bytes to allocate to reach marktarget. + * This is the initial buffer size. When the buffer is grown because + * of marking requirements, it will be grown by bufferSize increments. + * The underlying stream will be read in chunks of bufferSize. */ - static final private int CHUNKSIZE = 1024; + private final int bufferSize; /** * This method initializes a new <code>BufferedInputStream</code> that will @@ -143,6 +138,9 @@ public class BufferedInputStream extends FilterInputStream if (size <= 0) throw new IllegalArgumentException(); buf = new byte[size]; + // initialize pos & count to bufferSize, to prevent refill from + // allocating a new buffer (if the caller starts out by calling mark()). + pos = count = bufferSize = size; } /** @@ -160,7 +158,7 @@ public class BufferedInputStream extends FilterInputStream */ public synchronized int available() throws IOException { - return count - pos + super.available(); + return count - pos + in.available(); } /** @@ -173,7 +171,9 @@ public class BufferedInputStream extends FilterInputStream { // Free up the array memory. buf = null; - super.close(); + pos = count = 0; + markpos = -1; + in.close(); } /** @@ -196,9 +196,7 @@ public class BufferedInputStream extends FilterInputStream */ public synchronized void mark(int readlimit) { - marktarget = marklimit = readlimit; - if (marklimit > CHUNKSIZE) - marklimit = CHUNKSIZE; + marklimit = readlimit; markpos = pos; } @@ -231,9 +229,6 @@ public class BufferedInputStream extends FilterInputStream if (pos >= count && !refill()) return -1; // EOF - if (markpos >= 0 && pos - markpos > marktarget) - markpos = -1; - return buf[pos++] & 0xFF; } @@ -278,10 +273,7 @@ public class BufferedInputStream extends FilterInputStream off += totalBytesRead; len -= totalBytesRead; - if (markpos >= 0 && pos - markpos > marktarget) - markpos = -1; - - while (len > 0 && super.available() > 0 && refill()) + while (len > 0 && in.available() > 0 && refill()) { int remain = Math.min(count - pos, len); System.arraycopy(buf, pos, b, off, remain); @@ -289,9 +281,6 @@ public class BufferedInputStream extends FilterInputStream off += remain; len -= remain; totalBytesRead += remain; - - if (markpos >= 0 && pos - markpos > marktarget) - markpos = -1; } return totalBytesRead; @@ -338,23 +327,28 @@ public class BufferedInputStream extends FilterInputStream while (n > 0L) { - if (pos >= count && !refill()) - if (n < origN) - break; - else - return 0; // No bytes were read before EOF. + if (pos >= count) + { + if (markpos == -1) + { + // Buffer is empty and no mark is set, skip on the + // underlying stream. + n -= in.skip(n); + break; + } + else if (!refill()) + break; + } int numread = (int) Math.min((long) (count - pos), n); pos += numread; n -= numread; - - if (markpos >= 0 && pos - markpos > marktarget) - markpos = -1; } return origN - n; } + // GCJ LOCAL: package-private for use by InputStreamReader /** * Called to refill the buffer (when count is equal to pos). * @@ -366,39 +360,31 @@ public class BufferedInputStream extends FilterInputStream if (buf == null) throw new IOException("Stream closed."); - if (markpos < 0) - count = pos = 0; - else if (markpos > 0) + if (markpos == -1 || count - markpos >= marklimit) { - // Shift the marked bytes (if any) to the beginning of the array - // but don't grow it. This saves space in case a reset is done - // before we reach the max capacity of this array. - System.arraycopy(buf, markpos, buf, 0, count - markpos); - count -= markpos; - pos -= markpos; - markpos = 0; + markpos = -1; + pos = count = 0; } - else if (count >= buf.length && count < marktarget) // BTW, markpos == 0 + else { - // Need to grow the buffer now to have room for marklimit bytes. - // Note that the new buffer is one greater than marklimit. - // This is so that there will be one byte past marklimit to be read - // before having to call refill again, thus allowing marklimit to be - // invalidated. That way refill doesn't have to check marklimit. - marklimit += CHUNKSIZE; - if (marklimit >= marktarget) - marklimit = marktarget; - byte[] newbuf = new byte[marklimit + 1]; - System.arraycopy(buf, 0, newbuf, 0, count); + byte[] newbuf = buf; + if (markpos < bufferSize) + { + newbuf = new byte[count - markpos + bufferSize]; + } + System.arraycopy(buf, markpos, newbuf, 0, count - markpos); buf = newbuf; + count -= markpos; + pos -= markpos; + markpos = 0; } - int numread = super.read(buf, count, buf.length - count); + int numread = in.read(buf, count, bufferSize); - if (numread < 0) // EOF + if (numread <= 0) // EOF return false; count += numread; - return numread > 0; + return true; } } diff --git a/libjava/java/io/InputStreamReader.java b/libjava/java/io/InputStreamReader.java index ee03a5e6175..b3f65368ce3 100644 --- a/libjava/java/io/InputStreamReader.java +++ b/libjava/java/io/InputStreamReader.java @@ -282,11 +282,9 @@ public class InputStreamReader extends Reader { // We have knowledge of the internals of BufferedInputStream // here. Eww. - in.mark (0); // BufferedInputStream.refill() can only be called when // `pos>=count'. boolean r = in.pos < in.count || in.refill (); - in.reset (); if (! r) return -1; converter.setInput(in.buf, in.pos, in.count); diff --git a/libjava/java/io/PipedInputStream.java b/libjava/java/io/PipedInputStream.java index 906ef10fa9f..d424587889a 100644 --- a/libjava/java/io/PipedInputStream.java +++ b/libjava/java/io/PipedInputStream.java @@ -1,5 +1,5 @@ /* PipedInputStream.java -- Read portion of piped streams. - Copyright (C) 1998, 1999, 2000, 2001, 2003 Free Software Foundation, Inc. + Copyright (C) 1998, 1999, 2000, 2001, 2003, 2005 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -226,18 +226,17 @@ public class PipedInputStream extends InputStream } /** - * This method reads bytes from the stream into a caller supplied buffer. - * It starts storing bytes at position <code>offset</code> into the - * buffer and - * reads a maximum of <code>len</code> bytes. Note that this method - * can actually - * read fewer than <code>len</code> bytes. The actual number of bytes - * read is - * returned. A -1 is returned to indicated that no bytes can be read + * This method reads one byte from the stream. + * -1 is returned to indicated that no bytes can be read * because the end of the stream was reached. If the stream is already * closed, a -1 will again be returned to indicate the end of the stream. - * <p> - * This method will block if no byte is available to be read. + * + * <p>This method will block if no byte is available to be read.</p> + * + * @return the value of the read byte value, or -1 of the end of the stream + * was reached + * + * @throws IOException if an error occured */ public int read() throws IOException { @@ -248,7 +247,7 @@ public class PipedInputStream extends InputStream // if this method is never called. int r = read(read_buf, 0, 1); - return r != -1 ? read_buf[0] : -1; + return r != -1 ? (read_buf[0] & 0xff) : -1; } /** diff --git a/libjava/java/lang/Class.h b/libjava/java/lang/Class.h index d7b21e76b05..98ebcc13d38 100644 --- a/libjava/java/lang/Class.h +++ b/libjava/java/lang/Class.h @@ -234,8 +234,9 @@ jboolean _Jv_CheckAccess (jclass self_klass, jclass other_klass, jint flags); jclass _Jv_GetArrayClass (jclass klass, java::lang::ClassLoader *loader); -#ifdef INTERPRETER jboolean _Jv_IsInterpretedClass (jclass); + +#ifdef INTERPRETER void _Jv_InitField (jobject, jclass, int); class _Jv_ClassReader; @@ -466,8 +467,9 @@ private: friend jclass (::_Jv_GetArrayClass) (jclass klass, java::lang::ClassLoader *loader); -#ifdef INTERPRETER friend jboolean (::_Jv_IsInterpretedClass) (jclass); + +#ifdef INTERPRETER friend void ::_Jv_InitField (jobject, jclass, int); friend class ::_Jv_ClassReader; diff --git a/libjava/java/lang/ClassLoader.java b/libjava/java/lang/ClassLoader.java index 2621281273f..ae131308749 100644 --- a/libjava/java/lang/ClassLoader.java +++ b/libjava/java/lang/ClassLoader.java @@ -285,28 +285,28 @@ public abstract class ClassLoader { // Have we already loaded this class? Class c = findLoadedClass(name); - if (c != null) - return c; - - // Can the class be loaded by a parent? - try + if (c == null) { - if (parent == null) + // Can the class be loaded by a parent? + try { - c = VMClassLoader.loadClass(name, resolve); - if (c != null) - return c; + if (parent == null) + { + c = VMClassLoader.loadClass(name, resolve); + if (c != null) + return c; + } + else + { + return parent.loadClass(name, resolve); + } } - else + catch (ClassNotFoundException e) { - return parent.loadClass(name, resolve); } + // Still not found, we have to do it ourself. + c = findClass(name); } - catch (ClassNotFoundException e) - { - } - // Still not found, we have to do it ourself. - c = findClass(name); if (resolve) resolveClass(c); return c; diff --git a/libjava/java/lang/VMCompiler.java b/libjava/java/lang/VMCompiler.java index b3f55603487..6961a31d905 100644 --- a/libjava/java/lang/VMCompiler.java +++ b/libjava/java/lang/VMCompiler.java @@ -79,6 +79,24 @@ final class VMCompiler private static Vector precompiledMapFiles; + // We create a single MD5 engine and then clone it whenever we want + // a new one. This is simpler than trying to find a new one each + // time, and it avoids potential deadlocks due to class loader + // oddities. + private static final MessageDigest md5Digest; + + static + { + try + { + md5Digest = MessageDigest.getInstance("MD5"); + } + catch (NoSuchAlgorithmException _) + { + md5Digest = null; + } + } + static { gcjJitCompiler = System.getProperty("gnu.gcj.jit.compiler"); @@ -123,6 +141,10 @@ final class VMCompiler catch (java.io.IOException _) { } + catch (java.nio.BufferUnderflowException _) + { + // Invalid map file. + } } } } @@ -175,11 +197,18 @@ final class VMCompiler try { - MessageDigest md = MessageDigest.getInstance("MD5"); + MessageDigest md = (MessageDigest) md5Digest.clone(); digest = md.digest(data); } - catch (NoSuchAlgorithmException _) + catch (CloneNotSupportedException _) + { + // Can't happen. + return null; + } + catch (NullPointerException _) { + // If md5Digest==null -- but really this should never happen + // either, since the MD5 digest is in libgcj. return null; } diff --git a/libjava/java/lang/natClassLoader.cc b/libjava/java/lang/natClassLoader.cc index 17b2a883386..dfb976a2954 100644 --- a/libjava/java/lang/natClassLoader.cc +++ b/libjava/java/lang/natClassLoader.cc @@ -106,7 +106,7 @@ void _Jv_RegisterInitiatingLoader (jclass klass, java::lang::ClassLoader *loader) { if (! loader) - loader = java::lang::ClassLoader::getSystemClassLoader(); + loader = java::lang::ClassLoader::systemClassLoader; loader->loadedClasses->put(klass->name->toString(), klass); } @@ -116,7 +116,7 @@ void _Jv_UnregisterInitiatingLoader (jclass klass, java::lang::ClassLoader *loader) { if (! loader) - loader = java::lang::ClassLoader::getSystemClassLoader(); + loader = java::lang::ClassLoader::systemClassLoader; loader->loadedClasses->remove(klass->name->toString()); } @@ -211,8 +211,7 @@ _Jv_FindClass (_Jv_Utf8Const *name, java::lang::ClassLoader *loader) // See if the class was already loaded by this loader. This handles // initiating loader checks, as we register classes with their // initiating loaders. - java::lang::ClassLoader *sys - = java::lang::ClassLoader::getSystemClassLoader (); + java::lang::ClassLoader *sys = java::lang::ClassLoader::systemClassLoader; java::lang::ClassLoader *real = loader; if (! real) real = sys; diff --git a/libjava/java/lang/natDouble.cc b/libjava/java/lang/natDouble.cc index dfec5967a9b..72fe5fbe1c6 100644 --- a/libjava/java/lang/natDouble.cc +++ b/libjava/java/lang/natDouble.cc @@ -1,6 +1,6 @@ // natDouble.cc - Implementation of java.lang.Double native methods. -/* Copyright (C) 1998, 1999, 2000, 2001, 2003 Free Software Foundation +/* Copyright (C) 1998, 1999, 2000, 2001, 2003, 2005 Free Software Foundation This file is part of libgcj. @@ -167,11 +167,15 @@ java::lang::Double::parseDouble(jstring str) length--; // The String could end with a f/F/d/D which is valid but we don't need. + bool saw_trailer = false; if (length > 0) { jchar last = str->charAt(length-1); if (last == 'f' || last == 'F' || last == 'd' || last == 'D') - length--; + { + length--; + saw_trailer = true; + } } jsize start = 0; @@ -186,6 +190,17 @@ java::lang::Double::parseDouble(jstring str) jsize blength = _Jv_GetStringUTFRegion (str, start, length, data); data[blength] = 0; + if (! saw_trailer) + { + if (! strcmp (data, "NaN") || ! strcmp (data, "+NaN") + || ! strcmp (data, "-NaN")) + return NaN; + else if (! strcmp (data, "Infinity") || ! strcmp (data, "+Infinity")) + return POSITIVE_INFINITY; + else if (! strcmp (data, "-Infinity")) + return NEGATIVE_INFINITY; + } + struct _Jv_reent reent; memset (&reent, 0, sizeof reent); diff --git a/libjava/java/lang/natRuntime.cc b/libjava/java/lang/natRuntime.cc index 31f9b90b6fa..23d8ad25d7d 100644 --- a/libjava/java/lang/natRuntime.cc +++ b/libjava/java/lang/natRuntime.cc @@ -163,7 +163,7 @@ java::lang::Runtime::_load (jstring path, jboolean do_search) if (do_search) { - ClassLoader *sys = ClassLoader::getSystemClassLoader(); + ClassLoader *sys = ClassLoader::systemClassLoader; ClassLoader *look = NULL; gnu::gcj::runtime::StackTrace *t = new gnu::gcj::runtime::StackTrace(10); try @@ -391,8 +391,8 @@ java::lang::Runtime::insertSystemProperties (java::util::Properties *newprops) // (introduced in 1.2), and earlier versioning properties. Some // programs rely on seeing values that they expect, so we claim to // be a 1.4-ish VM for their sake. - SET ("java.version", "1.4.2"); - SET ("java.runtime.version", "1.4.2"); + SET ("java.version", JV_VERSION); + SET ("java.runtime.version", JV_VERSION); SET ("java.vendor", "Free Software Foundation, Inc."); SET ("java.vendor.url", "http://gcc.gnu.org/java/"); SET ("java.class.version", "46.0"); @@ -402,7 +402,7 @@ java::lang::Runtime::insertSystemProperties (java::util::Properties *newprops) SET ("java.vm.version", __VERSION__); SET ("java.vm.vendor", "Free Software Foundation, Inc."); SET ("java.vm.name", "GNU libgcj"); - SET ("java.specification.version", "1.4"); + SET ("java.specification.version", JV_API_VERSION); SET ("java.specification.name", "Java(tm) Platform API Specification"); SET ("java.specification.vendor", "Sun Microsystems Inc."); @@ -553,6 +553,9 @@ java::lang::Runtime::insertSystemProperties (java::util::Properties *newprops) // The path to libgcj's boot classes SET ("sun.boot.class.path", BOOT_CLASS_PATH); + // If there is a default system database, set it. + SET ("gnu.gcj.precompiled.db.path", LIBGCJ_DEFAULT_DATABASE); + // Set some properties according to whatever was compiled in with // `-D'. Important: after this point, the only properties that // should be set are those which either the user cannot meaningfully @@ -583,30 +586,6 @@ java::lang::Runtime::insertSystemProperties (java::util::Properties *newprops) } #endif - if (_Jv_Jar_Class_Path) - newprops->put(JvNewStringLatin1 ("java.class.path"), - JvNewStringLatin1 (_Jv_Jar_Class_Path)); - else - { - // FIXME: find libgcj.zip and append its path? - char *classpath = ::getenv("CLASSPATH"); - jstring cp = newprops->getProperty (JvNewStringLatin1("java.class.path")); - java::lang::StringBuffer *sb = new java::lang::StringBuffer (); - - if (classpath) - { - sb->append (JvNewStringLatin1 (classpath)); - sb->append (_Jv_platform_path_separator); - } - if (cp != NULL) - sb->append (cp); - else - sb->append ((jchar) '.'); - - newprops->put(JvNewStringLatin1 ("java.class.path"), - sb->toString ()); - } - // The name used to invoke this process (argv[0] in C). SET ("gnu.gcj.progname", _Jv_GetSafeArg (0)); diff --git a/libjava/java/lang/natVMClassLoader.cc b/libjava/java/lang/natVMClassLoader.cc index 1da79497154..9a539d7e5c3 100644 --- a/libjava/java/lang/natVMClassLoader.cc +++ b/libjava/java/lang/natVMClassLoader.cc @@ -68,7 +68,7 @@ java::lang::VMClassLoader::defineClass (java::lang::ClassLoader *loader, // Record the defining loader. For the system class loader, we // record NULL. - if (loader != java::lang::ClassLoader::getSystemClassLoader()) + if (loader != java::lang::ClassLoader::systemClassLoader) klass->loader = loader; if (name != 0) diff --git a/libjava/java/net/URL.java b/libjava/java/net/URL.java index 7ab30513b7c..576e2d3e55f 100644 --- a/libjava/java/net/URL.java +++ b/libjava/java/net/URL.java @@ -125,7 +125,7 @@ import java.util.StringTokenizer; public final class URL implements Serializable { private static final String DEFAULT_SEARCH_PATH = - "gnu.java.net.protocol|gnu.inet"; + "org.metastatic.jessie|gnu.java.net.protocol|gnu.inet"; // Cached System ClassLoader private static ClassLoader systemClassLoader; diff --git a/libjava/java/net/URLClassLoader.java b/libjava/java/net/URLClassLoader.java index 919fc9de0f6..9593e7d0fb0 100644 --- a/libjava/java/net/URLClassLoader.java +++ b/libjava/java/net/URLClassLoader.java @@ -799,6 +799,9 @@ public class URLClassLoader extends SecureClassLoader if (newUrl == null) return; // Silently ignore... + // Reset the toString() value. + thisString = null; + // Check global cache to see if there're already url loader // for this url. URLLoader loader = (URLLoader) urlloaders.get(newUrl); @@ -1020,25 +1023,28 @@ public class URLClassLoader extends SecureClassLoader */ public String toString() { - if (thisString == null) + synchronized (urlloaders) { - StringBuffer sb = new StringBuffer(); - sb.append(this.getClass().getName()); - sb.append("{urls=[" ); - URL[] thisURLs = getURLs(); - for (int i = 0; i < thisURLs.length; i++) + if (thisString == null) { - sb.append(thisURLs[i]); - if (i < thisURLs.length - 1) - sb.append(','); + StringBuffer sb = new StringBuffer(); + sb.append(this.getClass().getName()); + sb.append("{urls=[" ); + URL[] thisURLs = getURLs(); + for (int i = 0; i < thisURLs.length; i++) + { + sb.append(thisURLs[i]); + if (i < thisURLs.length - 1) + sb.append(','); + } + sb.append(']'); + sb.append(", parent="); + sb.append(getParent()); + sb.append('}'); + thisString = sb.toString(); } - sb.append(']'); - sb.append(", parent="); - sb.append(getParent()); - sb.append('}'); - thisString = sb.toString(); + return thisString; } - return thisString; } /** diff --git a/libjava/java/nio/DirectByteBufferImpl.java b/libjava/java/nio/DirectByteBufferImpl.java index 83279382a22..a0599c722a9 100644 --- a/libjava/java/nio/DirectByteBufferImpl.java +++ b/libjava/java/nio/DirectByteBufferImpl.java @@ -117,7 +117,7 @@ abstract class DirectByteBufferImpl extends ByteBuffer DirectByteBufferImpl(RawData address, int capacity) { super(capacity, capacity, 0, -1); - this.owner = this; + this.owner = null; this.address = address; } diff --git a/libjava/java/text/SimpleDateFormat.java b/libjava/java/text/SimpleDateFormat.java index c1eb3cd3a70..190b4d624f4 100644 --- a/libjava/java/text/SimpleDateFormat.java +++ b/libjava/java/text/SimpleDateFormat.java @@ -916,6 +916,8 @@ public class SimpleDateFormat extends DateFormat boolean is_numeric = true; int offset = 0; boolean maybe2DigitYear = false; + boolean oneBasedHour = false; + boolean oneBasedHourOfDay = false; Integer simpleOffset; String[] set1 = null; String[] set2 = null; @@ -964,12 +966,14 @@ public class SimpleDateFormat extends DateFormat break; case 'h': calendar_field = Calendar.HOUR; + oneBasedHour = true; break; case 'H': calendar_field = Calendar.HOUR_OF_DAY; break; case 'k': calendar_field = Calendar.HOUR_OF_DAY; + oneBasedHourOfDay = true; break; case 'm': calendar_field = Calendar.MINUTE; @@ -1108,6 +1112,14 @@ public class SimpleDateFormat extends DateFormat } } + // Calendar uses 0-based hours. + // I.e. 00:00 AM is midnight, not 12 AM or 24:00 + if (oneBasedHour && value == 12) + value = 0; + + if (oneBasedHourOfDay && value == 24) + value = 0; + // Assign the value and move on. calendar.set(calendar_field, value); } diff --git a/libjava/java/util/Calendar.java b/libjava/java/util/Calendar.java index 0e9284c7c21..7faaeee43bc 100644 --- a/libjava/java/util/Calendar.java +++ b/libjava/java/util/Calendar.java @@ -706,6 +706,8 @@ public abstract class Calendar implements Serializable, Cloneable isSet[WEEK_OF_YEAR] = false; break; case WEEK_OF_MONTH: // pattern 2 + if (! isSet[DAY_OF_WEEK]) + fields[DAY_OF_WEEK] = getFirstDayOfWeek(); isSet[YEAR] = true; isSet[MONTH] = true; isSet[DAY_OF_WEEK] = true; @@ -715,6 +717,8 @@ public abstract class Calendar implements Serializable, Cloneable isSet[WEEK_OF_YEAR] = false; break; case DAY_OF_WEEK_IN_MONTH: // pattern 3 + if (! isSet[DAY_OF_WEEK]) + fields[DAY_OF_WEEK] = getFirstDayOfWeek(); isSet[YEAR] = true; isSet[MONTH] = true; isSet[DAY_OF_WEEK] = true; @@ -733,6 +737,8 @@ public abstract class Calendar implements Serializable, Cloneable isSet[DAY_OF_WEEK_IN_MONTH] = false; break; case WEEK_OF_YEAR: // pattern 5 + if (! isSet[DAY_OF_WEEK]) + fields[DAY_OF_WEEK] = getFirstDayOfWeek(); isSet[YEAR] = true; isSet[DAY_OF_WEEK] = true; isSet[MONTH] = false; diff --git a/libjava/java/util/GregorianCalendar.java b/libjava/java/util/GregorianCalendar.java index 710dd56f58b..d036cd620e8 100644 --- a/libjava/java/util/GregorianCalendar.java +++ b/libjava/java/util/GregorianCalendar.java @@ -275,7 +275,6 @@ public class GregorianCalendar extends Calendar * Constructs a new GregorianCalendar representing midnight on the * given date with the default time zone and locale. * - * * @param year corresponds to the YEAR time field. * @param month corresponds to the MONTH time field. * @param day corresponds to the DAY time field. @@ -478,7 +477,7 @@ public class GregorianCalendar extends Calendar if (isSet[AM_PM] && fields[AM_PM] != AM && fields[AM_PM] != PM) throw new IllegalArgumentException("Illegal AM_PM."); - if (isSet[HOUR] && (fields[HOUR] < 0 || fields[HOUR] > 12)) + if (isSet[HOUR] && (fields[HOUR] < 0 || fields[HOUR] > 11)) throw new IllegalArgumentException("Illegal HOUR."); if (isSet[HOUR_OF_DAY] && (fields[HOUR_OF_DAY] < 0 || fields[HOUR_OF_DAY] > 23)) @@ -564,10 +563,18 @@ public class GregorianCalendar extends Calendar // 3: YEAR + MONTH + DAY_OF_WEEK_IN_MONTH + DAY_OF_WEEK if (isSet[DAY_OF_WEEK_IN_MONTH]) { + if (fields[DAY_OF_WEEK_IN_MONTH] < 0) + { + month++; + first = getFirstDayOfMonth(year, month); + day = 1 + 7 * (fields[DAY_OF_WEEK_IN_MONTH]); + } + else + day = 1 + 7 * (fields[DAY_OF_WEEK_IN_MONTH] - 1); + int offs = fields[DAY_OF_WEEK] - first; if (offs < 0) offs += 7; - day = 1 + 7 * (fields[DAY_OF_WEEK_IN_MONTH] - 1); day += offs; } else @@ -584,7 +591,7 @@ public class GregorianCalendar extends Calendar day = offs + 7 * (fields[WEEK_OF_MONTH] - 1); offs = fields[DAY_OF_WEEK] - getFirstDayOfWeek(); - if (offs < 0) + if (offs <= 0) offs += 7; day += offs; } @@ -602,11 +609,7 @@ public class GregorianCalendar extends Calendar { hour = fields[HOUR]; if (fields[AM_PM] == PM) - if (hour != 12) /* not Noon */ - hour += 12; - /* Fix the problem of the status of 12:00 AM (midnight). */ - if (fields[AM_PM] == AM && hour == 12) - hour = 0; + hour += 12; } else hour = fields[HOUR_OF_DAY]; @@ -709,15 +712,15 @@ public class GregorianCalendar extends Calendar * @param gregorian <code>true</code>, if we should use the Gregorian rules. * @return the days since the epoch, may be negative. */ - public long getLinearDay(int year, int dayOfYear, boolean gregorian) - { - // The 13 is the number of days, that were omitted in the Gregorian - // Calender until the epoch. - // We shift right by 2 instead of dividing by 4, to get correct - // results for negative years (and this is even more efficient). - long julianDay = (year - 1) * 365L + ((year - 1) >> 2) + (dayOfYear - 1) - - EPOCH_DAYS; // gregorian days from 1 to epoch. - + private long getLinearDay(int year, int dayOfYear, boolean gregorian) + { + // The 13 is the number of days, that were omitted in the Gregorian + // Calender until the epoch. + // We shift right by 2 instead of dividing by 4, to get correct + // results for negative years (and this is even more efficient). + long julianDay = (year - 1) * 365L + ((year - 1) >> 2) + (dayOfYear - 1) + - EPOCH_DAYS; // gregorian days from 1 to epoch. + if (gregorian) { // subtract the days that are missing in gregorian calendar @@ -858,7 +861,7 @@ public class GregorianCalendar extends Calendar int hourOfDay = millisInDay / (60 * 60 * 1000); fields[AM_PM] = (hourOfDay < 12) ? AM : PM; int hour = hourOfDay % 12; - fields[HOUR] = (hour == 0) ? 12 : hour; + fields[HOUR] = hour; fields[HOUR_OF_DAY] = hourOfDay; millisInDay %= (60 * 60 * 1000); fields[MINUTE] = millisInDay / (60 * 1000); @@ -925,9 +928,7 @@ public class GregorianCalendar extends Calendar } int maxDay = getActualMaximum(DAY_OF_MONTH); if (fields[DAY_OF_MONTH] > maxDay) - { - fields[DAY_OF_MONTH] = maxDay; - } + fields[DAY_OF_MONTH] = maxDay; set(YEAR, fields[YEAR]); set(MONTH, fields[MONTH]); break; diff --git a/libjava/java/util/Timer.java b/libjava/java/util/Timer.java index 3c7223b2782..364d5314a97 100644 --- a/libjava/java/util/Timer.java +++ b/libjava/java/util/Timer.java @@ -350,8 +350,9 @@ public class Timer throw death; } catch (Throwable t) - { - /* ignore all errors */ + { + // If an exception escapes, the Timer becomes invalid. + queue.stop(); } } |