1 | import java.util.*; |
2 | import java.io.*; |
3 | import java.util.regex.*; |
4 | import java.net.*; |
5 | |
6 | public class main { |
7 | static String[] standardFunctions = { |
8 | "#2000323/saveTextFile", |
9 | "#2000322/loadTextFile", |
10 | "#2000324/loadMainJava", |
11 | "#2000325/saveMainJava", |
12 | "#2000326/toLines", |
13 | "#2000329/fromLines", |
14 | "#2000330/loadSnippet", |
15 | "#2000330/parseSnippetID", |
16 | "#2000331/makeJavaStringLiteral", |
17 | "#2000367/popupError", |
18 | "#2000368/exitOnFrameClose", |
19 | "#2000378/commonPrefix", |
20 | "#2000379/commonSuffix", |
21 | "#2000442/quote", |
22 | "#2000471/unquote", |
23 | "#2000444/cncToLines", |
24 | "#2000460/bytesToHex", |
25 | "#2000466/loadBinaryPage", |
26 | "#2000464/saveBinaryFile" |
27 | }; |
28 | |
29 | public static void main(String[] args) throws IOException { |
30 | String s = loadMainJava(); |
31 | List<String> defd = findFunctions(s); |
32 | for (int i = 0; i < 2; i++) |
33 | for (String x : standardFunctions) { |
34 | String[] f = x.split("/"); |
35 | if (hasInvocation(s, f[1]) && !defd.contains(f[1])) { |
36 | System.out.println("Adding function: " + f[1] + " (" + f[0] + ")"); |
37 | s = addFunction(s, f[0]); |
38 | |
39 | defd = findFunctions(s); |
40 | //defd.add(f[1]); |
41 | } |
42 | } |
43 | saveMainJava(s); |
44 | } |
45 | |
46 | static boolean hasInvocation(String src, String f) { |
47 | return src.indexOf(f) >= 0; // generous matching :) |
48 | } |
49 | |
50 | static List<String> findFunctions(String src) { |
51 | int[] main = findMain(src); |
52 | src = src.substring(main[0], main[1]); |
53 | /*int idx = src.indexOf("main {"); // yes it's a hack... |
54 | if (idx >= 0) src = src.substring(idx);*/ |
55 | |
56 | //System.out.println("Scanning for functions"); |
57 | List<String> functions = new ArrayList<String>(); |
58 | for (String line : toLines(src)) { |
59 | Matcher matcher = Pattern.compile("static.*\\s+(\\w+)\\(").matcher(line); |
60 | if (matcher.find()) { |
61 | String f = matcher.group(1); |
62 | functions.add(f); |
63 | //System.out.println("Function found: " + f); |
64 | } |
65 | } |
66 | return functions; |
67 | } |
68 | |
69 | public static String addFunction(String s, String fID) throws IOException { |
70 | int[] main = findMain(s); |
71 | int i = s.lastIndexOf('}', main[1]); |
72 | String function = loadSnippet(fID); |
73 | return s.substring(0, i) + "\n" + function +"\n" + s.substring(i); |
74 | } |
75 | |
76 | static findMain(String s) { |
77 | List<String> tok = JavaTok.split(s); |
78 | for (int i = 1; i+2 < tok.size(); i += 2) |
79 | if (tok.get(i).equals("class") && tok.get(i+2).equals("main")) { |
80 | int j = i; |
81 | while (j < tok.size() && !tok.get(j).equals("{")) |
82 | j += 2; |
83 | int k = findEndOfBlock(tok, j); |
84 | return new int[] {cncLength(tok, i), cncLength(tok, k)}; |
85 | } |
86 | |
87 | //throw new RuntimeException("main class not found"); |
88 | return new int[] {0, s.length()}; |
89 | } |
90 | |
91 | static int cncLength(List<String> cnc, int idx) { |
92 | int l = 0; |
93 | for (int i = 0; i < idx; i++) |
94 | l += cnc.get(i).length(); |
95 | return l; |
96 | } |
97 | |
98 | static int findEndOfBlock(List<String> cnc, int i) { |
99 | int j = i+2, level = 1; |
100 | while (j < cnc.size()) { |
101 | if (cnc.get(j).equals("{")) ++level; |
102 | else if (cnc.get(j).equals("}")) --level; |
103 | if (level == 0) |
104 | return j+1; |
105 | ++j; |
106 | } |
107 | return cnc.size(); |
108 | } |
109 | |
110 | public static List<String> toLines(String s) { |
111 | List<String> lines = new ArrayList<String>(); |
112 | int start = 0; |
113 | while (true) { |
114 | int i = toLines_nextLineBreak(s, start); |
115 | if (i < 0) { |
116 | if (s.length() > start) lines.add(s.substring(start)); |
117 | break; |
118 | } |
119 | |
120 | lines.add(s.substring(start, i)); |
121 | if (s.charAt(i) == '\r' && i+1 < s.length() && s.charAt(i+1) == '\n') |
122 | i += 2; |
123 | else |
124 | ++i; |
125 | |
126 | start = i; |
127 | } |
128 | return lines; |
129 | } |
130 | |
131 | private static int toLines_nextLineBreak(String s, int start) { |
132 | for (int i = start; i < s.length(); i++) { |
133 | char c = s.charAt(i); |
134 | if (c == '\r' || c == '\n') |
135 | return i; |
136 | } |
137 | return -1; |
138 | } |
139 | |
140 | static String loadMainJava() throws IOException { |
141 | return loadTextFile("input/main.java", ""); |
142 | } |
143 | |
144 | static void saveMainJava(String s) throws IOException { |
145 | saveTextFile("output/main.java", s); |
146 | } |
147 | |
148 | static String charsetForTextFiles = "UTF-8"; |
149 | |
150 | public static String loadTextFile(String fileName, String defaultContents) throws IOException { |
151 | if (!new File(fileName).exists()) |
152 | return defaultContents; |
153 | |
154 | FileInputStream fileInputStream = new FileInputStream(fileName); |
155 | InputStreamReader inputStreamReader = new InputStreamReader(fileInputStream, charsetForTextFiles); |
156 | return loadTextFile(inputStreamReader); |
157 | } |
158 | |
159 | public static String loadTextFile(Reader reader) throws IOException { |
160 | StringBuilder builder = new StringBuilder(); |
161 | try { |
162 | BufferedReader bufferedReader = new BufferedReader(reader); |
163 | String line; |
164 | while ((line = bufferedReader.readLine()) != null) |
165 | builder.append(line).append('\n'); |
166 | } finally { |
167 | reader.close(); |
168 | } |
169 | return builder.length() == 0 ? "" : builder.substring(0, builder.length()-1); |
170 | } |
171 | |
172 | /** writes safely (to temp file, then rename) */ |
173 | public static void saveTextFile(String fileName, String contents) throws IOException { |
174 | File file = new File(fileName); |
175 | File parentFile = file.getParentFile(); |
176 | if (parentFile != null) |
177 | parentFile.mkdirs(); |
178 | String tempFileName = fileName + "_temp"; |
179 | FileOutputStream fileOutputStream = new FileOutputStream(tempFileName); |
180 | OutputStreamWriter outputStreamWriter = new OutputStreamWriter(fileOutputStream, charsetForTextFiles); |
181 | PrintWriter printWriter = new PrintWriter(outputStreamWriter); |
182 | printWriter.print(contents); |
183 | printWriter.close(); |
184 | if (file.exists() && !file.delete()) |
185 | throw new IOException("Can't delete " + fileName); |
186 | |
187 | if (!new File(tempFileName).renameTo(file)) |
188 | throw new IOException("Can't rename " + tempFileName + " to " + fileName); |
189 | } |
190 | |
191 | public static String loadSnippet(String snippetID) throws IOException { |
192 | return loadSnippet(snippetID, preferCached); |
193 | } |
194 | |
195 | public static String loadSnippet(String snippetID, boolean preferCached) throws IOException { |
196 | return loadSnippet(parseSnippetID(snippetID), preferCached); |
197 | } |
198 | |
199 | public static long parseSnippetID(String snippetID) { |
200 | return Long.parseLong(shortenSnippetID(snippetID)); |
201 | } |
202 | |
203 | private static String shortenSnippetID(String snippetID) { |
204 | if (snippetID.startsWith("#")) |
205 | snippetID = snippetID.substring(1); |
206 | String httpBlaBla = "http://tinybrain.de/"; |
207 | if (snippetID.startsWith(httpBlaBla)) |
208 | snippetID = snippetID.substring(httpBlaBla.length()); |
209 | return snippetID; |
210 | } |
211 | |
212 | public static boolean isSnippetID(String snippetID) { |
213 | snippetID = shortenSnippetID(snippetID); |
214 | return isInteger(snippetID) && Long.parseLong(snippetID) != 0; |
215 | } |
216 | |
217 | public static boolean isInteger(String s) { |
218 | return Pattern.matches("\\-?\\d+", s); |
219 | } |
220 | |
221 | static boolean preferCached = false; |
222 | |
223 | public static String loadSnippet(long snippetID) throws IOException { |
224 | return loadSnippet(snippetID, preferCached); |
225 | } |
226 | |
227 | public static String loadSnippet(long snippetID, boolean preferCached) throws IOException { |
228 | if (preferCached) { |
229 | initSnippetCache(); |
230 | String text = DiskSnippetCache_get(snippetID); |
231 | if (text != null) |
232 | return text; |
233 | } |
234 | |
235 | String text; |
236 | try { |
237 | URL url = new URL("http://tinybrain.de:8080/getraw.php?id=" + snippetID); |
238 | text = loadPage(url); |
239 | } catch (FileNotFoundException e) { |
240 | throw new IOException("Snippet #" + snippetID + " not found or not public"); |
241 | } |
242 | |
243 | try { |
244 | initSnippetCache(); |
245 | DiskSnippetCache_put(snippetID, text); |
246 | } catch (IOException e) { |
247 | System.err.println("Minor warning: Couldn't save snippet to cache (" + DiskSnippetCache_getDir() + ")"); |
248 | } |
249 | |
250 | return text; |
251 | } |
252 | |
253 | private static String loadPage(URL url) throws IOException { |
254 | System.out.println("Loading: " + url.toExternalForm()); |
255 | URLConnection con = url.openConnection(); |
256 | return loadPage(con, url); |
257 | } |
258 | |
259 | public static String loadPage(URLConnection con, URL url) throws IOException { |
260 | String contentType = con.getContentType(); |
261 | if (contentType == null) |
262 | throw new IOException("Page could not be read: " + url); |
263 | //Log.info("Content-Type: " + contentType); |
264 | String charset = guessCharset(contentType); |
265 | Reader r = new InputStreamReader(con.getInputStream(), charset); |
266 | StringBuilder buf = new StringBuilder(); |
267 | while (true) { |
268 | int ch = r.read(); |
269 | if (ch < 0) |
270 | break; |
271 | //Log.info("Chars read: " + buf.length()); |
272 | buf.append((char) ch); |
273 | } |
274 | return buf.toString(); |
275 | } |
276 | |
277 | public static String guessCharset(String contentType) { |
278 | Pattern p = Pattern.compile("text/html;\\s+charset=([^\\s]+)\\s*"); |
279 | Matcher m = p.matcher(contentType); |
280 | /* If Content-Type doesn't match this pre-conception, choose default and hope for the best. */ |
281 | return m.matches() ? m.group(1) : "ISO-8859-1"; |
282 | } |
283 | |
284 | static File DiskSnippetCache_dir; |
285 | |
286 | public static void initDiskSnippetCache(File dir) { |
287 | DiskSnippetCache_dir = dir; |
288 | dir.mkdirs(); |
289 | } |
290 | |
291 | public static synchronized String DiskSnippetCache_get(long snippetID) throws IOException { |
292 | return loadTextFile(DiskSnippetCache_getFile(snippetID).getPath(), null); |
293 | } |
294 | |
295 | private static File DiskSnippetCache_getFile(long snippetID) { |
296 | return new File(DiskSnippetCache_dir, "" + snippetID); |
297 | } |
298 | |
299 | public static synchronized void DiskSnippetCache_put(long snippetID, String snippet) throws IOException { |
300 | saveTextFile(DiskSnippetCache_getFile(snippetID).getPath(), snippet); |
301 | } |
302 | |
303 | public static File DiskSnippetCache_getDir() { |
304 | return DiskSnippetCache_dir; |
305 | } |
306 | |
307 | public static void initSnippetCache() { |
308 | if (DiskSnippetCache_dir == null) |
309 | initDiskSnippetCache(new File(System.getProperty("user.home"), ".tinybrain/snippet-cache")); |
310 | } |
311 | } |
Began life as a copy of #629
download show line numbers debug dex old transpilations
Travelled to 13 computer(s): aoiabmzegqzx, bhatertpkbcr, cbybwowwnfue, cfunsshuasjs, gwrvuhgaqvyk, ishqpsrjomds, lpdgvwnxivlt, mqqgnosmbjvj, pyentgdyhuwx, pzhvpgtvlbxg, tslmcundralx, tvejysmllsmz, vouqrxazstgt
No comments. add comment
Snippet ID: | #698 |
Snippet name: | Standard Function Adder (new, developing) |
Eternal ID of this version: | #698/1 |
Text MD5: | e9ceee0f813f9cb67e31993669e826ec |
Author: | stefan |
Category: | javax |
Type: | JavaX translator |
Public (visible to everyone): | Yes |
Archived (hidden from active list): | No |
Created/modified: | 2015-08-01 18:25:51 |
Source code size: | 10208 bytes / 311 lines |
Pitched / IR pitched: | No / Yes |
Views / Downloads: | 722 / 664 |
Referenced in: | [show references] |