aboutsummaryrefslogtreecommitdiff
path: root/libjava/java
diff options
context:
space:
mode:
Diffstat (limited to 'libjava/java')
-rw-r--r--libjava/java/io/BufferedInputStream.java100
-rw-r--r--libjava/java/io/InputStreamReader.java2
-rw-r--r--libjava/java/io/PipedInputStream.java23
-rw-r--r--libjava/java/lang/Class.h6
-rw-r--r--libjava/java/lang/ClassLoader.java32
-rw-r--r--libjava/java/lang/VMCompiler.java33
-rw-r--r--libjava/java/lang/natClassLoader.cc7
-rw-r--r--libjava/java/lang/natDouble.cc19
-rw-r--r--libjava/java/lang/natRuntime.cc35
-rw-r--r--libjava/java/lang/natVMClassLoader.cc2
-rw-r--r--libjava/java/net/URL.java2
-rw-r--r--libjava/java/net/URLClassLoader.java36
-rw-r--r--libjava/java/nio/DirectByteBufferImpl.java2
-rw-r--r--libjava/java/text/SimpleDateFormat.java12
-rw-r--r--libjava/java/util/Calendar.java6
-rw-r--r--libjava/java/util/GregorianCalendar.java45
-rw-r--r--libjava/java/util/Timer.java5
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();
}
}