KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > armedbear > lisp > Load


1 /*
2  * Load.java
3  *
4  * Copyright (C) 2002-2004 Peter Graves
5  * $Id: Load.java,v 1.77 2004/09/24 18:05:50 piso Exp $
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20  */

21
22 package org.armedbear.lisp;
23
24 import java.io.File JavaDoc;
25 import java.io.FileInputStream JavaDoc;
26 import java.io.FileNotFoundException JavaDoc;
27 import java.io.IOException JavaDoc;
28 import java.io.InputStream JavaDoc;
29 import java.net.URL JavaDoc;
30 import java.util.ArrayList JavaDoc;
31
32 public final class Load extends Lisp
33 {
34     public static final LispObject load(String JavaDoc filename)
35         throws ConditionThrowable
36     {
37         final LispThread thread = LispThread.currentThread();
38         return load(filename,
39                     _LOAD_VERBOSE_.symbolValue(thread) != NIL,
40                     _LOAD_PRINT_.symbolValue(thread) != NIL,
41                     true);
42     }
43
44     public static final LispObject load(final String JavaDoc filename,
45                                         boolean verbose,
46                                         boolean print,
47                                         boolean ifDoesNotExist)
48         throws ConditionThrowable
49     {
50         File JavaDoc file = null;
51         boolean isFile = false;
52         if (Utilities.isFilenameAbsolute(filename)) {
53             file = new File JavaDoc(filename);
54             if (file != null) {
55                 isFile = file.isFile();
56                 if (!isFile) {
57                     String JavaDoc extension = getExtension(filename);
58                     if (extension == null) {
59                         // No extension specified. Try appending ".lisp".
60
file = new File JavaDoc(filename.concat(".lisp"));
61                         isFile = file.isFile();
62                     }
63                 }
64             }
65         } else {
66             // Filename is not absolute.
67
String JavaDoc dir =
68                 Pathname.coerceToPathname(_DEFAULT_PATHNAME_DEFAULTS_.symbolValue()).getNamestring();
69             file = new File JavaDoc(dir, filename);
70             if (file != null) {
71                 isFile = file.isFile();
72                 if (!isFile) {
73                     String JavaDoc extension = getExtension(filename);
74                     if (extension == null) {
75                         // No extension specified. Try appending ".lisp".
76
file = new File JavaDoc(dir, filename.concat(".lisp"));
77                         isFile = file.isFile();
78                     }
79                 }
80             }
81         }
82         if (!isFile) {
83             if (ifDoesNotExist)
84                 return signal(new FileError("File not found: " + filename));
85             else
86                 return NIL;
87         }
88         String JavaDoc truename = filename;
89         InputStream JavaDoc in = null;
90         try {
91             in = new FileInputStream JavaDoc(file);
92             truename = file.getCanonicalPath();
93         }
94         catch (FileNotFoundException JavaDoc e) {
95             if (ifDoesNotExist)
96                 return signal(new FileError("File not found: " + filename));
97             else
98                 return NIL;
99         }
100         catch (IOException JavaDoc e) {
101             return signal(new LispError(e.getMessage()));
102         }
103         try {
104             return loadFileFromStream(null, truename, in, verbose, print, false);
105         }
106         catch (FaslVersionMismatch e) {
107             StringBuffer JavaDoc sb = new StringBuffer JavaDoc("Incorrect fasl version: ");
108             sb.append(truename);
109             return signal(new SimpleError(sb.toString()));
110         }
111         finally {
112             try {
113                 in.close();
114             }
115             catch (IOException JavaDoc e) {
116                 return signal(new LispError(e.getMessage()));
117             }
118         }
119     }
120
121     public static final LispObject loadSystemFile(String JavaDoc filename)
122         throws ConditionThrowable
123     {
124         final LispThread thread = LispThread.currentThread();
125         return loadSystemFile(filename,
126                               _LOAD_VERBOSE_.symbolValue(thread) != NIL,
127                               _LOAD_PRINT_.symbolValue(thread) != NIL,
128                               false);
129     }
130
131     public static final LispObject loadSystemFile(String JavaDoc filename, boolean auto)
132         throws ConditionThrowable
133     {
134         LispThread thread = LispThread.currentThread();
135         if (auto) {
136             Environment oldDynEnv = thread.getDynamicEnvironment();
137             thread.bindSpecial(_READTABLE_,
138                                Readtable._STANDARD_READTABLE_.symbolValue(thread));
139             thread.bindSpecial(_PACKAGE_, PACKAGE_CL_USER);
140             try {
141                 return loadSystemFile(filename,
142                                       _AUTOLOAD_VERBOSE_.symbolValue(thread) != NIL,
143                                       _LOAD_PRINT_.symbolValue(thread) != NIL,
144                                       auto);
145             }
146             finally {
147                 thread.setDynamicEnvironment(oldDynEnv);
148             }
149         } else {
150             return loadSystemFile(filename,
151                                   _LOAD_VERBOSE_.symbolValue(thread) != NIL,
152                                   _LOAD_PRINT_.symbolValue(thread) != NIL,
153                                   auto);
154         }
155     }
156
157     public static final LispObject loadSystemFile(final String JavaDoc filename,
158                                                   boolean verbose,
159                                                   boolean print,
160                                                   boolean auto)
161         throws ConditionThrowable
162     {
163         final int ARRAY_SIZE = 2;
164         String JavaDoc[] candidates = new String JavaDoc[ARRAY_SIZE];
165         String JavaDoc extension = getExtension(filename);
166         if (extension == null) {
167             // No extension specified.
168
candidates[0] = filename + '.' + COMPILE_FILE_TYPE;
169             candidates[1] = filename.concat(".lisp");
170         } else if (extension.equals(".abcl")) {
171             candidates[0] = filename;
172             candidates[1] =
173                 filename.substring(0, filename.length() - 5).concat(".lisp");
174         } else
175             candidates[0] = filename;
176         InputStream JavaDoc in = null;
177         Pathname pathname = null;
178         String JavaDoc truename = null;
179         for (int i = 0; i < ARRAY_SIZE; i++) {
180             String JavaDoc s = candidates[i];
181             if (s == null)
182                 break;
183             final String JavaDoc dir = Site.getLispHome();
184             if (dir != null) {
185                 File JavaDoc file = new File JavaDoc(dir, s);
186                 if (file.isFile()) {
187                     try {
188                         in = new FileInputStream JavaDoc(file);
189                         truename = file.getCanonicalPath();
190                     }
191                     catch (IOException JavaDoc e) {
192                         in = null;
193                     }
194                 }
195             } else {
196                 URL JavaDoc url = Lisp.class.getResource(s);
197                 if (url != null) {
198                     try {
199                         in = url.openStream();
200                         if ("jar".equals(url.getProtocol()))
201                             pathname = new Pathname(url);
202                         truename = getPath(url);
203                     }
204                     catch (IOException JavaDoc e) {
205                         in = null;
206                     }
207                 }
208             }
209             if (in != null) {
210                 try {
211                     return loadFileFromStream(pathname, truename, in, verbose, print, auto);
212                 }
213                 catch (FaslVersionMismatch e) {
214                     StringBuffer JavaDoc sb =
215                         new StringBuffer JavaDoc("; Incorrect fasl version: ");
216                     sb.append(truename);
217                     System.err.println(sb.toString());
218                 }
219                 finally {
220                     try {
221                         in.close();
222                     }
223                     catch (IOException JavaDoc e) {
224                         return signal(new LispError(e.getMessage()));
225                     }
226                 }
227             }
228         }
229         return signal(new LispError("file not found: " + filename));
230     }
231
232     // ### *fasl-source*
233
// internal symbol
234
public static final Symbol _FASL_SOURCE_ =
235         internSpecial("*FASL-SOURCE*", PACKAGE_SYS, NIL);
236
237     // ### *fasl-version*
238
// internal symbol
239
private static final Symbol _FASL_VERSION_ =
240         internConstant("*FASL-VERSION*", PACKAGE_SYS, new Fixnum(13));
241
242     // ### *fasl-anonymous-package*
243
// internal symbol
244
public static final Symbol _FASL_ANONYMOUS_PACKAGE_ =
245         internSpecial("*FASL-ANONYMOUS-PACKAGE*", PACKAGE_SYS, NIL);
246
247     // ### init-fasl
248
private static final Primitive2 INIT_FASL =
249         new Primitive2("init-fasl", PACKAGE_SYS, true, "&key version")
250     {
251         public LispObject execute(LispObject first, LispObject second)
252             throws ConditionThrowable
253         {
254             if (first == Keyword.VERSION) {
255                 if (second.eql(_FASL_VERSION_.getSymbolValue())) {
256                     // OK
257
final LispThread thread = LispThread.currentThread();
258                     Readtable readtable = new Readtable(NIL);
259                     readtable.setDispatchMacroCharacter('#', ':', FASL_SHARP_COLON);
260                     thread.bindSpecial(_READTABLE_, readtable);
261                     thread.bindSpecial(_FASL_ANONYMOUS_PACKAGE_, NIL);
262                     thread.bindSpecial(_FASL_SOURCE_, NIL);
263                     thread.bindSpecial(_DEFAULT_PATHNAME_DEFAULTS_,
264                                        _LOAD_TRUENAME_.symbolValue(thread));
265                     return T;
266                 }
267             }
268             throw new FaslVersionMismatch(second);
269         }
270     };
271
272     private static final LispObject loadFileFromStream(Pathname pathname,
273                                                        String JavaDoc truename,
274                                                        InputStream JavaDoc in,
275                                                        boolean verbose,
276                                                        boolean print,
277                                                        boolean auto)
278         throws ConditionThrowable
279     {
280         long start = System.currentTimeMillis();
281         LispThread thread = LispThread.currentThread();
282         Environment oldDynEnv = thread.getDynamicEnvironment();
283         thread.bindSpecial(_PACKAGE_, _PACKAGE_.symbolValue(thread));
284         int loadDepth = Fixnum.getValue(_LOAD_DEPTH_.symbolValue(thread));
285         thread.bindSpecial(_LOAD_DEPTH_, new Fixnum(++loadDepth));
286         // Compiler policy.
287
thread.bindSpecial(_SPEED_, _SPEED_.symbolValue(thread));
288         thread.bindSpecial(_SAFETY_, _SAFETY_.symbolValue(thread));
289         final String JavaDoc prefix = getLoadVerbosePrefix(loadDepth);
290         try {
291             if (pathname == null)
292                 pathname = Pathname.parseNamestring(truename);
293             thread.bindSpecial(_LOAD_PATHNAME_, pathname);
294             thread.bindSpecial(_LOAD_TRUENAME_, pathname);
295             if (verbose) {
296                 Stream out = getStandardOutput();
297                 out.freshLine();
298                 out._writeString(prefix);
299                 out._writeString(auto ? " Autoloading " : " Loading ");
300                 out._writeString(truename);
301                 out._writeLine(" ...");
302                 out._finishOutput();
303                 LispObject result = loadStream(in, print);
304                 long elapsed = System.currentTimeMillis() - start;
305                 out.freshLine();
306                 out._writeString(prefix);
307                 out._writeString(auto ? " Autoloaded " : " Loaded ");
308                 out._writeString(truename);
309                 out._writeString(" (");
310                 out._writeString(String.valueOf(((float)elapsed)/1000));
311                 out._writeLine(" seconds)");
312                 out._finishOutput();
313                 return result;
314             } else
315                 return loadStream(in, print);
316         }
317         finally {
318             thread.setDynamicEnvironment(oldDynEnv);
319         }
320     }
321
322     public static String JavaDoc getLoadVerbosePrefix(int loadDepth)
323     {
324         StringBuffer JavaDoc sb = new StringBuffer JavaDoc(";");
325         for (int i = loadDepth - 1; i-- > 0;)
326             sb.append(' ');
327         return sb.toString();
328     }
329
330     // ### fasl-sharp-colon
331
public static final DispatchMacroFunction FASL_SHARP_COLON =
332         new DispatchMacroFunction("sharp-colon", PACKAGE_SYS, false,
333                                   "stream sub-char numarg")
334     {
335         public LispObject execute(Stream stream, char c, int n)
336             throws ConditionThrowable
337         {
338             LispThread thread = LispThread.currentThread();
339             Symbol symbol = (Symbol) stream.readSymbol();
340             LispObject pkg = _FASL_ANONYMOUS_PACKAGE_.symbolValue(thread);
341             if (pkg == NIL) {
342                 thread.bindSpecial(_FASL_ANONYMOUS_PACKAGE_,
343                                    pkg = new Package JavaDoc());
344             }
345             symbol = ((Package JavaDoc)pkg).intern(symbol.getName());
346             symbol.setPackage(NIL);
347             return symbol;
348         }
349     };
350
351     private static final LispObject loadStream(InputStream JavaDoc inputStream,
352                                                boolean print)
353         throws ConditionThrowable
354     {
355         Stream in = new Stream(inputStream, Symbol.CHARACTER);
356         final LispThread thread = LispThread.currentThread();
357         Environment oldDynEnv = thread.getDynamicEnvironment();
358         thread.bindSpecial(_LOAD_STREAM_, in);
359         try {
360             final Environment env = new Environment();
361             while (true) {
362                 LispObject obj = in.read(false, EOF, true);
363                 if (obj == EOF)
364                     break;
365                 LispObject result = eval(obj, env, thread);
366                 if (print) {
367                     Stream out = getStandardOutput();
368                     out._writeLine(result.writeToString());
369                     out._finishOutput();
370                 }
371             }
372             return T;
373         }
374         finally {
375             thread.setDynamicEnvironment(oldDynEnv);
376         }
377     }
378
379     // Returns extension including leading '.'
380
private static final String JavaDoc getExtension(String JavaDoc filename)
381     {
382         int index = filename.lastIndexOf('.');
383         if (index < 0)
384             return null;
385         if (index < filename.lastIndexOf(File.separatorChar))
386             return null; // Last dot was in path part of filename.
387
return filename.substring(index);
388     }
389
390     private static final String JavaDoc getPath(URL JavaDoc url)
391     {
392         if (url != null) {
393             String JavaDoc path = url.getPath();
394             if (path != null) {
395                 if (Utilities.isPlatformWindows()) {
396                     if (path.length() > 0 && path.charAt(0) == '/')
397                         path = path.substring(1);
398                 }
399                 return path;
400             }
401         }
402         return null;
403     }
404
405     // ### %load filespec verbose print if-does-not-exist => generalized-boolean
406
private static final Primitive4 _LOAD =
407         new Primitive4("%load", PACKAGE_SYS, false,
408                        "filespec verbose print if-does-not-exist")
409     {
410         public LispObject execute(LispObject filespec, LispObject verbose,
411                                   LispObject print, LispObject ifDoesNotExist)
412             throws ConditionThrowable
413         {
414             return load(Pathname.coerceToPathname(filespec).getNamestring(),
415                         verbose != NIL,
416                         print != NIL,
417                         ifDoesNotExist != NIL);
418         }
419     };
420
421     // ### load-system-file
422
private static final Primitive1 LOAD_SYSTEM_FILE =
423         new Primitive1("load-system-file", PACKAGE_SYS, true)
424     {
425         public LispObject execute(LispObject arg) throws ConditionThrowable
426         {
427             final LispThread thread = LispThread.currentThread();
428             return loadSystemFile(arg.getStringValue(),
429                                   _LOAD_VERBOSE_.symbolValue(thread) != NIL,
430                                   _LOAD_PRINT_.symbolValue(thread) != NIL,
431                                   false);
432         }
433     };
434
435     private static class FaslVersionMismatch extends Error JavaDoc
436     {
437         private final LispObject version;
438
439         public FaslVersionMismatch(LispObject version)
440         {
441             this.version = version;
442         }
443
444         public LispObject getVersion()
445         {
446             return version;
447         }
448     }
449 }
450
Popular Tags