KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > kawa > standard > define_autoload


1 // Copyright (C) 2000 Per M.A. Bothner.
2
// This is free software; for terms and warranty disclaimer see ../../COPYING.
3

4 package kawa.standard;
5 import gnu.expr.*;
6 import kawa.lang.*;
7 import gnu.lists.*;
8 import java.io.File JavaDoc;
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 JavaDoc name, boolean fromFile)
22   {
23     super(name);
24     this.fromFile = fromFile;
25   }
26
27   public boolean scanForDefinitions (Pair st, java.util.Vector JavaDoc 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 JavaDoc 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 JavaDoc names = p.car;
52     Object JavaDoc 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 JavaDoc filespec, ScopeExp defs, Translator tr)
64   {
65     if (filespec.endsWith(".el"))
66       ;
67     File JavaDoc file = new File JavaDoc(filespec);
68     if (! file.isAbsolute())
69       file = new File JavaDoc(new File JavaDoc(tr.getFileName()).getParent(), filespec);
70     String JavaDoc filename = file.getPath();
71     int dot = filename.lastIndexOf('.');
72     Language language;
73     if (dot >= 0)
74       {
75     String JavaDoc 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     /*
85     // Since (module-name ...) is not handled in this pass,
86     // we won't see it until its too late. FIXME.
87     ModuleExp module = tr.getModule();
88     String prefix = module == null ? null : module.getName();
89     System.err.println("module:"+module);
90     if (prefix == null)
91       prefix = kawa.repl.compilationPrefix;
92     else
93       {
94         int i = prefix.lastIndexOf('.');
95         if (i < 0)
96           prefix = null;
97         else
98           prefix = prefix.substring(0, i+1);
99       }
100     */

101     String JavaDoc prefix = tr.classPrefix;
102     int extlen = extension.length();
103     int speclen = filespec.length();
104     String JavaDoc 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 JavaDoc 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 JavaDoc 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 JavaDoc filename,
135                        ScopeExp defs, Translator tr)
136     throws java.io.IOException JavaDoc, gnu.text.SyntaxException
137   {
138     boolean lineStart = true;
139     String JavaDoc 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; // No match.
171
}
172         if (i > 0)
173           {
174         Object JavaDoc form = in.readObject();
175         if (form instanceof Pair)
176           {
177             Pair pair = (Pair) form;
178             Object JavaDoc value = null;
179             String JavaDoc name = null;
180             Object JavaDoc car = pair.car;
181             String JavaDoc command
182               = car instanceof String JavaDoc ? 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 JavaDoc skipped = in.readObject(ch);
224         if (skipped == Sequence.eofValue)
225           return;
226       }
227       }
228   }
229
230   public static boolean process(Object JavaDoc names, Object JavaDoc filename,
231                    java.util.Vector JavaDoc 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 JavaDoc fn;
243     int len;
244
245     /*
246     if (names == "*" && filename instanceof String
247     && (len = (fn = (String) filename).length()) > 2
248     && fn.charAt(0) == '<' && fn.charAt(len-1) == '>')
249       {
250     fn = fn.substring(1, len-1);
251     try
252       {
253         Class fclass = Class.forName(fn);
254         Object instance = require.find(ctype, env);
255         ...;
256       }
257     catch (ClassNotFoundException ex)
258       {
259         tr.syntaxError("class <"+fn+"> not found");
260         return false;
261       }
262       }
263     */

264
265     if (names instanceof String JavaDoc || names instanceof Symbol)
266       {
267     String JavaDoc name = names.toString();
268     Declaration decl = defs.getDefine(name, 'w', tr);
269     if (filename instanceof String JavaDoc
270         && (len = (fn = (String JavaDoc) filename).length()) > 2
271         && fn.charAt(0) == '<' && fn.charAt(len-1) == '>')
272       filename = fn.substring(1, len-1);
273     Object JavaDoc 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