Skip to content
EKnife.java 3.72 KiB
Newer Older
Carlos Galindo's avatar
Carlos Galindo committed
package eknife;

import edg.graph.EDG;
import edg.graph.Node;
import edg.slicing.ConstrainedAlgorithm;
import edg.slicing.SlicingAlgorithm;
import edg.slicing.SlicingCriterion;

import java.io.File;
import java.util.List;

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

	public static void main(String[] args)
	{
		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":
				if (argIndex == args.length - 1) {
					System.out.printf("Parameter %s requires an argument\n", arg);
					printHelp();
					System.exit(1);
				}
				default:
					break;
			}
			switch (arg)
			{
				case "--help":
					printHelp();
					System.exit(0);
				case "-i": case "--input":
				kArgs.inputPath = args[argIndex + 1];
				break;
				case "-o": case "--output":
				kArgs.outputFile = new File(args[argIndex + 1]);
				break;
				case "-f": case "--file":
				kArgs.file = args[argIndex + 1];
				break;
				case "-l": case "--line":
				kArgs.line = Integer.parseInt(args[argIndex + 1]);
				break;
				case "-v": case "--var":
				kArgs.name = args[argIndex + 1];
				break;
				case "-n": case "--occurrence":
				kArgs.occurrence = Integer.parseInt(args[argIndex + 1]);
				break;
			}
		}

		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 += "  --help                      Show this message.\n";

		System.out.print(help);
	}

	private static void run(Args a)
	{
		final EDG edg = EDGFactory.createEDG(Language.Erlang, a.inputPath, true);
		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();
		final List<Node> slice = slicingAlgorithm.slice(SC);
		if (slice.isEmpty()) {
			System.out.println("Warning: no files will be written, as the slice is empty.");
			System.exit(2);
		}

		CodeFactory.createCode(Language.Erlang, a.outputFile, edg, slice);
	}

	static class Args {
		String inputPath;
		File outputFile;
		String file;
		int line;
		String name;
		int occurrence = 1;

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

		boolean isValid() {
			return inputPath != null && new File(inputPath).exists() &&
					outputFile != null && (outputFile.exists() || outputFile.getAbsoluteFile().getParentFile().isDirectory()) &&
					file != null &&
					line > 0 &&
					name != null && !name.isEmpty() &&
					occurrence > 0;
		}
	}
}