Newer
Older
/*
* 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/>.
*/
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
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;
}
}
}