/** Eliminates all non-normal variables from varInfos. See isNormalVar() for details. */
 private static VarInfo[] filterNonVars(VarInfo[] varInfos) {
   List<VarInfo> filteredList = new ArrayList<VarInfo>();
   for (int i = 0; i < varInfos.length; i++) {
     if (isNormalVar(varInfos[i])) {
       filteredList.add(varInfos[i]);
     } else {
       // System.out.println("filterNonVars removed " + varInfos[i].name.name());
     }
   }
   return filteredList.toArray(new VarInfo[0]);
 }
 /**
  * requires: condition is a string representation of a conditional
  *
  * @return a list of all possible variable variable names in condition. arrays appear with "[]" at
  *     the end if their elements or accessed in the condition.
  */
 private static List<String> findPossibleClassVariables(String condition) throws ParseException {
   NodeToken[] tokens = TokenExtractor.extractTokens(condition);
   // System.out.println("TokenExtractor.extractTokens(" + condition + ") ==> " +
   // ArraysMDE.toString(tokens));
   List<String> variables = new ArrayList<String>();
   if (tokens.length >= 1) {
     if (tokens[0].kind == IDENTIFIER && (tokens.length <= 1 || tokens[1].kind != LPAREN)) {
       variables.add(tokens[0].tokenImage);
     }
   }
   if (tokens.length >= 2) {
     if (tokens[1].kind == IDENTIFIER
         && (tokens.length <= 2 || tokens[2].kind != LPAREN)
         && (!variables.contains(tokens[1].tokenImage))) {
       variables.add(tokens[1].tokenImage);
     }
   }
   for (int i = 2; i < tokens.length - 1; i++) {
     NodeToken token = tokens[i];
     if (token.kind == IDENTIFIER
         && tokens[i - 1].kind != DOT
         && tokens[i + 1].kind != LPAREN
         && (!variables.contains(token.tokenImage))) {
       variables.add(token.tokenImage);
     }
   }
   if (tokens.length >= 3) {
     int lastIndex = tokens.length - 1;
     if (tokens[lastIndex].kind == IDENTIFIER
         && tokens[lastIndex - 1].kind != DOT
         && (!variables.contains(tokens[lastIndex].tokenImage))) {
       variables.add(tokens[lastIndex].tokenImage);
     }
   }
   // System.out.println("findPossibleClassVariables(" + condition + ") ==> " +
   // variables.toString());
   return variables;
 }
 /**
  * Creates a new instance of VariableManager.
  *
  * @param varInfos the varInfos for the variables to be managed.
  * @param condition the condition in which the variables are used.
  */
 private static VariableManager[] makeVariableManagerArray(
     VarInfo[] varInfos, String condition, String className) throws ParseException {
   List<VariableManager> variableManagerList = new ArrayList<VariableManager>();
   List<String> classVars = findPossibleClassVariables(condition);
   for (int i = 0; i < varInfos.length; i++) {
     VarInfo varInfo = varInfos[i];
     try {
       String compilableName = compilableName(varInfo, className);
       // System.out.println("varInfo " + varInfo.name.name() + ", compilableName=" +
       // compilableName + ", isNeeded=" + isNeeded(compilableName, classVars));
       if (isNeeded(compilableName, classVars)) {
         variableManagerList.add(new VariableManager(varInfo, condition, className));
       }
     } catch (ParseException e) {
       System.out.println("ParseException: " + e.toString());
     }
   }
   return variableManagerList.toArray(new VariableManager[0]);
 }
Пример #4
0
  /**
   * This does the work of main, but it never calls System.exit, so it is appropriate to be called
   * progrmmatically. Termination of the program with a message to the user is indicated by throwing
   * Daikon.TerminationMessage.
   *
   * @see #main(String[])
   * @see daikon.Daikon.TerminationMessage
   */
  public static void mainHelper(final String[] args)
      throws FileNotFoundException, StreamCorruptedException, OptionalDataException, IOException,
          ClassNotFoundException {
    daikon.LogHelper.setupLogs(daikon.LogHelper.INFO);

    LongOpt[] longopts =
        new LongOpt[] {
          new LongOpt(Daikon.config_option_SWITCH, LongOpt.REQUIRED_ARGUMENT, null, 0),
          new LongOpt(output_SWITCH, LongOpt.REQUIRED_ARGUMENT, null, 0),
          new LongOpt(dir_SWITCH, LongOpt.REQUIRED_ARGUMENT, null, 0),
          new LongOpt(conf_SWITCH, LongOpt.NO_ARGUMENT, null, 0),
          new LongOpt(filter_SWITCH, LongOpt.NO_ARGUMENT, null, 0),
          new LongOpt(Daikon.debugAll_SWITCH, LongOpt.NO_ARGUMENT, null, 0),
          new LongOpt(Daikon.debug_SWITCH, LongOpt.REQUIRED_ARGUMENT, null, 0),
          new LongOpt(Daikon.ppt_regexp_SWITCH, LongOpt.REQUIRED_ARGUMENT, null, 0),
          new LongOpt(Daikon.track_SWITCH, LongOpt.REQUIRED_ARGUMENT, null, 0),
        };
    Getopt g = new Getopt("daikon.tools.InvariantChecker", args, "h", longopts);
    int c;
    while ((c = g.getopt()) != -1) {
      switch (c) {
        case 0:
          // got a long option
          String option_name = longopts[g.getLongind()].getName();
          if (Daikon.help_SWITCH.equals(option_name)) {
            System.out.println(usage);
            throw new Daikon.TerminationMessage();
          } else if (conf_SWITCH.equals(option_name)) {
            doConf = true;
          } else if (filter_SWITCH.equals(option_name)) {
            doFilter = true;
          } else if (dir_SWITCH.equals(option_name)) {
            dir_file = new File(g.getOptarg());
            if (!dir_file.exists() || !dir_file.isDirectory())
              throw new Daikon.TerminationMessage("Error reading the directory " + dir_file);

          } else if (output_SWITCH.equals(option_name)) {
            output_file = new File(g.getOptarg());
            output_stream = new PrintStream(new FileOutputStream(output_file));
          } else if (Daikon.config_option_SWITCH.equals(option_name)) {
            String item = g.getOptarg();
            daikon.config.Configuration.getInstance().apply(item);
            break;
          } else if (Daikon.debugAll_SWITCH.equals(option_name)) {
            Global.debugAll = true;
          } else if (Daikon.debug_SWITCH.equals(option_name)) {
            LogHelper.setLevel(g.getOptarg(), LogHelper.FINE);
          } else if (Daikon.track_SWITCH.equals(option_name)) {
            LogHelper.setLevel("daikon.Debug", LogHelper.FINE);
            String error = Debug.add_track(g.getOptarg());
            if (error != null) {
              throw new Daikon.TerminationMessage(
                  "Error parsing track argument '" + g.getOptarg() + "' - " + error);
            }
          } else {
            throw new RuntimeException("Unknown long option received: " + option_name);
          }
          break;
        case 'h':
          System.out.println(usage);
          throw new Daikon.TerminationMessage();
        case '?':
          break; // getopt() already printed an error
        default:
          System.out.println("getopt() returned " + c);
          break;
      }
    }

    // Loop through each filename specified
    for (int i = g.getOptind(); i < args.length; i++) {

      // Get the file and make sure it exists
      File file = new File(args[i]);
      if (!file.exists()) {
        throw new Error("File " + file + " not found.");
      }

      // These aren't "endsWith()" because there might be a suffix on the end
      // (eg, a date).
      String filename = file.toString();
      if (filename.indexOf(".inv") != -1) {
        if (inv_file != null) {
          throw new Daikon.TerminationMessage("multiple inv files specified", usage);
        }
        inv_file = file;
      } else if (filename.indexOf(".dtrace") != -1) {
        dtrace_files.add(filename);
      } else {
        throw new Error("Unrecognized argument: " + file);
      }
    }
    if (dir_file == null) {
      checkInvariants();
      return;
    }

    // Yoav additions:
    File[] filesInDir = dir_file.listFiles();
    if (filesInDir == null || filesInDir.length == 0)
      throw new Daikon.TerminationMessage("The directory " + dir_file + " is empty", usage);
    ArrayList<File> invariants = new ArrayList<File>();
    for (File f : filesInDir) if (f.toString().indexOf(".inv") != -1) invariants.add(f);
    if (invariants.size() == 0)
      throw new Daikon.TerminationMessage(
          "Did not find any invariant files in the directory " + dir_file, usage);
    ArrayList<File> dtraces = new ArrayList<File>();
    for (File f : filesInDir) if (f.toString().indexOf(".dtrace") != -1) dtraces.add(f);
    if (dtraces.size() == 0)
      throw new Daikon.TerminationMessage(
          "Did not find any dtrace files in the directory " + dir_file, usage);

    System.out.println(
        "Collecting data for invariants files " + invariants + " and dtrace files " + dtraces);

    dtrace_files.clear();
    for (File dtrace : dtraces) {
      dtrace_files.add(dtrace.toString());
    }

    String commaLine = "";
    for (File inFile : invariants) {
      String name = inFile.getName().replace(".inv", "").replace(".gz", "");
      commaLine += "," + name;
    }
    outputComma.add(commaLine);

    commaLine = "";
    for (File inFile : invariants) {
      inv_file = inFile;
      failedInvariants.clear();
      testedInvariants.clear();
      error_cnt = 0;

      output_stream =
          new PrintStream(
              new FileOutputStream(
                  inFile.toString().replace(".inv", "").replace(".gz", "")
                      + ".false-positives.txt"));
      checkInvariants();
      output_stream.close();

      int failedCount = failedInvariants.size();
      int testedCount = testedInvariants.size();
      String percent = toPercentage(failedCount, testedCount);
      commaLine += "," + percent;
    }
    outputComma.add(commaLine);

    System.out.println();
    for (String output : outputComma) System.out.println(output);
  }