/*
 * Copyright © 2002 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
 * California 95054, U.S.A. All rights reserved.  Sun Microsystems, Inc. has
 * intellectual property rights relating to technology embodied in the product
 * that is described in this document. In particular, and without limitation,
 * these intellectual property rights may include one or more of the U.S.
 * patents listed at http://www.sun.com/patents and one or more additional
 * patents or pending patent applications in the U.S. and in other countries.
 * U.S. Government Rights - Commercial software. Government users are subject
 * to the Sun Microsystems, Inc. standard license agreement and applicable
 * provisions of the FAR and its supplements.  Use is subject to license terms.
 * Sun,  Sun Microsystems,  the Sun logo and  Java are trademarks or registered
 * trademarks of Sun Microsystems, Inc. in the U.S. and other countries.  This
 * product is covered and controlled by U.S. Export Control laws and may be
 * subject to the export or import laws in other countries.  Nuclear, missile,
 * chemical biological weapons or nuclear maritime end uses or end users,
 * whether direct or indirect, are strictly prohibited.  Export or reexport
 * to countries subject to U.S. embargo or to entities identified on U.S.
 * export exclusion lists, including, but not limited to, the denied persons
 * and specially designated nationals lists is strictly prohibited.
 */

package org.javacc.parser;

public class Main {

  static void help_message() {
    System.out.println("Usage:");
    System.out.println("    javacc option-settings inputfile");
    System.out.println("");
    System.out.println("\"option-settings\" is a sequence of settings separated by spaces.");
    System.out.println("Each option setting must be of one of the following forms:");
    System.out.println("");
    System.out.println("    -optionname=value (e.g., -STATIC=false)");
    System.out.println("    -optionname:value (e.g., -STATIC:false)");
    System.out.println("    -optionname       (equivalent to -optionname=true.  e.g., -STATIC)");
    System.out.println("    -NOoptionname     (equivalent to -optionname=false. e.g., -NOSTATIC)");
    System.out.println("");
    System.out.println("Option settings are not case-sensitive, so one can say \"-nOsTaTiC\" instead");
    System.out.println("of \"-NOSTATIC\".  Option values must be appropriate for the corresponding");
    System.out.println("option, and must be either an integer, a boolean, or a string value.");
    System.out.println("");
    System.out.println("The integer valued options are:");
    System.out.println("");
    System.out.println("    LOOKAHEAD              (default 1)");
    System.out.println("    CHOICE_AMBIGUITY_CHECK (default 2)");
    System.out.println("    OTHER_AMBIGUITY_CHECK  (default 1)");
    System.out.println("");
    System.out.println("The boolean valued options are:");
    System.out.println("");
    System.out.println("    STATIC                 (default true)");
    System.out.println("    DEBUG_PARSER           (default false)");
    System.out.println("    DEBUG_LOOKAHEAD        (default false)");
    System.out.println("    DEBUG_TOKEN_MANAGER    (default false)");
    System.out.println("    OPTIMIZE_TOKEN_MANAGER (default true)");
    System.out.println("    ERROR_REPORTING        (default true)");
    System.out.println("    JAVA_UNICODE_ESCAPE    (default false)");
    System.out.println("    UNICODE_INPUT          (default false)");
    System.out.println("    IGNORE_CASE            (default false)");
    System.out.println("    COMMON_TOKEN_ACTION    (default false)");
    System.out.println("    USER_TOKEN_MANAGER     (default false)");
    System.out.println("    USER_CHAR_STREAM       (default false)");
    System.out.println("    BUILD_PARSER           (default true)");
    System.out.println("    BUILD_TOKEN_MANAGER    (default true)");
    System.out.println("    TOKEN_MANAGER_USES_PARSER (default false)");
    System.out.println("    SANITY_CHECK           (default true)");
    System.out.println("    FORCE_LA_CHECK         (default false)");
    System.out.println("    CACHE_TOKENS           (default false)");
    System.out.println("    KEEP_LINE_COLUMN       (default true)");
    System.out.println("");
    System.out.println("The string valued options are:");
    System.out.println("");
    System.out.println("    OUTPUT_DIRECTORY       (default Current Directory)");
    System.out.println("    JDK_VERSION       (default 1.4)");
    System.out.println("");
    System.out.println("EXAMPLE:");
    System.out.println("    javacc -STATIC=false -LOOKAHEAD:2 -debug_parser mygrammar.jj");
    System.out.println("");
  }

  /**
   * A main program that exercises the parser.
   */
  public static void main(String args[]) throws Exception {
    int errorcode = mainProgram(args);
    System.exit(errorcode);
  }

  /**
   * The method to call to exercise the parser from other Java programs.
   * It returns an error code.  See how the main program above uses
   * this method.
   */
  public static int mainProgram(String args[]) throws Exception {

    // Initialize all static state
    reInitAll();

    JavaCCGlobals.bannerLine("Parser Generator", "");

    JavaCCParser parser = null;
    if (args.length == 0) {
      System.out.println("");
      help_message();
      return 1;
    } else {
      System.out.println("(type \"javacc\" with no arguments for help)");
    }

    if (Options.isOption(args[args.length-1])) {
      System.out.println("Last argument \"" + args[args.length-1] + "\" is not a filename.");
      return 1;
    }
    for (int arg = 0; arg < args.length-1; arg++) {
      if (!Options.isOption(args[arg])) {
        System.out.println("Argument \"" + args[arg] + "\" must be an option setting.");
        return 1;
      }
      Options.setCmdLineOption(args[arg]);
    }

    try {
      java.io.File fp = new java.io.File(args[args.length-1]);
      if (!fp.exists()) {
         System.out.println("File " + args[args.length-1] + " not found.");
         return 1;
      }
      if (fp.isDirectory()) {
         System.out.println(args[args.length-1] + " is a directory. Please use a valid file name.");
         return 1;
      }
      parser = new JavaCCParser(new java.io.FileReader(args[args.length-1]));
    } catch (NullPointerException ne) { // Should never happen
    } catch (SecurityException se) {
      System.out.println("Security voilation while trying to open " + args[args.length-1]);
      return 1;
    } catch (java.io.FileNotFoundException e) {
      System.out.println("File " + args[args.length-1] + " not found.");
      return 1;
    }

    try {
      System.out.println("Reading from file " + args[args.length-1] + " . . .");
      JavaCCGlobals.fileName = JavaCCGlobals.origFileName = args[args.length-1];
      JavaCCGlobals.jjtreeGenerated = JavaCCGlobals.isGeneratedBy("JJTree", args[args.length-1]);
      JavaCCGlobals.jjcovGenerated = JavaCCGlobals.isGeneratedBy("JJCov", args[args.length-1]);
      JavaCCGlobals.toolNames = JavaCCGlobals.getToolNames(args[args.length-1]);
      parser.javacc_input();
      JavaCCGlobals.createOutputDir(Options.getOutputDirectory());

      if (Options.getUnicodeInput())
      {
         NfaState.unicodeWarningGiven = true;
         System.out.println("Note: UNICODE_INPUT option is specified. " +
              "Please make sure you create the parser/lexer using a Reader with the correct character encoding.");
      }

      Semanticize.start();
      ParseGen.start();
      LexGen.start();
      OtherFilesGen.start();

      if ((JavaCCErrors.get_error_count() == 0) && (Options.getBuildParser() || Options.getBuildTokenManager())) {
        if (JavaCCErrors.get_warning_count() == 0) {
          System.out.println("Parser generated successfully.");
        } else {
          System.out.println("Parser generated with 0 errors and "
                             + JavaCCErrors.get_warning_count() + " warnings.");
        }
        return 0;
      } else {
        System.out.println("Detected " + JavaCCErrors.get_error_count() + " errors and "
                           + JavaCCErrors.get_warning_count() + " warnings.");
        return (JavaCCErrors.get_error_count()==0)?0:1;
      }
    } catch (MetaParseException e) {
      System.out.println("Detected " + JavaCCErrors.get_error_count() + " errors and "
                         + JavaCCErrors.get_warning_count() + " warnings.");
      return 1;
    } catch (ParseException e) {
      System.out.println(e.toString());
      System.out.println("Detected " + (JavaCCErrors.get_error_count()+1) + " errors and "
                         + JavaCCErrors.get_warning_count() + " warnings.");
      return 1;
    }
  }

   public static void reInitAll()
   {
      org.javacc.parser.Expansion.reInit();
      org.javacc.parser.JavaCCErrors.reInit();
      org.javacc.parser.JavaCCGlobals.reInit();
      Options.init();
      org.javacc.parser.JavaCCParserInternals.reInit();
      org.javacc.parser.RStringLiteral.reInit();
      org.javacc.parser.JavaFiles.reInit();
      org.javacc.parser.LexGen.reInit();
      org.javacc.parser.NfaState.reInit();
      org.javacc.parser.MatchInfo.reInit();
      org.javacc.parser.LookaheadWalk.reInit();
      org.javacc.parser.Semanticize.reInit();
      org.javacc.parser.ParseGen.reInit();
      org.javacc.parser.OtherFilesGen.reInit();
      org.javacc.parser.ParseEngine.reInit();
   }

}
