Skip to content
EKnife.java 21.7 KiB
Newer Older
Carlos Galindo's avatar
Carlos Galindo committed
/*
 * e-Knife, a program slicing tool for Erlang based on the EDG
 * Copyright (c) 2021. David Insa, Sergio Pérez, Josep Silva, Salvador Tamarit.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 */

Carlos Galindo's avatar
Carlos Galindo committed
package eknife;

import edg.DotFactory;
import edg.EDGFactory;
Carlos Galindo's avatar
Carlos Galindo committed
import edg.PdfFactory;
Carlos Galindo's avatar
Carlos Galindo committed
import edg.graph.EDG;
Sergio Pérez's avatar
Sergio Pérez committed
import edg.graph.Edge;
import edg.graph.LAST;
Carlos Galindo's avatar
Carlos Galindo committed
import edg.graph.Node;
Sergio Pérez's avatar
Sergio Pérez committed
import edg.slicing.*;
Carlos Galindo's avatar
Carlos Galindo committed

import java.io.File;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
Carlos Galindo's avatar
Carlos Galindo committed

public class EKnife
{
	public enum Language { Java, Erlang, Php }

Sergio Pérez's avatar
Sergio Pérez committed
	// TODO: OUTPUT FILES PATH

	// Graph Generation Time
	public static final String graphGenerationCsv = "/Users/serperu/Desktop/SlicerOutput/Times/generationTimeMilliseconds.csv";
	public static final String sliceGenerationCsv = "/Users/serperu/Desktop/SlicerOutput/Times/slicingStatisticsMicroseconds.csv";
	public static final String nodeCounterFile = "/Users/serperu/Desktop/SlicerOutput/Times/programSizes.txt";

Carlos Galindo's avatar
Carlos Galindo committed
	public static void main(String[] args)
	{
		if (args.length == 0) {
			EKnife.printHelp();
			return;
		}

Carlos Galindo's avatar
Carlos Galindo committed
		final Args arguments = EKnife.processArguments(args);

		if (!arguments.isValid()) {
			EKnife.printHelp();
			System.exit(3);
		}
		EKnife.run(arguments);
	}

	private static Args processArguments(String[] args)
	{
		Args kArgs = new Args();

		for (int argIndex = 0; argIndex < args.length; argIndex++)
		{
			final String arg = args[argIndex];

			switch (arg)
			{
				case "-i": case "--input":
				case "-o": case "--output":
				case "-f": case "--file":
				case "-l": case "--line":
				case "-v": case "--var":
				case "-n": case "--occurrence":
Carlos Galindo's avatar
Carlos Galindo committed
				case "-G": case "--print-graph":
					if (argIndex == args.length - 1) {
						System.out.printf("Parameter %s requires an argument\n", arg);
						printHelp();
						System.exit(1);
					}
Carlos Galindo's avatar
Carlos Galindo committed
			}
			switch (arg)
			{
				case "--help":
					printHelp();
					System.exit(0);
				case "-i": case "--input":
Carlos Galindo's avatar
Carlos Galindo committed
					kArgs.inputPath = args[argIndex + 1];
					break;
Carlos Galindo's avatar
Carlos Galindo committed
				case "-o": case "--output":
Carlos Galindo's avatar
Carlos Galindo committed
					kArgs.outputFile = new File(args[argIndex + 1]);
					break;
Carlos Galindo's avatar
Carlos Galindo committed
				case "-f": case "--file":
Carlos Galindo's avatar
Carlos Galindo committed
					kArgs.file = args[argIndex + 1];
					break;
Carlos Galindo's avatar
Carlos Galindo committed
				case "-l": case "--line":
Carlos Galindo's avatar
Carlos Galindo committed
					kArgs.line = Integer.parseInt(args[argIndex + 1]);
					break;
Carlos Galindo's avatar
Carlos Galindo committed
				case "-v": case "--var":
Carlos Galindo's avatar
Carlos Galindo committed
					kArgs.name = args[argIndex + 1];
					break;
Carlos Galindo's avatar
Carlos Galindo committed
				case "-n": case "--occurrence":
Carlos Galindo's avatar
Carlos Galindo committed
					kArgs.occurrence = Integer.parseInt(args[argIndex + 1]);
					break;
				case "-G": case "--print-graph":
					kArgs.setGraphFile(new File(args[argIndex + 1]));
					break;
Carlos Galindo's avatar
Carlos Galindo committed
			}
		}

		kArgs.completeData();
		return kArgs;
	}
	private static void printHelp()
	{
		String help = "";

		help += "Use the following options:\n";
		help += "  -i,--input  <file/folder>   The file/folder where the source code is\n";
		help += "  -o,--output <file/folder>   The file/folder where the slice will be stored\n";
		help += "  -f,--file   <file>          The file (relative to -i) where the slicing criterion is\n";
		help += "  -l,--line   <num>           The line of the slicing criterion\n";
		help += "  -v,--var    <name>          The name of the slicing criterion (must be a variable)\n";
		help += "  -n,--occurrence <num>       The occurrence of the slicing criterion in that line\n";
		help += "  -G,--print-graph <file.dot> Exports the graph as a dot file\n";
		help += "  -G,--print-graph <file.pdf> Exports the graph as a PDF file\n";
Carlos Galindo's avatar
Carlos Galindo committed
		help += "  --help                      Show this message.\n";

		System.out.print(help);
	}

	private static void run(Args a)
	{
		final LAST last = LASTFactory.createLAST(Language.Erlang, a.inputPath, true);
		final EDG edg = new EDGFactory(last).createEDG();
Carlos Galindo's avatar
Carlos Galindo committed
		final SlicingCriterion slicingCriterion = new SlicingCriterion(a.file, a.line, a.name, a.occurrence);
		final Node SC = edg.getNode(slicingCriterion);
		if (SC == null) {
			System.out.println("Error: the slicing criterion could not be found! " + slicingCriterion);
			System.exit(1);
		}
		final SlicingAlgorithm slicingAlgorithm = new ConstrainedAlgorithm(edg);
		final Set<Node> slice = slicingAlgorithm.slice(SC);
Carlos Galindo's avatar
Carlos Galindo committed
		if (slice.isEmpty()) {
			System.out.println("Warning: no files will be written, as the slice is empty.");
			System.exit(2);
		}
Carlos Galindo's avatar
Carlos Galindo committed
		if (a.graphFile != null) {
			switch (a.graphFormat) {
				case DOT:
					DotFactory.createDot(a.graphFile, edg, SC, slice);
					break;
				case PDF:
					PdfFactory.createPdf(a.graphFile, edg, SC, slice);
					break;
			}
		}
Carlos Galindo's avatar
Carlos Galindo committed
		CodeFactory.createCode(Language.Erlang, a.outputFile, edg, slice);
	}

Sergio Pérez's avatar
Sergio Pérez committed
	private static void timedRun(Args a)
	{
		// CONFIGURE MEASURED DIMENSIONS
		boolean measureGenerationTime = true;
		boolean measureNodes = false;
		boolean performAllSCs = true;
Sergio Pérez's avatar
Sergio Pérez committed
		/* ***************************************************** */
		/* ** MEASUREMENT OF GENERATION TIME (100 executions) ** */
		/* ***************************************************** */
Sergio Pérez's avatar
Sergio Pérez committed
		int numberOfIterations = 100;

		if (measureGenerationTime) {
Sergio Pérez's avatar
Sergio Pérez committed
			double[] StructuralTime = new double[numberOfIterations];
			double[] CFGTime = new double[numberOfIterations];
			double[] ValueTime = new double[numberOfIterations];
			double[] CompositeTime = new double[numberOfIterations];
			double[] ControlTime = new double[numberOfIterations];
			double[] FlowTime = new double[numberOfIterations];
			double[] IPTime = new double[numberOfIterations];
Sergio Pérez's avatar
Sergio Pérez committed

Sergio Pérez's avatar
Sergio Pérez committed
//			double totalStructural, totalCFG, totalValue, totalComposite, totalControl, totalFlow;
//			totalStructural = totalCFG = totalValue = totalComposite = totalControl = totalFlow = 0.0;

			double[] standardTime = new double[numberOfIterations];
			double[] constrainedTime = new double[numberOfIterations];
Sergio Pérez's avatar
Sergio Pérez committed

			for (int i = -1; i < numberOfIterations; i++) {

				final LAST last = LASTFactory.createLAST(Language.Erlang, a.inputPath, true);
				final EDG edg = new EDGFactory(last).createEDG();

				if (i == -1)
					continue;

Sergio Pérez's avatar
Sergio Pérez committed
//				totalStructural += edg.getGenerationTime().getStructureTime();
//				totalCFG += edg.getGenerationTime().getControlFlowTime();
//				totalValue += edg.getGenerationTime().getValueTime();
//				totalComposite += edg.getGenerationTime().getCompositeTime();
//				totalControl += edg.getGenerationTime().getControlTime();
//				totalFlow += edg.getGenerationTime().getFlowTime();

				StructuralTime[i] = edg.getGenerationTime().getStructureTime();
				CFGTime[i] = edg.getGenerationTime().getControlFlowTime();
				ValueTime[i] = edg.getGenerationTime().getValueTime();
				CompositeTime[i] = edg.getGenerationTime().getCompositeTime();
				ControlTime[i] = edg.getGenerationTime().getControlTime();
				FlowTime[i] = edg.getGenerationTime().getFlowTime();
				IPTime[i] = edg.getGenerationTime().getInterproceduralTime();
				standardTime[i] = StructuralTime[i] + CFGTime[i] + ValueTime[i] - CompositeTime[i]
						+ ControlTime[i] + FlowTime[i] + IPTime[i];
				constrainedTime[i] = StructuralTime[i] + CFGTime[i] + ValueTime[i]
						+ ControlTime[i] + FlowTime[i] + IPTime[i];
				// printArray("/Users/serperu/Desktop/SlicerOutput/Times/ArrayContent.txt",constrainedTime);
Sergio Pérez's avatar
Sergio Pérez committed
			}

//		double totalStructural, totalCFG, totalValue, totalControl, totalFlow;
//		totalStructural = totalCFG = totalValue = totalControl = totalFlow = 0.0;
//		for (int i = 0; i < 100; i++){
//			totalStructural += StructuralTime[i];
//			totalCFG += CFGTime[i];
//			totalValue += ValueTime[i];
//			totalControl += ControlTime[i];
//			totalFlow += FlowTime[i];
//		}
			// INTRAPROCEDURAL GENERATION TIME
			// TIME MEASSUREMENT:
Sergio Pérez's avatar
Sergio Pérez committed
			printCSVGenerationTime(a.file, standardTime, constrainedTime);

//			printGenerationTime(a.file, numberOfIterations, totalStructural, totalCFG, totalValue,
//					totalComposite, totalControl, totalFlow, false);
//			printGenerationTime(a.file, numberOfIterations, totalStructural, totalCFG, totalValue,
//					totalComposite, totalControl, totalFlow, true);
Sergio Pérez's avatar
Sergio Pérez committed
		}

		final LAST last = LASTFactory.createLAST(Language.Erlang, a.inputPath, true);
		final EDG edg = new EDGFactory(last).createEDG();
Sergio Pérez's avatar
Sergio Pérez committed
		/* *************************** */
		/* ** MEASUREMENT OF NODES: ** */
		/* *************************** */
Sergio Pérez's avatar
Sergio Pérez committed
		if (measureNodes) {
			int SDGNodeCounter = countSDGNodes(edg);
			int EDGNodeCounter = countEDGNodes(edg);

			printNodeCounter(a.file, SDGNodeCounter, EDGNodeCounter);
		}
Sergio Pérez's avatar
Sergio Pérez committed
		/* ************************ */
		/* ** MEASUREMENT OF SCs ** */
		/* ************************ */
Sergio Pérez's avatar
Sergio Pérez committed
		if (performAllSCs) {

			// SC SELECTION
			List<Node> clauses = edg.getNodes(Node.Type.Clause);
			clauses.removeIf(c -> edg.getParent(c).getType() != Node.Type.Routine);

Sergio Pérez's avatar
Sergio Pérez committed
			// printHeadings("/Users/serperu/Desktop/SlicerOutput/Times/slicingStatistics.txt", a.file);
Sergio Pérez's avatar
Sergio Pérez committed

			for (Node clause : clauses) {
Sergio Pérez's avatar
Sergio Pérez committed
				int arity = edg.getChildrenNonResult(edg.getChild(clause, Node.Type.Parameters)).size();
				String functionName = edg.getParent(clause).getName() + "/" + arity;
				// printFunction("/Users/serperu/Desktop/SlicerOutput/Times/slicingStatistics.txt", edg.getParent(clause).getName() + "/" + arity);

Sergio Pérez's avatar
Sergio Pérez committed
				List<Node> descendants = edg.getDescendants(clause);
				descendants.add(clause);

				List<Node> resultNodes = new LinkedList<>();
				List<Node> nonResultNodes = new LinkedList<>();

				for (Node n : descendants)
					if (n.getType() == Node.Type.Result) {
						if (edg.getNodeFromRes(n).getType() != Node.Type.Callee)
							resultNodes.add(n);
					} else
						nonResultNodes.add(n);
				nonResultNodes.add(clause);
				resultNodes.add(edg.getResFromNode(clause));


				// IGNORE FUNCTIONS WITHOUT COMPOSITE STRUCTURES
				if (nonResultNodes.stream()
						.noneMatch(
								n -> { if (n.getType() == Node.Type.DataConstructor)
											return true;
										if (n.getType() == Node.Type.List)
											if (edg.getChildren(n).size() != 0 || edg.getParent(n).getType() == Node.Type.List)
												return true;
										return false;})) {
					System.out.println("File Name: " + a.file);
					int functionArity = edg.getChildrenNonResult(edg.getChild(clause, Node.Type.Parameters)).size();
					System.out.println("Function " + edg.getParent(clause).getName() + "/" + functionArity + " has no valid slicing criteria.");
					continue;
				}

Sergio Pérez's avatar
Sergio Pérez committed
				/* FILTER SC NODES BY A CRITERION (CONSIDER ONLY VARIABLES) */
				resultNodes.removeIf(n -> edg.getNodeFromRes(n).getType() != Node.Type.Variable);
Sergio Pérez's avatar
Sergio Pérez committed


Sergio Pérez's avatar
Sergio Pérez committed
				// SlicingCriterionState[] allCriteriaStandard = new SlicingCriterionState[resultNodes.size()];
				// SlicingCriterionState[] allCriteriaConstrained = new SlicingCriterionState[resultNodes.size()];
Sergio Pérez's avatar
Sergio Pérez committed

				// CONFIGURE MEASURED DIMENSIONS
				boolean measureSlicingTime = true;
Sergio Pérez's avatar
Sergio Pérez committed
				boolean measureSlicingPerformance = true;
Sergio Pérez's avatar
Sergio Pérez committed

				final SlicingAlgorithm standardAlgorithm = new AdaptedStandardAlgorithm(edg);
				final SlicingAlgorithm constrainedAlgorithm = new ConstrainedAlgorithm(edg);

				int scCounter = 0;
				int scConstrainedImprovements = 0;

Sergio Pérez's avatar
Sergio Pérez committed
				double[] stdAvgArray = new double[resultNodes.size()];
				double[] consAvgArray = new double[resultNodes.size()];
				double[] stdVarArray = new double[resultNodes.size()];
				double[] consVarArray = new double[resultNodes.size()];
				int[] standardNodes = new int[resultNodes.size()];
				int[] constrainedNodes = new int[resultNodes.size()];
Sergio Pérez's avatar
Sergio Pérez committed
				for (Node SC : resultNodes) {
					// INITIALIZATIONS
						// PERFORMANCE
					double standardSlicePercentage = 0.0;
					double constrainedSlicePercentage = 0.0;
Sergio Pérez's avatar
Sergio Pérez committed

Sergio Pérez's avatar
Sergio Pérez committed
						// TIME
Sergio Pérez's avatar
Sergio Pérez committed
					double totalStandardTime = 0.0;
					double totalConstrainedTime = 0.0;

					double[] standardTime = new double[numberOfIterations];
					double[] constrainedTime = new double[numberOfIterations];
Sergio Pérez's avatar
Sergio Pérez committed

					// MEASURE TIME FOR EACH SC
					if (measureSlicingTime) {
						for (int j = -1; j < numberOfIterations; j++) {
							long initialStandardTime = System.nanoTime();
							standardAlgorithm.slice(SC);
							long finalStandardTime = System.nanoTime();

Sergio Pérez's avatar
Sergio Pérez committed
							if (j == -1)
								continue;

							standardTime[j] = (finalStandardTime - initialStandardTime) / 1000.0;
							totalStandardTime += standardTime[j];
						}

						for (int j = -1; j < numberOfIterations; j++){
Sergio Pérez's avatar
Sergio Pérez committed
							long initialConstrainedTime = System.nanoTime();
							constrainedAlgorithm.slice(SC);
							long finalConstrainedTime = System.nanoTime();

							if (j == -1)
								continue;

Sergio Pérez's avatar
Sergio Pérez committed
							constrainedTime[j] = (finalConstrainedTime - initialConstrainedTime) / 1000.0 ;
							totalConstrainedTime += constrainedTime[j];
Sergio Pérez's avatar
Sergio Pérez committed
						}
Sergio Pérez's avatar
Sergio Pérez committed

						// COMPUTE AVG
						stdAvgArray[scCounter] = totalStandardTime / numberOfIterations;
						consAvgArray[scCounter] = totalConstrainedTime / numberOfIterations;



						// COMPUTE VARIANCE
						double varianceAccStd = 0.0;
						double varianceAccCons = 0.0;

						// printArray("/Users/serperu/Desktop/SlicerOutput/Times/ArrayContent.txt",constrainedTime);

						for (int l = 0; l < numberOfIterations; l++) {
							varianceAccStd += Math.pow((standardTime[l] - stdAvgArray[scCounter]), 2);
							varianceAccCons += Math.pow((constrainedTime[l] - consAvgArray[scCounter]), 2);
						}

						stdVarArray[scCounter] = varianceAccStd / numberOfIterations;
						consVarArray[scCounter] = varianceAccCons / numberOfIterations;
Sergio Pérez's avatar
Sergio Pérez committed
					}

					// MEASURE PERFORMARNCE
					final Set<Node> standardSlice = standardAlgorithm.slice(SC);
					final Set<Node> constrainedSlice = constrainedAlgorithm.slice(SC);

					if (measureSlicingPerformance) {
Sergio Pérez's avatar
Sergio Pérez committed
						standardSlice.removeIf(n -> n.getType() == Node.Type.Result);
Sergio Pérez's avatar
Sergio Pérez committed
						standardSlicePercentage = standardSlice.size() * 100.0 / nonResultNodes.size();

Sergio Pérez's avatar
Sergio Pérez committed
						constrainedSlice.removeIf(n -> n.getType() == Node.Type.Result);
Sergio Pérez's avatar
Sergio Pérez committed
						constrainedSlicePercentage = constrainedSlice.size() * 100.0 / nonResultNodes.size();

Sergio Pérez's avatar
Sergio Pérez committed
						standardNodes[scCounter] = standardSlice.size();
						constrainedNodes[scCounter] = constrainedSlice.size();

Sergio Pérez's avatar
Sergio Pérez committed
						if (constrainedSlice.size() < standardSlice.size())
							scConstrainedImprovements++;

						if (standardSlicePercentage < constrainedSlicePercentage)
							throw new IllegalStateException("The SDG cannot be more precise than the EDG");

					}
Sergio Pérez's avatar
Sergio Pérez committed
//					allCriteriaStandard[scCounter] = new SlicingCriterionState(standardSlicePercentage, 0);
//					allCriteriaConstrained[scCounter] = new SlicingCriterionState(constrainedSlicePercentage, 0);
Sergio Pérez's avatar
Sergio Pérez committed
					scCounter++;
				}
Sergio Pérez's avatar
Sergio Pérez committed

				int edgNodes = (int) edg.vertexSet().stream()
					.filter(n -> n.getType() != Node.Type.Result)
					.count();
				printEachSCData(a.file, functionName, stdAvgArray, stdVarArray, consAvgArray, consVarArray,
						edgNodes, standardNodes, constrainedNodes);

				// int arity = edg.getChildrenNonResult(edg.getChild(clause, Node.Type.Parameters)).size();
				// printSlicingResults(edg.getParent(clause).getName() + "/" + arity,
//					resultNodes.size(), allCriteriaStandard, allCriteriaConstrained,
//						scConstrainedImprovements, measureSlicingPerformance, measureSlicingTime);
Sergio Pérez's avatar
Sergio Pérez committed
			}
		}
//		DotFactory.createDot(new File("/Users/serperu/Desktop/SlicerOutput/graphSliced.dot"), edg, SC, slice, edgeFlags);
//		CodeFactory.createCode(Language.Erlang, a.outputFile, edg, slice);
	}

	public static int countSDGNodes(EDG edg) {
		Node root = edg.getRootNode();
		return countSDGNodes(edg, root);
	}

	public static int countSDGNodes(EDG edg, Node node) {
		int counter = 1;
		List<Node> children = edg.getChildren(node);
		for (Node child : children) {
			if (child.getType() == Node.Type.Result)
				continue;
			if (child.getType() == Node.Type.List ||child.getType() == Node.Type.DataConstructor)
				counter++;
			else {
				counter += countSDGNodes(edg, child);
			}
		}
		return counter;
	}

	public static int countEDGNodes(EDG edg) {
		Set<Node> nodes = new HashSet<>();
		nodes.addAll(edg.vertexSet());
		nodes.removeIf(n -> n.getType() == Node.Type.Result);
		return nodes.size();
	}
Sergio Pérez's avatar
Sergio Pérez committed
	/* *********************** *********************** *********************** *********************** */
	/* *********************** ****************** PRINT METHODS ************** *********************** */
	/* *********************** *********************** *********************** *********************** */
Sergio Pérez's avatar
Sergio Pérez committed

Sergio Pérez's avatar
Sergio Pérez committed
	public static void printCSVGenerationTime(String file, double[] stdTimes, double[] consTimes){
Sergio Pérez's avatar
Sergio Pérez committed
		FileWriter timeFileWriter;
		PrintWriter timeWriter = null;
Sergio Pérez's avatar
Sergio Pérez committed
		int numberOfElems = stdTimes.length;
Sergio Pérez's avatar
Sergio Pérez committed
		try {
Sergio Pérez's avatar
Sergio Pérez committed
			timeFileWriter = new FileWriter(graphGenerationCsv, true);
Sergio Pérez's avatar
Sergio Pérez committed
			timeWriter = new PrintWriter(timeFileWriter);
Sergio Pérez's avatar
Sergio Pérez committed

			for (int i = 0; i < numberOfElems; i++)
				timeWriter.printf("%s;GEN_%d;%.5f;%.5f\n",file,i,stdTimes[i],consTimes[i]);

Sergio Pérez's avatar
Sergio Pérez committed

		} catch (IOException e) {
			System.out.println("FILE NOT FOUND ERROR");
		} finally {
			if (timeWriter != null)
				timeWriter.close();
		}
	}

	public static void printNodeCounter(String programName, int SDGNodes, int EDGNodes) {
		FileWriter timeFileWriter;
		PrintWriter timeWriter = null;
		try {
Sergio Pérez's avatar
Sergio Pérez committed
			timeFileWriter = new FileWriter(nodeCounterFile, true);
Sergio Pérez's avatar
Sergio Pérez committed
			timeWriter = new PrintWriter(timeFileWriter);
			timeWriter.println("---------------------------");
			timeWriter.println("Program Name: " + programName);
			timeWriter.println("---------------------------");
			timeWriter.println(" SDG Nodes: " + SDGNodes);
			timeWriter.println(" EDG Nodes: " + EDGNodes + "\n");
		} catch (IOException e) {
			System.out.println("FILE NOT FOUND ERROR");
		} finally {
			if (timeWriter != null)
				timeWriter.close();
		}
	}

Sergio Pérez's avatar
Sergio Pérez committed
	public static void printHeadings(String outputFile1, String outputFile2){
Sergio Pérez's avatar
Sergio Pérez committed
		FileWriter timeFileWriter;
		PrintWriter timeWriter = null;
		try {
Sergio Pérez's avatar
Sergio Pérez committed
			timeFileWriter = new FileWriter(outputFile1, true);
Sergio Pérez's avatar
Sergio Pérez committed
			timeWriter = new PrintWriter(timeFileWriter);
Sergio Pérez's avatar
Sergio Pérez committed
			timeWriter.println("PROGRAM;GEN_NUMBER;STD_AVG_GEN_TIME;CONS_GEN_TIME");
		} catch (IOException e) {
			System.out.println("FILE NOT FOUND ERROR");
		} finally {
			if (timeWriter != null)
				timeWriter.close();
		}
		try {
			timeFileWriter = new FileWriter(outputFile2, true);
			timeWriter = new PrintWriter(timeFileWriter);
			timeWriter.println("PROGRAM;FUNCTION;SC;STD_AVG;STD_VAR;CONS_AVG;CONS_VAR;FUNC_NODES;STD_NODES;CONS_NODES");
Sergio Pérez's avatar
Sergio Pérez committed
		} catch (IOException e) {
			System.out.println("FILE NOT FOUND ERROR");
		} finally {
			if (timeWriter != null)
				timeWriter.close();
		}

Sergio Pérez's avatar
Sergio Pérez committed
	}
	public static void printEachSCData(String file, String funName, double[] stdAvg, double[] stdVar,
									   double[] consAvg, double[] consVar, int funNodeSize, int[] stdNodeSize, int[] consNodeSize) {
Sergio Pérez's avatar
Sergio Pérez committed

		FileWriter timeFileWriter;
		PrintWriter timeWriter = null;
Sergio Pérez's avatar
Sergio Pérez committed
		int numberOfElems = stdAvg.length;
Sergio Pérez's avatar
Sergio Pérez committed
		try {
Sergio Pérez's avatar
Sergio Pérez committed
			timeFileWriter = new FileWriter(sliceGenerationCsv, true);
Sergio Pérez's avatar
Sergio Pérez committed
			timeWriter = new PrintWriter(timeFileWriter);

Sergio Pérez's avatar
Sergio Pérez committed
			for (int i = 0; i < numberOfElems; i++) {
				timeWriter.printf("%s;%s;SC_%d;%.5f;%.5f;%.5f;%.5f;%d;%d;%d\n",file,funName,i,stdAvg[i],stdVar[i],
						consAvg[i],consVar[i],funNodeSize,stdNodeSize[i],consNodeSize[i]);
Sergio Pérez's avatar
Sergio Pérez committed
			}

		} catch (IOException e) {
			System.out.println("FILE NOT FOUND ERROR");
		} finally {
			if (timeWriter != null)
				timeWriter.close();
		}
	}

Sergio Pérez's avatar
Sergio Pérez committed
	/* *********************** *********************** *********************** *********************** */
	/* *********************** *********************** *********************** *********************** */
	/* *********************** *********************** *********************** *********************** */



Carlos Galindo's avatar
Carlos Galindo committed
	static class Args {
Carlos Galindo's avatar
Carlos Galindo committed
		enum GraphFormat { PDF, DOT }

Carlos Galindo's avatar
Carlos Galindo committed
		String inputPath;
		File outputFile;
		String file;
		int line;
		String name;
		int occurrence = 1;
Carlos Galindo's avatar
Carlos Galindo committed
		File graphFile;
		GraphFormat graphFormat;


		void setGraphFile(File graphFile) {
			if (graphFile.getName().endsWith(".dot"))
				graphFormat = GraphFormat.DOT;
			else if (graphFile.getName().endsWith(".pdf"))
				graphFormat = GraphFormat.PDF;
			else {
				System.out.println("The graph file must end in .dot or .pdf, you set it to " + graphFile);
				System.exit(1);
			}
			this.graphFile = graphFile;
		}
Carlos Galindo's avatar
Carlos Galindo committed

		void completeData() {
			if (file == null && inputPath != null && new File(inputPath).isFile())
				file = new File(inputPath).getName();
		}

		boolean isValid() {
			List<String> errors = new LinkedList<>();
			if (inputPath == null)
				errors.add("You must specify a file to analyze with '-i'.");
			else if (!new File(inputPath).exists())
				errors.add("The input file you've specified does not exist or isn't readable(" + inputPath + ").");
			else if (file == null)
				errors.add("The input file is a folder, so you must specify a the file that contains the slicing criterion with '-f'.");
			if (outputFile == null)
				errors.add("You must specify a location for the output with '-o'.");
			else if (!outputFile.exists() && !outputFile.getAbsoluteFile().getParentFile().isDirectory())
				errors.add("The output file's parent folder does not exist, or the output folder does not exist.");
			if (line <= 0)
				errors.add("You must specify a line number greater than 0 with '-l'.");
			if (name == null || name.isEmpty())
				errors.add("You must specify a valid variable name with '-v'.");
			if (occurrence <= 0)
				errors.add("You must specify an occurrence greater than 0 with '-n'.");
			for (String error : errors)
				System.out.println(error);
			return errors.isEmpty();
Carlos Galindo's avatar
Carlos Galindo committed
		}
	}
Sergio Pérez's avatar
Sergio Pérez committed

Sergio Pérez's avatar
Sergio Pérez committed
	public static class SlicingCriterionState{
Sergio Pérez's avatar
Sergio Pérez committed
		private final double slicingPerformance;
		private final double slicingTime;

		public SlicingCriterionState(double performance, double time) {
			slicingPerformance = performance;
			slicingTime = time;
		}
		public double getPerformance() { return this.slicingPerformance; }
		public double getTime() { return this.slicingTime; }
	}
Carlos Galindo's avatar
Carlos Galindo committed
}