Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/ProbeParser.java')
-rw-r--r--systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/ProbeParser.java230
1 files changed, 168 insertions, 62 deletions
diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/ProbeParser.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/ProbeParser.java
index c096d6f6a1..d2ab9fc06f 100644
--- a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/ProbeParser.java
+++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/ProbeParser.java
@@ -12,6 +12,9 @@
package org.eclipse.linuxtools.internal.systemtap.ui.ide.structures;
import java.text.MessageFormat;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Map;
import java.util.Scanner;
import java.util.StringTokenizer;
import java.util.regex.Matcher;
@@ -36,6 +39,7 @@ public final class ProbeParser extends TreeTapsetParser {
public static final String PROBE_REGEX = "(?s)(?<!\\w)probe\\s+{0}\\s*\\+?="; //$NON-NLS-1$
private static final String TAPSET_PROBE_REGEX = "probe {0} \\+?="; //$NON-NLS-1$
+ private static final Pattern PROBE_GROUP_PATTERN = Pattern.compile("[^\\.\\( ]+"); //$NON-NLS-1$
private static ProbeParser parser = null;
public static ProbeParser getInstance(){
@@ -47,7 +51,7 @@ public final class ProbeParser extends TreeTapsetParser {
}
private ProbeParser() {
- super("Probe Parser"); //$NON-NLS-1$
+ super(Messages.ProbeParser_name);
}
/**
@@ -67,33 +71,34 @@ public final class ProbeParser extends TreeTapsetParser {
* Root->Named Groups->ProbePoints->Variables
*/
@Override
- protected IStatus runAction(IProgressMonitor monitor) {
- addStaticProbes(monitor);
- addProbeAliases(monitor, tree.getChildAt(0));
- return super.runAction(monitor);
+ protected int runAction(IProgressMonitor monitor) {
+ int result = addStaticProbes(monitor);
+ if (result == IStatus.OK) {
+ result = addProbeAliases(monitor);
+ }
+ return result;
}
/**
* Runs stap to obtain a log of all static probes, and populate the probe tree with them.
- *
- * @return <code>false</code> if a cancelation prevented all probes from being added;
- * <code>true</code> otherwise.
+ * @return An {@link IStatus} severity level for the result of the operation.
*/
- private boolean addStaticProbes(IProgressMonitor monitor) {
+ private int addStaticProbes(IProgressMonitor monitor) {
TreeNode statics = new TreeNode(Messages.ProbeParser_staticProbes, false);
tree.add(statics);
if (monitor.isCanceled()) {
- return false;
+ return IStatus.CANCEL;
}
String probeDump = runStap(new String[]{"--dump-probe-types"}, null, false); //$NON-NLS-1$
- if (probeDump == null) {
- return false;
+ int result = verifyRunResult(probeDump);
+ if (result != IStatus.OK) {
+ return result;
}
boolean canceled = false;
try (Scanner st = new Scanner(probeDump)) {
- TreeNode group = null;
+ TreeNode groupNode = null;
while (st.hasNextLine()) {
if (monitor.isCanceled()) {
canceled = true;
@@ -101,36 +106,39 @@ public final class ProbeParser extends TreeTapsetParser {
}
String tokenString = st.nextLine();
String probeName = (new StringTokenizer(tokenString)).nextToken();
- group = addOrFindProbeGroup(extractProbeGroupName(probeName), group, statics);
- group.add(makeStaticProbeNode(probeName));
+ groupNode = addOrFindProbeGroup(extractProbeGroupName(probeName), groupNode, statics);
+ groupNode.add(makeStaticProbeNode(probeName));
}
}
statics.sortTree();
- return !canceled;
+ return !canceled ? IStatus.OK : IStatus.CANCEL;
}
/**
* Runs stap to obtain a log of all probe aliases & their variables,
* and populate the probe tree with them.
- *
- * @return <code>false</code> if a cancelation prevented all probes from being added;
- * <code>true</code> otherwise.
+ * @return An {@link IStatus} severity level for the result of the operation.
*/
- private boolean addProbeAliases(IProgressMonitor monitor, TreeNode statics) {
+ private int addProbeAliases(IProgressMonitor monitor) {
+ TreeNode statics = tree.getChildByName(Messages.ProbeParser_staticProbes);
+ if (statics == null) {
+ return IStatus.ERROR;
+ }
TreeNode aliases = new TreeNode(Messages.ProbeParser_aliasProbes, false);
tree.add(aliases);
- if (statics == null || monitor.isCanceled()) {
- return false;
+ if (monitor.isCanceled()) {
+ return IStatus.CANCEL;
}
String probeDump = runStap(new String[]{"-L"}, "**", false); //$NON-NLS-1$ //$NON-NLS-2$
- if (probeDump == null) {
- return false;
+ int result = verifyRunResult(probeDump);
+ if (result != IStatus.OK) {
+ return result;
}
boolean canceled = false;
try (Scanner st = new Scanner(probeDump)) {
- TreeNode group = null;
+ TreeNode groupNode = null;
while (st.hasNextLine()) {
if (monitor.isCanceled()) {
canceled = false;
@@ -142,35 +150,56 @@ public final class ProbeParser extends TreeTapsetParser {
if (tokenString.startsWith("_")) { //$NON-NLS-1$
continue;
}
-
- StringTokenizer probeTokenizer = new StringTokenizer(tokenString);
- String probeName = probeTokenizer.nextToken();
-
- String groupName = extractProbeGroupName(tokenString);
// Only add this group if it is not a static probe group
- if (statics.getChildByName(groupName) == null) {
- TreeNode probeNode = makeProbeAliasNode(probeName);
- group = addOrFindProbeGroup(groupName, group, aliases);
- group.add(probeNode);
- addAllVarNodesToProbeNode(probeTokenizer, probeNode);
+ String groupName = extractProbeGroupName(tokenString);
+ if (statics.getChildByName(groupName) != null) {
+ continue;
}
+ groupNode = addSingleProbeAlias(tokenString, aliases, groupNode, groupName, null);
}
}
aliases.sortTree();
- return !canceled;
+ return !canceled ? IStatus.OK : IStatus.CANCEL;
+ }
+
+ /**
+ * Adds a single probe alias to the collection.
+ * @param probeLine A line of probe information printed by a call to "stap -L".
+ * @param aliases The tree of probe aliases. The probe will be added to this tree.
+ * @param groupNode For optimization, pass an existing group node here, as it will be used if the
+ * probe belongs in it. Otherwise, or if <code>null</code> is passed, a new one will be created.
+ * @param groupName The name of the probe group, or <code>null</code> if it is unknown at the time
+ * this method is called.
+ * @param definition The path of the file in which this probe is defined, or <code>null</code> if it
+ * is unknown at the time this method is called.
+ */
+ private TreeNode addSingleProbeAlias(String probeLine, TreeNode aliases, TreeNode groupNode,
+ String groupName, String definition) {
+ StringTokenizer probeTokenizer = new StringTokenizer(probeLine);
+ String probeName = probeTokenizer.nextToken();
+
+ TreeNode probeNode = makeProbeAliasNode(probeName,
+ definition == null ? findDefinitionOf(probeName) : definition);
+
+ groupNode = addOrFindProbeGroup(
+ groupName == null ? extractProbeGroupName(probeName) : groupName,
+ groupNode, aliases);
+
+ groupNode.add(probeNode);
+ addAllVarNodesToProbeNode(probeTokenizer, probeNode);
+ return groupNode;
}
/**
- * Find the appropriate parent group node for a probe alias to group probes by name.
+ * Finds the appropriate parent group node for a probe alias to group probes by name.
* If it doesn't yet exist, create it and add it to the view's tree.
- * @param probeLine The name of the probe group.
+ * @param groupName The name of the probe group.
* @param groupNode For optimization, pass an existing group node here, as it will be
* used if the probe belongs in it. Otherwise, or if <code>null</code> is passed, a new one will be created.
* @param category The parent tree node in which to put the group node.
* @return The found or created group node that will be the parent of the probe's entry item in the view.
*/
private TreeNode addOrFindProbeGroup(String groupName, TreeNode groupNode, TreeNode category) {
-
// If the current probe belongs to a group other than
// the most recent group. This should rarely be needed because the
// probe list is sorted... mostly.
@@ -190,50 +219,38 @@ public final class ProbeParser extends TreeTapsetParser {
* @return the name of the group a probe belongs to, based on the probe's name.
*/
private String extractProbeGroupName(String probeName) {
- int dotIndex = probeName.indexOf('.');
- int parenIndex = probeName.indexOf('(');
- if (dotIndex > 0 && parenIndex > 0) {
- return probeName.substring(0, Math.min(dotIndex, parenIndex));
- }
- if (dotIndex > 0) {
- return probeName.substring(0, dotIndex);
- }
- if (parenIndex > 0) {
- return probeName.substring(0, parenIndex);
- }
- return probeName;
+ Matcher m = PROBE_GROUP_PATTERN.matcher(probeName);
+ return m.find() ? m.group() : probeName;
}
private TreeNode makeStaticProbeNode(String probeName) {
return new TreeNode(new ProbeNodeData(probeName), probeName, true);
}
- private TreeNode makeProbeAliasNode(String probeName) {
- return new TreeDefinitionNode(new ProbeNodeData(probeName), probeName, findDefinitionOf(probeName), true);
+ private TreeNode makeProbeAliasNode(String probeName, String definition) {
+ return new TreeDefinitionNode(new ProbeNodeData(probeName), probeName, definition, true);
}
/**
- * Search the tapset content dump for the path of the file which defines the provided probe alias.
+ * Searches the tapset content dump for the path of the file which defines the provided probe alias.
* @param probeName The alias of the probe to find the definition file of.
* @return The path of the probe's definition file, or <code>null</code> if a definition
* file can't be found (which is the case for static probes).
*/
private String findDefinitionOf(String probeName) {
- SharedParser sparser = SharedParser.getInstance();
- String tapsetContents = sparser.getTapsetContents();
+ String tapsetContents = SharedParser.getInstance().getTapsetContents();
if (tapsetContents == null) {
return null;
}
- Matcher probeMatcher = Pattern.compile(MessageFormat.format(TAPSET_PROBE_REGEX, Pattern.quote(probeName))).matcher(tapsetContents);
+ Matcher probeMatcher = Pattern.compile(MessageFormat.format(
+ TAPSET_PROBE_REGEX, Pattern.quote(probeName))).matcher(tapsetContents);
if (!probeMatcher.find()) {
return null;
}
- int fileLocIndex = tapsetContents.substring(0, probeMatcher.start()).lastIndexOf(SharedParser.TAG_FILE);
+ int fileLocIndex = tapsetContents.substring(0, probeMatcher.start())
+ .lastIndexOf(SharedParser.TAG_FILE);
try (Scanner scanner = new Scanner(tapsetContents.substring(fileLocIndex))) {
- Matcher fileMatcher = sparser.filePattern.matcher(scanner.nextLine());
- return fileMatcher.matches()
- ? fileMatcher.group(1)
- : null;
+ return SharedParser.findFileNameInTag(scanner.nextLine());
}
}
@@ -264,10 +281,99 @@ public final class ProbeParser extends TreeTapsetParser {
prev.setLength(prev.length() - 1); // Remove the trailing space.
addVarNodeToProbeNode(prev.toString(), probeNode);
}
+ probeNode.sortLevel();
}
private void addVarNodeToProbeNode(String info, TreeNode probeNode) {
probeNode.add(new TreeNode(new ProbevarNodeData(info), info, false));
}
+ @Override
+ protected int delTapsets(String[] tapsets, IProgressMonitor monitor) {
+ TreeNode aliases = tree.getChildByName(Messages.ProbeParser_aliasProbes);
+
+ // Search through alias groups for probes whose definition files
+ // come from removed directories, and remove them from the group.
+ for (int i = 0; i < tapsets.length; i++) {
+ for (int g = 0, gn = aliases.getChildCount(); g < gn; g++) {
+ if (monitor.isCanceled()) {
+ return IStatus.CANCEL;
+ }
+ TreeNode group = aliases.getChildAt(g);
+ for (int p = 0, pn = group.getChildCount(); p < pn; p++) {
+ String definition = ((TreeDefinitionNode) group.getChildAt(p)).getDefinition();
+ if (definition != null && definition.startsWith(tapsets[i])) {
+ group.remove(p--);
+ pn--;
+ }
+ }
+ // If removing the only probe left in a probe group, remove the group.
+ if (group.getChildCount() == 0) {
+ aliases.remove(g--);
+ gn--;
+ }
+ }
+ }
+ return IStatus.OK;
+ }
+
+ @Override
+ protected int addTapsets(String[] additions, IProgressMonitor monitor) {
+ String tapsetContents = SharedParser.getInstance().getTapsetContents();
+ boolean canceled = false;
+ TreeNode aliases = tree.getChildByName(Messages.ProbeParser_aliasProbes);
+ Map<String, ArrayList<String>> fileToItemMap = new HashMap<>();
+
+ // Search tapset contents for all files provided by each added directory.
+ for (int i = 0; i < additions.length; i++) {
+ int firstTagIndex = 0;
+ while (true) {
+ // Get the contents of each file provided by the directory additions[i].
+ firstTagIndex = tapsetContents.indexOf(
+ SharedParser.makeFileTag(additions[i]), firstTagIndex);
+ if (firstTagIndex == -1) {
+ break;
+ }
+ int nextTagIndex = tapsetContents.indexOf(SharedParser.TAG_FILE, firstTagIndex + 1);
+ String fileContents = nextTagIndex != -1
+ ? tapsetContents.substring(firstTagIndex, nextTagIndex)
+ : tapsetContents.substring(firstTagIndex);
+
+ String filename;
+ try (Scanner st = new Scanner(fileContents)) {
+ filename = SharedParser.findFileNameInTag(st.nextLine());
+ }
+
+ // Search file contents for the probes the file provides.
+ ArrayList<String> newItems = new ArrayList<>();
+ Matcher matcher = Pattern.compile(MessageFormat.format(
+ TAPSET_PROBE_REGEX, "(\\S+)")) //$NON-NLS-1$
+ .matcher(fileContents);
+ while (matcher.find()) {
+ newItems.add(matcher.group(1));
+ }
+ if (!newItems.isEmpty()) {
+ fileToItemMap.put(filename, newItems);
+ }
+ // Remove the contents of the file that was just examined from the total contents.
+ tapsetContents = tapsetContents.substring(0, firstTagIndex).concat(
+ tapsetContents.substring(firstTagIndex + fileContents.length()));
+ }
+ }
+ // Run stap on each discovered probe to obtain their variable information.
+ for (String file : fileToItemMap.keySet()) {
+ for (String newitem : fileToItemMap.get(file)) {
+ if (canceled || monitor.isCanceled()) {
+ canceled = true;
+ break;
+ }
+ addSingleProbeAlias(runStap(new String[]{"-L"}, newitem, false), //$NON-NLS-1$
+ aliases, null, null, file);
+ }
+ }
+
+ aliases.sortTree();
+ return !canceled ? IStatus.OK : IStatus.CANCEL;
+ }
+
}

Back to the top