1 21 22 package org.armedbear.lisp; 23 24 import java.io.File ; 25 import java.io.FileInputStream ; 26 import java.io.FileNotFoundException ; 27 import java.io.IOException ; 28 import java.io.InputStream ; 29 import java.net.URL ; 30 import java.util.ArrayList ; 31 32 public final class Load extends Lisp 33 { 34 public static final LispObject load(String 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 filename, 45 boolean verbose, 46 boolean print, 47 boolean ifDoesNotExist) 48 throws ConditionThrowable 49 { 50 File file = null; 51 boolean isFile = false; 52 if (Utilities.isFilenameAbsolute(filename)) { 53 file = new File (filename); 54 if (file != null) { 55 isFile = file.isFile(); 56 if (!isFile) { 57 String extension = getExtension(filename); 58 if (extension == null) { 59 file = new File (filename.concat(".lisp")); 61 isFile = file.isFile(); 62 } 63 } 64 } 65 } else { 66 String dir = 68 Pathname.coerceToPathname(_DEFAULT_PATHNAME_DEFAULTS_.symbolValue()).getNamestring(); 69 file = new File (dir, filename); 70 if (file != null) { 71 isFile = file.isFile(); 72 if (!isFile) { 73 String extension = getExtension(filename); 74 if (extension == null) { 75 file = new File (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 truename = filename; 89 InputStream in = null; 90 try { 91 in = new FileInputStream (file); 92 truename = file.getCanonicalPath(); 93 } 94 catch (FileNotFoundException e) { 95 if (ifDoesNotExist) 96 return signal(new FileError("File not found: " + filename)); 97 else 98 return NIL; 99 } 100 catch (IOException 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 sb = new StringBuffer ("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 e) { 116 return signal(new LispError(e.getMessage())); 117 } 118 } 119 } 120 121 public static final LispObject loadSystemFile(String 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 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 filename, 158 boolean verbose, 159 boolean print, 160 boolean auto) 161 throws ConditionThrowable 162 { 163 final int ARRAY_SIZE = 2; 164 String [] candidates = new String [ARRAY_SIZE]; 165 String extension = getExtension(filename); 166 if (extension == null) { 167 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 in = null; 177 Pathname pathname = null; 178 String truename = null; 179 for (int i = 0; i < ARRAY_SIZE; i++) { 180 String s = candidates[i]; 181 if (s == null) 182 break; 183 final String dir = Site.getLispHome(); 184 if (dir != null) { 185 File file = new File (dir, s); 186 if (file.isFile()) { 187 try { 188 in = new FileInputStream (file); 189 truename = file.getCanonicalPath(); 190 } 191 catch (IOException e) { 192 in = null; 193 } 194 } 195 } else { 196 URL 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 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 sb = 215 new StringBuffer ("; 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 e) { 224 return signal(new LispError(e.getMessage())); 225 } 226 } 227 } 228 } 229 return signal(new LispError("file not found: " + filename)); 230 } 231 232 public static final Symbol _FASL_SOURCE_ = 235 internSpecial("*FASL-SOURCE*", PACKAGE_SYS, NIL); 236 237 private static final Symbol _FASL_VERSION_ = 240 internConstant("*FASL-VERSION*", PACKAGE_SYS, new Fixnum(13)); 241 242 public static final Symbol _FASL_ANONYMOUS_PACKAGE_ = 245 internSpecial("*FASL-ANONYMOUS-PACKAGE*", PACKAGE_SYS, NIL); 246 247 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 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 truename, 274 InputStream 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 thread.bindSpecial(_SPEED_, _SPEED_.symbolValue(thread)); 288 thread.bindSpecial(_SAFETY_, _SAFETY_.symbolValue(thread)); 289 final String 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 getLoadVerbosePrefix(int loadDepth) 323 { 324 StringBuffer sb = new StringBuffer (";"); 325 for (int i = loadDepth - 1; i-- > 0;) 326 sb.append(' '); 327 return sb.toString(); 328 } 329 330 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 ()); 344 } 345 symbol = ((Package )pkg).intern(symbol.getName()); 346 symbol.setPackage(NIL); 347 return symbol; 348 } 349 }; 350 351 private static final LispObject loadStream(InputStream 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 private static final String getExtension(String filename) 381 { 382 int index = filename.lastIndexOf('.'); 383 if (index < 0) 384 return null; 385 if (index < filename.lastIndexOf(File.separatorChar)) 386 return null; return filename.substring(index); 388 } 389 390 private static final String getPath(URL url) 391 { 392 if (url != null) { 393 String 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 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 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 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 |