Not logged in.  Login/Logout/Register | List snippets | | Create snippet | Upload image | Upload data

511
LINES

< > BotCompany Repo | #588 // x6.java

Java source code

1  
import java.io.*;
2  
import java.net.URL;
3  
import java.net.URLConnection;
4  
import java.security.MessageDigest;
5  
import java.security.NoSuchAlgorithmException;
6  
import java.util.ArrayList;
7  
import java.util.List;
8  
import java.util.regex.Matcher;
9  
import java.util.regex.Pattern;
10  
11  
/**
12  
  Changes to v5:
13  
    "with" argument (e.g. "with 587")
14  
    "output=" argument
15  
 */
16  
17  
public class x6 {
18  
  static boolean verbose = false;
19  
  static boolean v2mode = true; // the heck...
20  
21  
  private static String isCompilable = "http://tinybrain.de/"
22  
    + /*"564"*/"1000251"; // silenced version (but I think we're silencing now anyway)
23  
  private static String isCompilableHash = "8fe3851d7a686b60546a2429a2bde0d9";
24  
25  
  private static String mainAdder = "http://tinybrain.de/1000252";
26  
  private static String mainAdderHash = "ce1e89785facd87ea64a6d9ad16a7aec";
27  
28  
  static List<String> translators = new ArrayList<String>();
29  
30  
  public static void main(String[] args) throws IOException {
31  
    File ioBaseDir = new File("."), inputDir = null, outputDir = null;
32  
    String src = ".";
33  
    for (int i = 0; i < args.length; i++) {
34  
      String arg = args[i];
35  
      if (arg.equals("-v"))
36  
        verbose = true;
37  
      else if (arg.equals("-v2"))
38  
        v2mode = true;
39  
      else if (arg.equals("-finderror"))
40  
        verbose = v2mode = true;
41  
      else if (arg.startsWith("input="))
42  
        inputDir = new File(arg.substring(6));
43  
      else if (arg.startsWith("output="))
44  
        outputDir = new File(arg.substring(7));
45  
      else if (arg.equals("with"))
46  
        translators.add(args[++i]);
47  
      else
48  
        src = arg;
49  
    }
50  
51  
    if (inputDir != null) {
52  
      ioBaseDir = TempDirMaker_make();
53  
      System.out.println("Taking input from: " + inputDir.getAbsolutePath());
54  
      System.out.println("Output is in: " + new File(ioBaseDir, "output").getAbsolutePath());
55  
      copyInput(inputDir, new File(ioBaseDir, "input"));
56  
    }
57  
58  
    javax4(src, ioBaseDir);
59  
60  
    if (outputDir != null) {
61  
      copyInput(new File(ioBaseDir, "output"), outputDir);
62  
      System.out.println("Output copied to: " + outputDir.getAbsolutePath());
63  
    }
64  
  }
65  
66  
  public static void javax4(String src, File ioDir) throws IOException {
67  
    File srcDir;
68  
    if (isSnippetID(src))
69  
      srcDir = loadSnippetAsMainJava(src);
70  
    else
71  
      srcDir = new File(src);
72  
    File X = programToInput(srcDir);
73  
74  
    X = applyTranslators(X);
75  
76  
    if (!v2mode) {
77  
      boolean compilable = isCompilable(X);
78  
      if (verbose) System.out.println("Compilable: " + compilable);
79  
      if (!compilable) {
80  
        X = expandProgram(X);
81  
        File file = new File(X, "main.java");
82  
        String program = loadTextFile(file.getPath(), null);
83  
        if (verbose) System.out.println("New program:\n" + program);
84  
        if (program == null)
85  
          throw new RuntimeException("Expansion failed (tried: " + file.getPath() + ")");
86  
      }
87  
    }
88  
89  
    File Y = luaPrintToJavaPrint(X);
90  
    javax2(Y, ioDir, false);
91  
  }
92  
93  
  private static File applyTranslators(File x) throws IOException {
94  
    for (String translator : translators) {
95  
      if (verbose)
96  
        System.out.println("Using translator " + translator + " on sources in " + x.getPath());
97  
      File newDir = runJavaX2_src_from_snippet(translator, null, x, true);
98  
      if (verbose)
99  
        System.out.println("Translated with " + translator + " from " + x.getPath() + " to " + newDir.getPath());
100  
      x = newDir;
101  
    }
102  
    return x;
103  
  }
104  
105  
  private static File luaPrintToJavaPrint(File x) throws IOException {
106  
    File newDir = TempDirMaker_make();
107  
    String code = loadTextFile(new File(x, "main.java").getPath(), null);
108  
    code = luaPrintToJavaPrint(code);
109  
    if (verbose)
110  
      System.out.println(code);
111  
    saveTextFile(new File(newDir, "main.java").getPath(), code);
112  
    return newDir;
113  
  }
114  
115  
  public static String luaPrintToJavaPrint(String code) {
116  
    return ("\n" + code).replaceAll(
117  
      "(\n\\s*)print (\".*\")",
118  
      "$1System.out.println($2);").substring(1);
119  
  }
120  
121  
  public static File loadSnippetAsMainJava(String snippetID) throws IOException {
122  
    File srcDir = TempDirMaker_make();
123  
    saveTextFile(new File(srcDir, "main.java").getPath(), loadSnippet(snippetID, false));
124  
    return srcDir;
125  
  }
126  
127  
  public static File loadSnippetAsMainJavaVerified(String snippetID, String hash) throws IOException {
128  
    File srcDir = TempDirMaker_make();
129  
    saveTextFile(new File(srcDir, "main.java").getPath(), loadSnippetVerified(snippetID, hash));
130  
    return srcDir;
131  
  }
132  
133  
  private static File expandProgram(File x) throws IOException {
134  
    return runJavaX2_src_from_snippet(mainAdder, mainAdderHash, x, true);
135  
  }
136  
137  
  private static boolean isCompilable(File x) throws IOException {
138  
    File output = runJavaX2_src_from_snippet(isCompilable, isCompilableHash, x, true);
139  
    return hasFile(output, "is-compilable");
140  
  }
141  
142  
  /** returns output dir */
143  
  private static File runJavaX2_src_from_snippet(String snippetID, String hash, File input, boolean silent) throws IOException {
144  
    File srcDir = hash == null ? loadSnippetAsMainJava(snippetID)
145  
      : loadSnippetAsMainJavaVerified(snippetID, hash);
146  
    return runJavaX(srcDir, input, silent);
147  
  }
148  
149  
  /** returns output dir */
150  
  private static File runJavaX(File originalSrcDir, File originalInput, boolean silent) throws IOException {
151  
    File ioBaseDir = TempDirMaker_make();
152  
    File srcDir = new File(ioBaseDir, "src");
153  
    File inputDir = new File(ioBaseDir, "input");
154  
    File input = inputDir;
155  
    File outputDir = new File(ioBaseDir, "output");
156  
    File output = outputDir;
157  
    copyInput(originalSrcDir, srcDir);
158  
    copyInput(originalInput, input);
159  
    javax2(srcDir, ioBaseDir, silent);
160  
    return output;
161  
  }
162  
163  
  private static void copyInput(File src, File dst) throws IOException {
164  
    copyDirectory(src, dst);
165  
  }
166  
167  
  private static File programToInput(File srcDir) {
168  
    return srcDir;
169  
  }
170  
171  
  public static boolean hasFile(File inputDir, String name) {
172  
    return new File(inputDir, name).exists();
173  
  }
174  
175  
  public static void copyDirectory(File src, File dst) throws IOException {
176  
    if (verbose) System.out.println("Copying " + src.getAbsolutePath() + " to " + dst.getAbsolutePath());
177  
    dst.mkdirs();
178  
    File[] files = src.listFiles();
179  
    if (files == null) return;
180  
    for (File file : files) {
181  
      File dst1 = new File(dst, file.getName());
182  
      if (file.isDirectory())
183  
        copyDirectory(file, dst1);
184  
      else {
185  
        if (verbose) System.out.println("Copying " + file.getAbsolutePath() + " to " + dst1.getAbsolutePath());
186  
        copy(file, dst1);
187  
      }
188  
    }
189  
  }
190  
191  
  /** Quickly copy a file without a progress bar or any other fancy GUI... :) */
192  
  public static void copy(File src, File dest) throws IOException {
193  
    FileInputStream inputStream = new FileInputStream(src);
194  
    FileOutputStream outputStream = new FileOutputStream(dest);
195  
    try {
196  
      copy(inputStream, outputStream);
197  
      inputStream.close();
198  
    } finally {
199  
      outputStream.close();
200  
    }
201  
  }
202  
203  
  public static void copy(InputStream in, OutputStream out) throws IOException {
204  
    byte[] buf = new byte[65536];
205  
    while (true) {
206  
      int n = in.read(buf);
207  
      if (n <= 0) return;
208  
      out.write(buf, 0, n);
209  
    }
210  
  }
211  
212  
  /** writes safely (to temp file, then rename) */
213  
  public static void saveTextFile(String fileName, String contents) throws IOException {
214  
    File file = new File(fileName);
215  
    File parentFile = file.getParentFile();
216  
    if (parentFile != null)
217  
      parentFile.mkdirs();
218  
    String tempFileName = fileName + "_temp";
219  
    FileOutputStream fileOutputStream = new FileOutputStream(tempFileName);
220  
    OutputStreamWriter outputStreamWriter = new OutputStreamWriter(fileOutputStream, charsetForTextFiles);
221  
    PrintWriter printWriter = new PrintWriter(outputStreamWriter);
222  
    printWriter.print(contents);
223  
    printWriter.close();
224  
    if (file.exists() && !file.delete())
225  
      throw new IOException("Can't delete " + fileName);
226  
227  
    if (!new File(tempFileName).renameTo(file))
228  
      throw new IOException("Can't rename " + tempFileName + " to " + fileName);
229  
  }
230  
231  
  public static String loadTextFile(String fileName, String defaultContents) throws IOException {
232  
    if (!new File(fileName).exists())
233  
      return defaultContents;
234  
235  
    FileInputStream fileInputStream = new FileInputStream(fileName);
236  
    InputStreamReader inputStreamReader = new InputStreamReader(fileInputStream, charsetForTextFiles);
237  
    return loadTextFile(inputStreamReader);
238  
  }
239  
240  
  public static String loadTextFile(Reader reader) throws IOException {
241  
    StringBuilder builder = new StringBuilder();
242  
    try {
243  
      BufferedReader bufferedReader = new BufferedReader(reader);
244  
      String line;
245  
      while ((line = bufferedReader.readLine()) != null)
246  
        builder.append(line).append('\n');
247  
    } finally {
248  
      reader.close();
249  
    }
250  
    return builder.length() == 0 ? "" : builder.substring(0, builder.length()-1);
251  
  }
252  
253  
  static File DiskSnippetCache_dir;
254  
255  
  public static void initDiskSnippetCache(File dir) {
256  
    DiskSnippetCache_dir = dir;
257  
    dir.mkdirs();
258  
  }
259  
260  
  public static synchronized String DiskSnippetCache_get(long snippetID) throws IOException {
261  
    return loadTextFile(DiskSnippetCache_getFile(snippetID).getPath(), null);
262  
  }
263  
264  
  private static File DiskSnippetCache_getFile(long snippetID) {
265  
    return new File(DiskSnippetCache_dir, "" + snippetID);
266  
  }
267  
268  
  public static synchronized void DiskSnippetCache_put(long snippetID, String snippet) throws IOException {
269  
    saveTextFile(DiskSnippetCache_getFile(snippetID).getPath(), snippet);
270  
  }
271  
272  
  public static File DiskSnippetCache_getDir() {
273  
    return DiskSnippetCache_dir;
274  
  }
275  
276  
  public static void initSnippetCache() {
277  
    if (DiskSnippetCache_dir == null)
278  
      initDiskSnippetCache(new File(System.getProperty("user.home"), ".tinybrain/snippet-cache"));
279  
  }
280  
281  
  public static String loadSnippetVerified(String snippetID, String hash) throws IOException {
282  
    String text = loadSnippet(snippetID, !hash.isEmpty());
283  
    String realHash = getHash(text.getBytes("UTF-8"));
284  
    if (!realHash.equals(hash)) {
285  
      String msg;
286  
      if (hash.isEmpty())
287  
        msg = "Here's your hash for " + snippetID + ", please put in your program: " + realHash;
288  
      else
289  
        msg = "Hash mismatch for " + snippetID + ": " + realHash + " (new) vs " + hash + " - has tinybrain.de been hacked??";
290  
      throw new RuntimeException(msg);
291  
    }
292  
    return text;
293  
  }
294  
295  
  public static String getHash(byte[] data) {
296  
    return bytesToHex(getFullFingerprint(data));
297  
  }
298  
299  
  public static byte[] getFullFingerprint(byte[] data) {
300  
    try {
301  
      return MessageDigest.getInstance("MD5").digest(data);
302  
    } catch (NoSuchAlgorithmException e) {
303  
      throw new RuntimeException(e);
304  
    }
305  
  }
306  
307  
  public static String bytesToHex(byte[] bytes) {
308  
    return bytesToHex(bytes, 0, bytes.length);
309  
  }
310  
311  
  public static String bytesToHex(byte[] bytes, int ofs, int len) {
312  
    StringBuilder stringBuilder = new StringBuilder(len*2);
313  
    for (int i = 0; i < len; i++) {
314  
      String s = "0" + Integer.toHexString(bytes[ofs+i]);
315  
      stringBuilder.append(s.substring(s.length()-2, s.length()));
316  
    }
317  
    return stringBuilder.toString();
318  
  }
319  
320  
  public static String loadSnippet(String snippetID, boolean preferCached) throws IOException {
321  
    return loadSnippet(parseSnippetID(snippetID), preferCached);
322  
  }
323  
324  
  public static long parseSnippetID(String snippetID) {
325  
    return Long.parseLong(shortenSnippetID(snippetID));
326  
  }
327  
328  
  private static String shortenSnippetID(String snippetID) {
329  
    if (snippetID.startsWith("#"))
330  
      snippetID = snippetID.substring(1);
331  
    String httpBlaBla = "http://tinybrain.de/";
332  
    if (snippetID.startsWith(httpBlaBla))
333  
      snippetID = snippetID.substring(httpBlaBla.length());
334  
    return snippetID;
335  
  }
336  
337  
  public static boolean isSnippetID(String snippetID) {
338  
    snippetID = shortenSnippetID(snippetID);
339  
    return isInteger(snippetID) && Long.parseLong(snippetID) != 0;
340  
  }
341  
342  
  public static boolean isInteger(String s) {
343  
    return Pattern.matches("\\-?\\d+", s);
344  
  }
345  
346  
  public static String loadSnippet(long snippetID, boolean preferCached) throws IOException {
347  
    if (preferCached) {
348  
      initSnippetCache();
349  
      String text = DiskSnippetCache_get(snippetID);
350  
      if (text != null)
351  
        return text;
352  
    }
353  
354  
    String text;
355  
    try {
356  
      URL url = new URL("http://tinybrain.de:8080/getraw.php?id=" + snippetID);
357  
      text = loadPage(url);
358  
    } catch (FileNotFoundException e) {
359  
      throw new IOException("Snippet #" + snippetID + " not found or not public");
360  
    }
361  
362  
    try {
363  
      initSnippetCache();
364  
      DiskSnippetCache_put(snippetID, text);
365  
    } catch (IOException e) {
366  
      System.err.println("Minor warning: Couldn't save snippet to cache ("  + DiskSnippetCache_getDir() + ")");
367  
    }
368  
369  
    return text;
370  
  }
371  
372  
  private static String loadPage(URL url) throws IOException {
373  
    System.out.println("Loading: " + url.toExternalForm());
374  
    URLConnection con = url.openConnection();
375  
    return loadPage(con, url);
376  
  }
377  
378  
  public static String loadPage(URLConnection con, URL url) throws IOException {
379  
    String contentType = con.getContentType();
380  
    if (contentType == null)
381  
      throw new IOException("Page could not be read: " + url);
382  
    //Log.info("Content-Type: " + contentType);
383  
    String charset = guessCharset(contentType);
384  
    Reader r = new InputStreamReader(con.getInputStream(), charset);
385  
    StringBuilder buf = new StringBuilder();
386  
    while (true) {
387  
      int ch = r.read();
388  
      if (ch < 0)
389  
        break;
390  
      //Log.info("Chars read: " + buf.length());
391  
      buf.append((char) ch);
392  
    }
393  
    return buf.toString();
394  
  }
395  
396  
  public static String guessCharset(String contentType) {
397  
    Pattern p = Pattern.compile("text/html;\\s+charset=([^\\s]+)\\s*");
398  
    Matcher m = p.matcher(contentType);
399  
    /* If Content-Type doesn't match this pre-conception, choose default and hope for the best. */
400  
    return m.matches() ? m.group(1) : "ISO-8859-1";
401  
  }
402  
403  
  public static void javax2(File srcDir, File ioBaseDir, boolean silent) throws IOException {
404  
    List<File> sources = new ArrayList<File>();
405  
    if (verbose) System.out.println("Scanning for sources in " + srcDir.getPath());
406  
    scanForSources(srcDir, sources, true);
407  
    if (sources.isEmpty()) {
408  
      System.out.println("No sources found");
409  
      return;
410  
    }
411  
    File optionsFile = File.createTempFile("javax", "");
412  
    File classesDir = TempDirMaker_make();
413  
    if (verbose) System.out.println("Compiling " + sources.size() + " source(s) to " + classesDir.getPath());
414  
    String options = "-d " + bashQuote(classesDir.getPath());
415  
    writeOptions(sources, optionsFile, options);
416  
    classesDir.mkdirs();
417  
    invokeJavac(optionsFile);
418  
    if (verbose) System.out.println("Running program (class main.java)\n");
419  
    runProgram(classesDir, ioBaseDir, silent);
420  
  }
421  
422  
  private static void runProgram(File classesDir, File ioBaseDir, boolean silent) throws IOException {
423  
    boolean echoOK = false;
424  
    String bashCmd = "(cd " + bashQuote(ioBaseDir.getAbsolutePath()) + " && (java -cp "
425  
      + bashQuote(classesDir.getAbsolutePath()) + " main" + (echoOK ? "; echo ok" : "") + "))";
426  
    if (verbose) System.out.println(bashCmd);
427  
    String output = backtick(bashCmd);
428  
    if (!silent)
429  
      System.out.println(output);
430  
  }
431  
432  
  private static void invokeJavac(File optionsFile) throws IOException {
433  
    String javacOutput = backtick("javac " + bashQuote("@" + optionsFile.getPath()));
434  
    if (verbose) System.out.println(javacOutput);
435  
  }
436  
437  
  private static void writeOptions(List<File> sources, File sourcesFile, String moreOptions) throws IOException {
438  
    FileWriter writer = new FileWriter(sourcesFile);
439  
    for (File source : sources)
440  
      writer.write(bashQuote(source.getPath()) + " ");
441  
    writer.write(moreOptions);
442  
    writer.close();
443  
  }
444  
445  
  private static void scanForSources(File source, List<File> sources, boolean topLevel) {
446  
    if (source.isFile() && source.getName().endsWith(".java"))
447  
      sources.add(source);
448  
    else if (source.isDirectory() && !isSkippedDirectoryName(source.getName(), topLevel)) {
449  
      File[] files = source.listFiles();
450  
      for (File file : files)
451  
        scanForSources(file, sources, false);
452  
    }
453  
  }
454  
455  
  private static boolean isSkippedDirectoryName(String name, boolean topLevel) {
456  
    if (topLevel) return false; // input or output ok as highest directory (intentionally specified by user, not just found by a directory scan in which case we probably don't want it. it's more like heuristics actually.)
457  
    return name.equalsIgnoreCase("input") || name.equalsIgnoreCase("output");
458  
  }
459  
460  
  public static String backtick(String cmd) throws IOException {
461  
    File outFile = File.createTempFile("_backtick", "");
462  
    File scriptFile = File.createTempFile("_backtick", "");
463  
464  
    String command = cmd + ">" + bashQuote(outFile.getPath()) + " 2>&1";
465  
    //Log.info("[Backtick] " + command);
466  
    try {
467  
      saveTextFile(scriptFile.getPath(), command);
468  
      String[] command2 = {"/bin/bash", scriptFile.getPath() };
469  
      Process process = Runtime.getRuntime().exec(command2);
470  
      try {
471  
        process.waitFor();
472  
      } catch (InterruptedException e) {
473  
        throw new RuntimeException(e);
474  
      }
475  
      int value = process.exitValue();
476  
      //Log.info("exit value: " + value);
477  
      return loadTextFile(outFile.getPath(), "");
478  
    } finally {
479  
      scriptFile.delete();
480  
    }
481  
  }
482  
483  
  /** possibly improvable */
484  
  public static String bashQuote(String text) {
485  
    if (text == null) return null;
486  
    return "\"" + text
487  
      .replace("\\", "\\\\")
488  
      .replace("\"", "\\\"")
489  
      .replace("\n", "\\n")
490  
      .replace("\r", "\\r") + "\"";
491  
  }
492  
493  
  public final static String charsetForTextFiles = "UTF8";
494  
495  
  static long TempDirMaker_lastValue;
496  
497  
  public static File TempDirMaker_make() {
498  
    File dir = new File(System.getProperty("user.home"), ".javax/" + TempDirMaker_newValue());
499  
    dir.mkdirs();
500  
    return dir;
501  
  }
502  
503  
  private static long TempDirMaker_newValue() {
504  
    long value;
505  
    do
506  
      value = System.currentTimeMillis();
507  
    while (value == TempDirMaker_lastValue);
508  
    TempDirMaker_lastValue = value;
509  
    return value;
510  
  }
511  
}

download  show line numbers   

Travelled to 12 computer(s): aoiabmzegqzx, bhatertpkbcr, cbybwowwnfue, gwrvuhgaqvyk, ishqpsrjomds, lpdgvwnxivlt, mqqgnosmbjvj, pyentgdyhuwx, pzhvpgtvlbxg, tslmcundralx, tvejysmllsmz, vouqrxazstgt

No comments. add comment

Snippet ID: #588
Snippet name: x6.java
Eternal ID of this version: #588/1
Text MD5: cc14a97e91b962b118a2e63515bb8fb6
Author: stefan
Category: javax
Type: Java source code
Public (visible to everyone): Yes
Archived (hidden from active list): No
Created/modified: 2015-04-24 20:04:09
Source code size: 18585 bytes / 511 lines
Pitched / IR pitched: No / Yes
Views / Downloads: 744 / 172
Referenced in: [show references]