001: /*
002: * Pathname.java
003: *
004: * Copyright (C) 2003 Peter Graves
005: * $Id: Pathname.java,v 1.6 2003/11/15 11:03:31 beedlem Exp $
006: *
007: * This program is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU General Public License
009: * as published by the Free Software Foundation; either version 2
010: * of the License, or (at your option) any later version.
011: *
012: * This program is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
015: * GNU General Public License for more details.
016: *
017: * You should have received a copy of the GNU General Public License
018: * along with this program; if not, write to the Free Software
019: * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
020: */
021:
022: package org.armedbear.lisp;
023:
024: import java.io.File;
025:
026: // FIXME Not much of an implementation...
027: public final class Pathname extends LispObject {
028: private String namestring;
029:
030: private Pathname(String namestring) {
031: this .namestring = namestring;
032: }
033:
034: private Pathname(String directory, String name) {
035: StringBuffer sb = new StringBuffer();
036: if (directory != null && directory.length() > 0) {
037: sb.append(directory);
038: if (!directory.endsWith(File.separator))
039: sb.append(File.separator);
040: }
041: if (name != null && name.length() > 0) {
042: sb.append(name);
043: }
044: namestring = sb.toString();
045: }
046:
047: public LispObject typeOf() {
048: return Symbol.PATHNAME;
049: }
050:
051: public LispClass classOf() {
052: return BuiltInClass.PATHNAME;
053: }
054:
055: public LispObject typep(LispObject type) throws ConditionThrowable {
056: if (type == Symbol.PATHNAME)
057: return T;
058: if (type == BuiltInClass.PATHNAME)
059: return T;
060: return super .typep(type);
061: }
062:
063: public String getNamestring() {
064: return namestring;
065: }
066:
067: public boolean equal(LispObject obj) {
068: if (this == obj)
069: return true;
070: if (obj instanceof Pathname) {
071: if (Utilities.isPlatformWindows())
072: return namestring.equalsIgnoreCase(((Pathname) obj)
073: .getNamestring());
074: return namestring.equals(((Pathname) obj).getNamestring());
075: }
076: return false;
077: }
078:
079: public String toString() {
080: StringBuffer sb = new StringBuffer("#P");
081: sb.append('"');
082: sb.append(getNamestring());
083: sb.append('"');
084: return sb.toString();
085: }
086:
087: public static Pathname parseNamestring(String namestring)
088: throws ConditionThrowable {
089: return new Pathname(namestring);
090: }
091:
092: // ### namestring
093: // namestring pathname => namestring
094: // FIXME arg can be a stream, too...
095: private static final Primitive1 NAMESTRING = new Primitive1(
096: "namestring") {
097: public LispObject execute(LispObject arg)
098: throws ConditionThrowable {
099: if (arg instanceof LispString)
100: return arg;
101: if (arg instanceof Pathname)
102: return new LispString(((Pathname) arg).getNamestring());
103: throw new ConditionThrowable(new TypeError(arg,
104: "pathname designator"));
105: }
106: };
107:
108: // ### directory-namestring
109: // directory-namestring pathname => namestring
110: // FIXME arg can be a stream, too...
111: private static final Primitive1 DIRECTORY_NAMESTRING = new Primitive1(
112: "directory-namestring") {
113: public LispObject execute(LispObject arg)
114: throws ConditionThrowable {
115: String namestring;
116: if (arg instanceof LispString)
117: namestring = ((LispString) arg).getValue();
118: else if (arg instanceof Pathname)
119: namestring = ((Pathname) arg).getNamestring();
120: else
121: throw new ConditionThrowable(new TypeError(arg,
122: "pathname designator"));
123: if (namestring != null) {
124: for (int i = namestring.length(); i-- > 0;) {
125: char c = namestring.charAt(i);
126: if (c == '/' || c == '\\')
127: return new LispString(namestring.substring(0,
128: i + 1));
129: }
130: }
131: return NIL;
132: }
133: };
134:
135: // ### pathname
136: // pathname pathspec => pathname
137: // FIXME pathspec can be a stream, too...
138: private static final Primitive1 PATHNAME = new Primitive1(
139: "pathname") {
140: public LispObject execute(LispObject arg)
141: throws ConditionThrowable {
142: if (arg instanceof Pathname)
143: return arg;
144: if (arg instanceof LispString)
145: return new Pathname(((LispString) arg).getValue());
146: throw new ConditionThrowable(new TypeError(arg,
147: "pathname designator"));
148: }
149: };
150:
151: // ### %make-pathname
152: // %make-pathname host device directory name type version defaults case =>
153: // pathname
154: // FIXME Very incomplete.
155: private static final Primitive _MAKE_PATHNAME = new Primitive(
156: "%make-pathname", PACKAGE_SYS, false) {
157: public LispObject execute(LispObject[] args)
158: throws ConditionThrowable {
159: if (args.length != 8)
160: throw new ConditionThrowable(
161: new WrongNumberOfArgumentsException(this ));
162: LispObject host = args[0];
163: LispObject device = args[1];
164: LispObject directory = args[2];
165: LispObject name = args[3];
166: LispObject type = args[4];
167: LispObject version = args[5]; // Ignored.
168: LispObject defaults = args[6];
169: LispObject _case = args[7]; // Ignored.
170: // FIXME
171: if (host != NIL || device != NIL || directory != NIL)
172: throw new ConditionThrowable(new LispError(
173: "MAKE-PATHNAME: not implemented"));
174: String d = ""; // directory
175: String n = ""; // name
176: String t = ""; // type
177: String defaultNamestring = null;
178: if (defaults instanceof Pathname)
179: defaultNamestring = ((Pathname) defaults)
180: .getNamestring();
181: else if (defaults instanceof LispString)
182: defaultNamestring = ((LispString) defaults).getValue();
183: if (defaultNamestring != null) {
184: File file = new File(defaultNamestring);
185: d = file.getParent();
186: n = file.getName();
187: int index = n.lastIndexOf('.');
188: if (index >= 0) {
189: t = n.substring(index + 1);
190: n = n.substring(0, index);
191: }
192: }
193: if (name == Keyword.WILD)
194: n = "*";
195: else if (name instanceof LispString)
196: n = ((LispString) name).getValue();
197: if (type == Keyword.WILD)
198: t = "*";
199: else if (type instanceof LispString)
200: t = ((LispString) type).getValue();
201: if (t.length() > 0)
202: n = n + "." + t;
203: return new Pathname(d, n);
204: }
205: };
206:
207: // ### pathnamep
208: private static final Primitive1 PATHNAMEP = new Primitive1(
209: "pathnamep") {
210: public LispObject execute(LispObject arg)
211: throws ConditionThrowable {
212: return arg instanceof Pathname ? T : NIL;
213: }
214: };
215:
216: // ### user-homedir-pathname
217: // user-homedir-pathname &optional host => pathname
218: private static final Primitive USER_HOMEDIR_PATHNAME = new Primitive(
219: "user-homedir-pathname") {
220: public LispObject execute(LispObject[] args)
221: throws ConditionThrowable {
222: switch (args.length) {
223: case 0: {
224: String s = System.getProperty("user.home");
225: // For compatibility with SBCL and ACL (and maybe other
226: // Lisps), we want the namestring of a directory to end
227: // with a '/' on Unix.
228: // FIXME Do we need to do something similar on Windows?
229: if (s.startsWith("/")) {
230: // Unix.
231: if (!s.endsWith("/"))
232: s = s.concat("/");
233: }
234: return new Pathname(s);
235: }
236: case 1:
237: return NIL;
238: default:
239: throw new ConditionThrowable(
240: new WrongNumberOfArgumentsException(this));
241: }
242: }
243: };
244: }
|