Merge changes Icaf1ef7f,I979c222a,I9e05ee0b,I798a4707,I7732f3ec

* changes:
  Add options to PrologMain to emulate usage in Gerrit
  Cleanup formatting of PrologMain
  Correct usage for cafeteria java_binary()
  Remove version from PrologMain header
  Add missing fake_pom_deploy.xml required by buck build deploy
diff --git a/fake_pom_deploy.xml b/fake_pom_deploy.xml
new file mode 100644
index 0000000..dec372e
--- /dev/null
+++ b/fake_pom_deploy.xml
@@ -0,0 +1,21 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0">
+  <modelVersion>4.0.0</modelVersion>
+  <groupId>com.googlecode.prolog-cafe</groupId>
+  <artifactId>prolog-cafe</artifactId>
+  <version>1</version> <!-- Do not edit; see BUCK. -->
+  <build>
+    <extensions>
+      <extension>
+        <groupId>com.googlesource.gerrit</groupId>
+        <artifactId>gs-maven-wagon</artifactId>
+        <version>3.3</version>
+      </extension>
+    </extensions>
+  </build>
+  <pluginRepositories>
+    <pluginRepository>
+      <id>gerrit-maven-repository</id>
+      <url>https://gerrit-maven.storage.googleapis.com/</url>
+    </pluginRepository>
+  </pluginRepositories>
+</project>
diff --git a/src/repl/PrologMain.java b/src/repl/PrologMain.java
index 95952b6..6e4b004 100644
--- a/src/repl/PrologMain.java
+++ b/src/repl/PrologMain.java
@@ -1,106 +1,154 @@
 package com.googlecode.prolog_cafe.repl;
+
 import com.googlecode.prolog_cafe.exceptions.HaltException;
+import com.googlecode.prolog_cafe.lang.JavaObjectTerm;
 import com.googlecode.prolog_cafe.lang.ListTerm;
 import com.googlecode.prolog_cafe.lang.Prolog;
 import com.googlecode.prolog_cafe.lang.StructureTerm;
 import com.googlecode.prolog_cafe.lang.SymbolTerm;
 import com.googlecode.prolog_cafe.lang.Term;
 
-import java.util.EnumSet;
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileReader;
+import java.io.PrintStream;
+import java.io.PushbackReader;
+import java.util.ArrayList;
+import java.util.LinkedHashSet;
+import java.util.List;
 import java.util.StringTokenizer;
-/**
- * Prolog Cafe launcher.
- * The <code>PrologMain</code> class launchs the Prolog Cafe system.<br>
- * The usage is as follows, where 
- * <code>package</code> is a package name, and 
- * <code>predicate</code> is a predicate name (only atom).
- * <pre>
- *   % java -cp $PLCAFEDIR/plcafe.jar com.googlecode.prolog_cafe.lang.PrologMain package:predicate
- *   % java -cp $PLCAFEDIR/plcafe.jar com.googlecode.prolog_cafe.lang.PrologMain predicate
- * </pre>
- * Let us show a sample session for launching a small Prolog interpreter:
- * <code>com.googlecode.prolog_cafe.builtin:cafeteria/0</code>.<br>
- * <pre>
- *    % java  -cp $PLCAFEDIR/plcafe.jar:$CLASSPATH com.googlecode.prolog_cafe.lang.PrologMain com.googlecode.prolog_cafe.builtin:cafeteria
- *    Prolog Cafe X.X.X (YYY)
- *    Copyright(C) 1997-200X M.Banbara and N.Tamura
- *    | ?- 
- * </pre>
- *
- * @author Mutsunori Banbara (banbara@kobe-u.ac.jp)
- * @author Naoyuki Tamura (tamura@kobe-u.ac.jp)
- * @version 1.0
- */
+
+/** Launches the meta-interpreter from the command line. */
 public class PrologMain {
-    /** Version information */
-    public static final String VERSION   = "Prolog Cafe 1.2.5 (mantis)";
-    /** Copyright information */
-    public static final String COPYRIGHT = "Copyright(C) 1997-2009 M.Banbara and N.Tamura";
+  private static final String COPYRIGHT = "Copyright(C) 1997-2009 M.Banbara and N.Tamura";
+  private static final String HEADER = "Prolog Cafe (" + COPYRIGHT + ")";
 
-    public static void main(String argv[]) {
-	BlockingPrologControl p;
-	try {
-	    System.err.println("\n" + VERSION); 
-	    System.err.println(COPYRIGHT);
-	    if (argv.length != 1) {
-		usage();
-		System.exit(999);
-	    } 
-	    Term arg1 = Prolog.Nil;
-	    arg1 = new ListTerm(SymbolTerm.intern("user"), arg1);
-	    arg1 = new ListTerm(SymbolTerm.intern(Prolog.BUILTIN), arg1);
-	    Term arg2 = parseAtomicGoal(argv[0]);
-	    if (arg2  == null) {
-		usage();
-		System.exit(1);
-	    }
+  public static void main(String argv[]) {
+    try {
+      System.err.println(HEADER);
 
-	    p = new BlockingPrologControl();
-	    p.setEnabled(EnumSet.allOf(Prolog.Feature.class), true);
-	    p.configureUserIO(System.in, System.out, System.err);
-	    p.setPredicate(Prolog.BUILTIN, "initialization", arg1, arg2);
-	    for (boolean r = p.call(); r; r = p.redo()) {}
-	    System.exit(0);
-	} catch (HaltException e) {
-	    System.exit(e.getStatus());
-	} catch (Exception e){
-	    e.printStackTrace();
-	    System.exit(1);
-	}
+      BlockingPrologControl p = new BlockingPrologControl();
+      p.configureUserIO(System.in, System.out, System.err);
+      p.setMaxDatabaseSize(256);
+
+      List<File> toLoad = new ArrayList<>(4);
+      long reductionLimit = Long.MAX_VALUE;
+      Term goal = null;
+      for (int i = 0; i < argv.length; i++) {
+        String arg = argv[i];
+        if (arg.equals("--enable-io")) {
+          p.setEnabled(Prolog.Feature.IO, true);
+        } else if (arg.equals("--enable-statistics")) {
+          p.setEnabled(Prolog.Feature.STATISTICS, true);
+        } else if (arg.startsWith("--max-database-size=")) {
+          String v = arg.substring(arg.indexOf('=') + 1);
+          p.setMaxDatabaseSize(Integer.parseInt(v, 10));
+        } else if (arg.startsWith("--reduction-limit=")) {
+          String v = arg.substring(arg.indexOf('=') + 1);
+          reductionLimit = Long.parseLong(v, 10);
+        } else if (arg.equals("-f") && i + 1 < argv.length) {
+          toLoad.add(new File(argv[++i]));
+        } else if (arg.startsWith("-")) {
+          usage();
+          System.exit(1);
+        } else if (i == argv.length - 1) {
+          goal = parseAtomicGoal(arg);
+        } else {
+          usage();
+          System.exit(1);
+        }
+      }
+
+      initializePackages(p, goal);
+      for (File file : toLoad) {
+        try (FileReader src = new FileReader(file);
+            BufferedReader buf = new BufferedReader(src);
+            PushbackReader in = new PushbackReader(buf, Prolog.PUSHBACK_SIZE)) {
+          Term path = SymbolTerm.create(file.getPath());
+          if (!p.execute(Prolog.BUILTIN, "consult_stream",
+              path, new JavaObjectTerm(in))) {
+            System.err.println();
+            System.err.flush();
+            System.exit(1);
+          }
+        }
+        System.err.println();
+        System.err.flush();
+      }
+
+      if (goal == null) {
+        System.err.println();
+        System.err.flush();
+        goal = new StructureTerm(SymbolTerm.intern(":", 2), new Term[]{
+          SymbolTerm.intern(Prolog.BUILTIN),
+          SymbolTerm.create("cafeteria")});
+      }
+
+      p.setReductionLimit(reductionLimit);
+      p.execute(Prolog.BUILTIN, "call", goal);
+    } catch (HaltException e) {
+      System.exit(e.getStatus());
+    } catch (Exception e) {
+      e.printStackTrace();
+      System.exit(1);
+    }
+  }
+
+  /**
+   * Returns a term for given string representation of atom goal, or
+   * <code>null</code> if parsing fails.
+   *
+   * @param s a string representation of initial goal (ex. foge:main).
+   * @return a term which corresponds to a given string, or <code>null</code> if
+   *         parsing fails.
+   */
+  private static Term parseAtomicGoal(String s) {
+    StringTokenizer st = new StringTokenizer(s, ":");
+    int i = st.countTokens();
+    if (i == 1) {
+      Term[] args = {
+          SymbolTerm.intern("user"),
+          SymbolTerm.create(st.nextToken())};
+      return new StructureTerm(SymbolTerm.intern(":", 2), args);
+    } else if (i == 2) {
+      Term[] args = {
+          SymbolTerm.create(st.nextToken()),
+          SymbolTerm.create(st.nextToken())};
+      return new StructureTerm(SymbolTerm.intern(":", 2), args);
+    } else {
+      return null;
+    }
+  }
+
+  private static void initializePackages(BlockingPrologControl p, Term goal) {
+    LinkedHashSet<String> set = new LinkedHashSet<>(3);
+    set.add(Prolog.BUILTIN);
+    set.add("user");
+    if (goal != null) {
+      set.add(goal.arg(1).name());
     }
 
-    /** Returns a term for given string representation of atom goal, or 
-     * <code>null</code> if parsing fails.
-     * @param s  a string representation of initial goal (ex. foge:main).
-     * @return a term which corresponds to a given string,
-     * or <code>null</code> if parsing fails.
-     */
-    protected static Term parseAtomicGoal(String s) {
-	StringTokenizer st = new StringTokenizer(s, ":");
-	int i = st.countTokens();
-	if (i == 1) {
-	    Term[] args = {SymbolTerm.intern("user"), 
-			   SymbolTerm.create(st.nextToken())};
-	    return new StructureTerm(SymbolTerm.intern(":", 2), args);
-	} else if (i == 2) {
-	    Term[] args = {SymbolTerm.create(st.nextToken()), 
-			   SymbolTerm.create(st.nextToken())};
-	    return new StructureTerm(SymbolTerm.intern(":", 2), args);
-	} else {
-	    return null;
-	}
+    List<String> list = new ArrayList<>(set);
+    Term done = SymbolTerm.intern("true");
+    Term head = Prolog.Nil;
+    for (int i = list.size() - 1; 0 <= i; i--) {
+      head = new ListTerm(SymbolTerm.intern(list.get(i)), head);
     }
+    p.execute(Prolog.BUILTIN, "initialization", head, done);
+  }
 
-    /** Shows usage */
-    protected static void usage() {
-	String s = "Usage:\n";
-	s += "java -cp $PLCAFEDIR/plcafe.jar";
-	s += " com.googlecode.prolog_cafe.lang.PrologMain package:predicate\n";
-	s += "java -cp $PLCAFEDIR/plcafe.jar";
-	s += " com.googlecode.prolog_cafe.lang.PrologMain predicate\n";
-	s += "    package:        package name\n";
-	s += "    predicate:      predicate name (only atom)";
-	System.out.println(s);
-    }
+  private static void usage() {
+    PrintStream e = System.err;
+    e.println("usage:  java -jar cafeteria.jar [options] [goal]");
+    e.println();
+    e.println("  --enable-io           : enable file system access");
+    e.println("  --enable-statistics   : enable statistics/2");
+    e.println("  --max-database-size=N : maximum entries in dynamic database");
+    e.println("  --reduction-limit=N   : max reductions during execution");
+    e.println();
+    e.println("   -f source.pl         : load file.pl  (may be repeated)");
+    e.println();
+    e.println("  goal :          predicate or package:predicate");
+    e.println("                  (if not specified, runs interactive loop)");
+  }
 }
-