1 4 package kawa.standard; 5 import gnu.expr.*; 6 import kawa.lang.*; 7 import gnu.lists.*; 8 import java.io.File ; 9 import gnu.mapping.*; 10 import gnu.kawa.lispexpr.*; 11 12 public class define_autoload extends Syntax 13 { 14 public static final define_autoload define_autoload 15 = new define_autoload("define-autoload", false); 16 public static final define_autoload define_autoloads_from_file 17 = new define_autoload("define-autoloads-from-file", true); 18 19 boolean fromFile; 20 21 public define_autoload (String name, boolean fromFile) 22 { 23 super(name); 24 this.fromFile = fromFile; 25 } 26 27 public boolean scanForDefinitions (Pair st, java.util.Vector forms, 28 ScopeExp defs, Translator tr) 29 { 30 if (! (st.cdr instanceof Pair)) 31 return super.scanForDefinitions(st, forms, defs, tr); 32 Pair p = (Pair) st.cdr; 33 if (fromFile) 34 { 35 for (;;) 36 { 37 if (! (p.car instanceof FString)) 38 break; 39 if (! scanFile(p.car.toString(), defs, tr)) 40 return false; 41 Object rest = p.cdr; 42 if (rest == LList.Empty) 43 return true; 44 if (! (rest instanceof Pair)) 45 break; 46 p = (Pair) p.cdr; 47 } 48 tr.syntaxError("invalid syntax for define-autoloads-from-file"); 49 return false; 50 } 51 Object names = p.car; 52 Object filename = null; 53 if (p.cdr instanceof Pair) 54 { 55 p = (Pair) p.cdr; 56 filename = p.car; 57 return process(names, filename, forms, defs, tr); 58 } 59 tr.syntaxError("invalid syntax for define-autoload"); 60 return false; 61 } 62 63 public boolean scanFile(String filespec, ScopeExp defs, Translator tr) 64 { 65 if (filespec.endsWith(".el")) 66 ; 67 File file = new File (filespec); 68 if (! file.isAbsolute()) 69 file = new File (new File (tr.getFileName()).getParent(), filespec); 70 String filename = file.getPath(); 71 int dot = filename.lastIndexOf('.'); 72 Language language; 73 if (dot >= 0) 74 { 75 String extension = filename.substring(dot); 76 language = Language.getInstance(extension); 77 if (language == null) 78 { 79 tr.syntaxError("unknown extension for "+filename); 80 return true; 81 } 82 gnu.text.Lexer lexer; 83 84 101 String prefix = tr.classPrefix; 102 int extlen = extension.length(); 103 int speclen = filespec.length(); 104 String cname = filespec.substring(0, speclen - extlen); 105 while (cname.startsWith("../")) 106 { 107 int i = prefix.lastIndexOf('.', prefix.length() - 2); 108 if (i < 0) 109 { 110 tr.syntaxError("cannot use relative filename \"" + filespec 111 + "\" with simple prefix \"" + prefix + "\""); 112 return false; 113 } 114 prefix = prefix.substring(0, i+1); 115 cname = cname.substring(3); 116 } 117 String classname = (prefix + cname).replace('/', '.'); 118 119 try 120 { 121 InPort port = InPort.openFile(filename); 122 lexer = language.getLexer(port, tr.getMessages()); 123 findAutoloadComments((LispReader) lexer, classname, defs, tr); 124 } 125 catch (Exception ex) 126 { 127 tr.syntaxError("error reading "+filename+": "+ex); 128 return true; 129 } 130 } 131 return true; 132 } 133 134 public static void findAutoloadComments (LispReader in, String filename, 135 ScopeExp defs, Translator tr) 136 throws java.io.IOException , gnu.text.SyntaxException 137 { 138 boolean lineStart = true; 139 String magic = ";;;###autoload"; 140 int magicLength = magic.length(); 141 mainLoop: 142 for (;;) 143 { 144 int ch = in.peek(); 145 if (ch < 0) 146 return; 147 if (ch == '\n' || ch == '\r') 148 { 149 in.read(); 150 lineStart = true; 151 continue; 152 } 153 if (lineStart && ch == ';') 154 { 155 int i = 0; 156 for (;;) 157 { 158 if (i == magicLength) 159 break; 160 ch = in.read(); 161 if (ch < 0) 162 return; 163 if (ch == '\n' || ch == '\r') 164 { 165 lineStart = true; 166 continue mainLoop; 167 } 168 if (i < 0 || ch == magic.charAt(i++)) 169 continue; 170 i = -1; } 172 if (i > 0) 173 { 174 Object form = in.readObject(); 175 if (form instanceof Pair) 176 { 177 Pair pair = (Pair) form; 178 Object value = null; 179 String name = null; 180 Object car = pair.car; 181 String command 182 = car instanceof String ? car.toString() 183 : car instanceof Symbol ? ((Symbol) car).getName() 184 : null; 185 if (command == "defun") 186 { 187 name = ((Pair)pair.cdr).car.toString(); 188 value = new AutoloadProcedure(name, filename, 189 tr.getLanguage()); 190 } 191 else 192 tr.error('w', "unsupported ;;;###autoload followed by: " 193 + pair.car); 194 if (value != null) 195 { 196 Declaration decl = defs.getDefine(name, 'w', tr); 197 Expression ex = new QuoteExp(value); 198 decl.setFlag(Declaration.IS_CONSTANT); 199 decl.noteValue(ex); 200 decl.setProcedureDecl(true); 201 decl.setType(Compilation.typeProcedure); 202 } 203 } 204 lineStart = false; 205 continue; 206 } 207 } 208 lineStart = false; 209 in.skip(); 210 if (ch == '#') 211 { 212 if (in.peek() == '|') 213 { 214 in.skip(); 215 in.readNestedComment('#', '|'); 216 continue; 217 } 218 } 219 if (Character.isWhitespace ((char)ch)) 220 ; 221 else 222 { 223 Object skipped = in.readObject(ch); 224 if (skipped == Sequence.eofValue) 225 return; 226 } 227 } 228 } 229 230 public static boolean process(Object names, Object filename, 231 java.util.Vector forms, 232 ScopeExp defs, Translator tr) 233 { 234 if (names instanceof Pair) 235 { 236 Pair p = (Pair) names; 237 return (process(p.car, filename, forms, defs, tr) 238 && process(p.cdr, filename, forms, defs, tr)); 239 } 240 if (names == LList.Empty) 241 return true; 242 String fn; 243 int len; 244 245 264 265 if (names instanceof String || names instanceof Symbol) 266 { 267 String name = names.toString(); 268 Declaration decl = defs.getDefine(name, 'w', tr); 269 if (filename instanceof String 270 && (len = (fn = (String ) filename).length()) > 2 271 && fn.charAt(0) == '<' && fn.charAt(len-1) == '>') 272 filename = fn.substring(1, len-1); 273 Object value = new AutoloadProcedure(name, filename.toString(), 274 tr.getLanguage()); 275 Expression ex = new QuoteExp(value); 276 decl.setFlag(Declaration.IS_CONSTANT); 277 decl.noteValue(ex); 278 return true; 279 } 280 return false; 281 } 282 283 public Expression rewriteForm (Pair form, Translator tr) 284 { 285 return null; 286 } 287 } 288 | Popular Tags |