aboutsummaryrefslogtreecommitdiff
path: root/libjava/java/io/File.java
diff options
context:
space:
mode:
Diffstat (limited to 'libjava/java/io/File.java')
-rw-r--r--libjava/java/io/File.java154
1 files changed, 135 insertions, 19 deletions
diff --git a/libjava/java/io/File.java b/libjava/java/io/File.java
index 2086f1057aa..6e5ce8e64ff 100644
--- a/libjava/java/io/File.java
+++ b/libjava/java/io/File.java
@@ -1,6 +1,6 @@
// File.java - File name
-/* Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation
+/* Copyright (C) 1998, 1999, 2000, 2001, 2003 Free Software Foundation, Inc.
This file is part of libgcj.
@@ -96,9 +96,13 @@ public class File implements Serializable, Comparable
if (dupIndex == -1)
{
- // Ignore trailing separator.
- if (plen > 1 && p.charAt(plen - 1) == separatorChar)
- return p.substring(0, plen - 1);
+ // Ignore trailing separator (though on Windows "a:\", for
+ // example, is a valid and minimal path).
+ if (plen > 1 && p.charAt (plen - 1) == separatorChar)
+ {
+ if (! (separatorChar == '\\' && plen == 3 && p.charAt (1) == ':'))
+ return p.substring (0, plen - 1);
+ }
else
return p;
}
@@ -120,10 +124,16 @@ public class File implements Serializable, Comparable
dupIndex = p.indexOf(dupSeparator, last);
}
- // Again, ignore possible trailing separator.
+ // Again, ignore possible trailing separator (except special cases
+ // like "a:\" on Windows).
int end;
- if (plen > 1 && p.charAt(plen - 1) == separatorChar)
- end = plen - 1;
+ if (plen > 1 && p.charAt (plen - 1) == separatorChar)
+ {
+ if (separatorChar == '\\' && plen == 3 && p.charAt (1) == ':')
+ end = plen;
+ else
+ end = plen - 1;
+ }
else
end = plen;
newpath.append(p.substring(last, end));
@@ -153,12 +163,47 @@ public class File implements Serializable, Comparable
this (dir == null ? null : dir.path, name);
}
- // FIXME ???
public String getAbsolutePath ()
{
if (isAbsolute ())
return path;
- return System.getProperty("user.dir") + separatorChar + path;
+ else if (separatorChar == '\\'
+ && path.length () > 0 && path.charAt (0) == '\\')
+ {
+ // On Windows, even if the path starts with a '\\' it is not
+ // really absolute until we prefix the drive specifier from
+ // the current working directory to it.
+ return System.getProperty ("user.dir").substring (0, 2) + path;
+ }
+ else if (separatorChar == '\\'
+ && path.length () > 1 && path.charAt (1) == ':'
+ && ((path.charAt (0) >= 'a' && path.charAt (0) <= 'z')
+ || (path.charAt (0) >= 'A' && path.charAt (0) <= 'Z')))
+ {
+ // On Windows, a process has a current working directory for
+ // each drive and a path like "G:foo\bar" would mean the
+ // absolute path "G:\wombat\foo\bar" if "\wombat" is the
+ // working directory on the G drive.
+ String drvDir = null;
+ try
+ {
+ drvDir = new File (path.substring (0, 2)).getCanonicalPath ();
+ }
+ catch (IOException e)
+ {
+ drvDir = path.substring (0, 2) + "\\";
+ }
+
+ // Note: this would return "C:\\." for the path "C:.", if "\"
+ // is the working folder on the C drive, but this is
+ // consistent with what Sun's JRE 1.4.1.01 actually returns!
+ if (path.length () > 2)
+ return drvDir + '\\' + path.substring (2, path.length ());
+ else
+ return drvDir;
+ }
+ else
+ return System.getProperty ("user.dir") + separatorChar + path;
}
/** @since 1.2 */
@@ -177,19 +222,84 @@ public class File implements Serializable, Comparable
public String getName ()
{
- int last = path.lastIndexOf(separatorChar);
- return path.substring(last + 1);
+ int nameSeqIndex = 0;
+
+ if (separatorChar == '\\' && path.length () > 1)
+ {
+ // On Windows, ignore the drive specifier or the leading '\\'
+ // of a UNC network path, if any (a.k.a. the "prefix").
+ if ((path.charAt (0) == '\\' && path.charAt (1) == '\\')
+ || (((path.charAt (0) >= 'a' && path.charAt (0) <= 'z')
+ || (path.charAt (0) >= 'A' && path.charAt (0) <= 'Z'))
+ && path.charAt (1) == ':'))
+ {
+ if (path.length () > 2)
+ nameSeqIndex = 2;
+ else
+ return "";
+ }
+ }
+
+ String nameSeq
+ = (nameSeqIndex > 0 ? path.substring (nameSeqIndex) : path);
+
+ int last = nameSeq.lastIndexOf (separatorChar);
+
+ return nameSeq.substring (last + 1);
}
public String getParent ()
{
- int last = path.lastIndexOf(separatorChar);
- if (last == -1)
+ String prefix = null;
+ int nameSeqIndex = 0;
+
+ // The "prefix", if present, is the leading "/" on UNIX and
+ // either the drive specifier (e.g. "C:") or the leading "\\"
+ // of a UNC network path on Windows.
+ if (separatorChar == '/' && path.charAt (0) == '/')
+ {
+ prefix = "/";
+ nameSeqIndex = 1;
+ }
+ else if (separatorChar == '\\' && path.length () > 1)
+ {
+ if ((path.charAt (0) == '\\' && path.charAt (1) == '\\')
+ || (((path.charAt (0) >= 'a' && path.charAt (0) <= 'z')
+ || (path.charAt (0) >= 'A' && path.charAt (0) <= 'Z'))
+ && path.charAt (1) == ':'))
+ {
+ prefix = path.substring (0, 2);
+ nameSeqIndex = 2;
+ }
+ }
+
+ // According to the JDK docs, the returned parent path is the
+ // portion of the name sequence before the last separator
+ // character, if found, prefixed by the prefix, otherwise null.
+ if (nameSeqIndex < path.length ())
+ {
+ String nameSeq = path.substring (nameSeqIndex, path.length ());
+ int last = nameSeq.lastIndexOf (separatorChar);
+ if (last == -1)
+ return prefix;
+ else if (last == (nameSeq.length () - 1))
+ // Note: The path would not have a trailing separator
+ // except for cases like "C:\" on Windows (see
+ // normalizePath( )), where Sun's JRE 1.4 returns null.
+ return null;
+ else if (last == 0)
+ last++;
+
+ if (prefix != null)
+ return prefix + nameSeq.substring (0, last);
+ else
+ return nameSeq.substring (0, last);
+ }
+ else
+ // Sun's JRE 1.4 returns null if the prefix is the only
+ // component of the path - so "/" gives null on UNIX and
+ // "C:", "\\", etc. return null on Windows.
return null;
- // FIXME: POSIX assumption.
- if (last == 0 && path.charAt (0) == '/')
- ++last;
- return path.substring(0, last);
}
/** @since 1.2 */
@@ -289,8 +399,14 @@ public class File implements Serializable, Comparable
public URL toURL () throws MalformedURLException
{
- return new URL ("file://" + getAbsolutePath ()
- + (isDirectory() ? "/" : ""));
+ // On Win32, Sun's JDK returns URLs of the form "file:/c:/foo/bar.txt",
+ // while on UNIX, it returns URLs of the form "file:/foo/bar.txt".
+ if (separatorChar == '\\')
+ return new URL ("file:/" + getAbsolutePath ().replace ('\\', '/')
+ + (isDirectory() ? "/" : ""));
+ else
+ return new URL ("file:" + getAbsolutePath ()
+ + (isDirectory() ? "/" : ""));
}
private final native boolean performMkdir ();