aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrew Ferrazzutti2013-10-09 16:56:28 (EDT)
committerJeff Johnston2014-01-08 17:54:53 (EST)
commitf52f13b7f628dab0eb49752606715b468a926899 (patch)
tree8c3fdfc84e50c5004cce916a949df260433192fe
parent5aceeed369aeb481e25e41712f73bf7f77d01e1d (diff)
downloadorg.eclipse.linuxtools-f52f13b7f628dab0eb49752606715b468a926899.zip
org.eclipse.linuxtools-f52f13b7f628dab0eb49752606715b468a926899.tar.gz
org.eclipse.linuxtools-f52f13b7f628dab0eb49752606715b468a926899.tar.bz2
Systemtap: Generate regexs with printfs.refs/changes/11/18911/8
Add a feature in Systemtap Run Configurations->Graphing for generating output-parsing regular expressions from printf statements in the target script. Change-Id: Ibdeab54b55ee6b714ec9e932dc8fe65d0915ab3c Signed-off-by: Andrew Ferrazzutti <aferrazz@redhat.com> Reviewed-on: https://git.eclipse.org/r/18911 Reviewed-by: Jeff Johnston <jjohnstn@redhat.com> IP-Clean: Jeff Johnston <jjohnstn@redhat.com> Tested-by: Jeff Johnston <jjohnstn@redhat.com>
-rw-r--r--systemtap/org.eclipse.linuxtools.systemtap.ui.ide.tests/src/org/eclipse/linuxtools/systemtap/ui/ide/test/swtbot/TestCreateSystemtapScript.java71
-rw-r--r--systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/launcher/CommentRemover.java57
-rw-r--r--systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/launcher/Messages.java8
-rw-r--r--systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/launcher/SystemTapScriptGraphOptionsTab.java363
-rw-r--r--systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/launcher/SystemTapScriptLaunchConfigurationTab.java2
-rw-r--r--systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/launcher/messages.properties11
6 files changed, 460 insertions, 52 deletions
diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide.tests/src/org/eclipse/linuxtools/systemtap/ui/ide/test/swtbot/TestCreateSystemtapScript.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide.tests/src/org/eclipse/linuxtools/systemtap/ui/ide/test/swtbot/TestCreateSystemtapScript.java
index 58e7018..a36e039 100644
--- a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide.tests/src/org/eclipse/linuxtools/systemtap/ui/ide/test/swtbot/TestCreateSystemtapScript.java
+++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide.tests/src/org/eclipse/linuxtools/systemtap/ui/ide/test/swtbot/TestCreateSystemtapScript.java
@@ -169,7 +169,6 @@ public class TestCreateSystemtapScript {
}
public static void createScript(SWTWorkbenchBot bot, String scriptName) {
-
SWTBotMenu fileMenu = bot.menu("File");
SWTBotMenu newMenu = fileMenu.menu("New");
SWTBotMenu projectMenu = newMenu.menu("Other...");
@@ -223,7 +222,7 @@ public class TestCreateSystemtapScript {
SWTBotView console = bot.viewById("org.eclipse.ui.console.ConsoleView");
console.setFocus();
assertTrue(console.bot().label().getText().contains(scriptName));
- bot.waitUntil(new StapHasExited(), 10000);
+ bot.waitUntil(new StapHasExited()); // The script should end on its own
} else {
bot.button("Close").click();
bot.waitUntil(new ShellIsClosed(shell));
@@ -371,7 +370,8 @@ public class TestCreateSystemtapScript {
+ "\nglobal i,j,k"
+ "\nprobe begin{i=0;j=0;k=0}"
+ "\nprobe timer.ms(100){printf(\"Value:%d %d\\n\",i,j);i++;j+=2}"
- + "\nprobe timer.ms(250){printf(\"Other:%d %d\\n\",i,k);k++}");
+ + "\nprobe timer.ms(250){printf(\"Other:%d %d\\n\",i,k);k++}"
+ + "\nprobe timer.ms(1000){exit()}");
editor.save();
String val0 = "i";
@@ -472,8 +472,7 @@ public class TestCreateSystemtapScript {
bot.sleep(2500); // Let the script run for a moment
SWTBotView console = bot.viewById("org.eclipse.ui.console.ConsoleView");
console.setFocus();
- console.toolbarButton("Stop Script").click(); // Stop the script manually
- bot.waitUntil(new StapHasExited(), 10000);
+ bot.waitUntil(new StapHasExited()); // The script should end on its own
bot.sleep(1000); // Give time for the table to be fully constructed
SWTBotEditor graphDisplay = bot.activeEditor();
@@ -499,6 +498,68 @@ public class TestCreateSystemtapScript {
assertEquals("3", dataTable.cell(3, 2));
}
+ @Test
+ public void testGenerateFromPrintf() {
+ String scriptName = "testGenerates.stp";
+ createScript(bot, scriptName);
+
+ // Write a script
+ SWTBotEclipseEditor editor = bot.editorByTitle(scriptName).toTextEditor();
+ editor.setText("#!/usr/bin/env stap"
+ + "\nglobal i,j,k,a"
+ + "\nprobe begin{i=0;j=5;k=20;a=65}"
+ + "\n#probe begin{printf(\"%1b%1b%1blo %1b%1brld\\n\", 72,101,108,87,111)}"
+ + "\nprobe timer.ms(100){printf(\"%5i|\\n%10.5d|\\n%-10.5i|\\n%05c\\n\",i,j,k,a);i++;j+=5;k+=20;a++}"
+ + "\n//printf(\"this is a comment\\n\");"
+ + "\n/*printf(\"this is a...\\n\");"
+ + "\nprintf(\"...multiline comment\\n\");*/"
+ + "\nprobe begin{b = sprintf(\"Here\"); printf(\"-->%s<--\\n\", b)}"
+ + "\nprobe timer.ms(100){printf(\"%x - %#x - %#X\\n\",i,i,i);}"
+ + "\nprobe timer.ms(100){printf(\"%o - %#o\\n\",i,i);}"
+ + "\nprobe begin{printf(\"%1b-\\\\n-%p\\n\", 65, 0x8000000002345678)}");
+ editor.save();
+
+ openRunConfigurations(scriptName);
+ SWTBotShell shell = bot.shell("Run Configurations");
+ shell.setFocus();
+ SWTBotTree runConfigurationsTree = bot.tree();
+ runConfigurationsTree.select("SystemTap").contextMenu("New").click();
+
+ // Select the "Graphing" tab.
+ SWTBotCTabItem tab = bot.cTabItem(Messages.SystemTapScriptGraphOptionsTab_7);
+ tab.activate();
+
+ // Generate regexs.
+ bot.checkBox(Messages.SystemTapScriptGraphOptionsTab_2).click();
+ bot.button(Messages.SystemTapScriptGraphOptionsTab_generateFromPrintsButton).click();
+
+ SWTBotShell shell2 = bot.shell(Messages.SystemTapScriptGraphOptionsTab_generateFromPrintsTitle);
+ shell2.setFocus();
+ bot.button("Yes").click();
+ bot.waitUntil(new ShellIsClosed(shell2));
+ shell.setFocus();
+
+ SWTBotCombo combo = bot.comboBoxWithLabel(Messages.SystemTapScriptGraphOptionsTab_regexLabel);
+ assertEquals(9, combo.itemCount()); // One extra entry for "Add New Regex"
+
+ String[] expectedRegexs = new String[]{
+ " {0,4}(-?\\d+)\\|",
+ " {0,9}(-?\\d+)\\|",
+ "(-?\\d+) {0,9}\\|",
+ " {0,4}(.)",
+ "-->(.+)<--",
+ "([a-f0-9]+) - (0x[a-f0-9]+) - (0X[A-F0-9]+)",
+ "(\\d+) - (0\\d+)",
+ "(.)-\\\\n-(0x[a-f0-9]+)",
+ Messages.SystemTapScriptGraphOptionsTab_regexAddNew
+ };
+ for (int i = 0, n = combo.itemCount(); i < n; i++) {
+ assertEquals(expectedRegexs[i], combo.items()[i]);
+ }
+ bot.button("Apply").click();
+ bot.button("Close").click();
+ }
+
private void openRunConfigurations(String scriptName) {
// Focus on project explorer view.
bot.viewByTitle("Project Explorer").setFocus();
diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/launcher/CommentRemover.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/launcher/CommentRemover.java
new file mode 100644
index 0000000..bd8e283
--- /dev/null
+++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/launcher/CommentRemover.java
@@ -0,0 +1,57 @@
+package org.eclipse.linuxtools.internal.systemtap.ui.ide.launcher;
+
+class CommentRemover {
+
+ public static String exec(String contents) {
+ if (contents.length() == 0)
+ return ""; //$NON-NLS-1$
+
+ char curchar, nxtchar;
+ boolean inQuotes = false;
+ boolean inComment = false;
+
+ int c = 0;
+ StringBuffer buffer = new StringBuffer();
+
+ do {
+ curchar = contents.charAt(c++);
+ nxtchar = c < contents.length() ? contents.charAt(c) : '\0';
+
+ // Comment tags don't count if they are in a string.
+ if (!inQuotes) {
+ if (!inComment) {
+ if (curchar == '#' || (curchar == '/' && nxtchar == '/')) {
+ inQuotes = false;
+ c = contents.indexOf('\n', c + 1);
+ continue;
+ }
+ if (curchar == '/' && nxtchar == '*') {
+ inComment = true;
+ c++; //Skip the * on the next character scan.
+ continue;
+ }
+ }
+ else if (curchar == '*' && nxtchar == '/') {
+ inComment = false;
+ c++; //Skip the / on the next character scan.
+ continue;
+ }
+ }
+
+ // Quotes only count if they aren't commented out.
+ if (!inComment) {
+ if (curchar == '\"') {
+ inQuotes = !inQuotes;
+ }
+ else if (curchar == '\n') {
+ inQuotes = false;
+ }
+
+ buffer.append(curchar);
+ }
+
+ } while (c != -1 && c < contents.length());
+
+ return buffer.toString();
+ }
+} \ No newline at end of file
diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/launcher/Messages.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/launcher/Messages.java
index e7abe00..faf3126 100644
--- a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/launcher/Messages.java
+++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/launcher/Messages.java
@@ -57,6 +57,14 @@ public class Messages extends NLS {
public static String SystemTapScriptGraphOptionsTab_sampleOutputNoMatch;
public static String SystemTapScriptGraphOptionsTab_sampleOutputIsEmpty;
+ public static String SystemTapScriptGraphOptionsTab_generateFromPrintsButton;
+ public static String SystemTapScriptGraphOptionsTab_generateFromPrintsTooltip;
+ public static String SystemTapScriptGraphOptionsTab_generateFromPrintsTitle;
+ public static String SystemTapScriptGraphOptionsTab_generateFromPrintsMessage;
+ public static String SystemTapScriptGraphOptionsTab_generateFromPrintsErrorTitle;
+ public static String SystemTapScriptGraphOptionsTab_generateFromPrintsError;
+ public static String SystemTapScriptGraphOptionsTab_generateFromPrintsEmpty;
+
public static String SystemTapScriptLaunchConfigurationTab_0;
public static String SystemTapScriptLaunchConfigurationTab_1;
public static String SystemTapScriptLaunchConfigurationTab_2;
diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/launcher/SystemTapScriptGraphOptionsTab.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/launcher/SystemTapScriptGraphOptionsTab.java
index aac030b..4f1aced 100644
--- a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/launcher/SystemTapScriptGraphOptionsTab.java
+++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/launcher/SystemTapScriptGraphOptionsTab.java
@@ -12,6 +12,11 @@
package org.eclipse.linuxtools.internal.systemtap.ui.ide.launcher;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.nio.charset.Charset;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.LinkedList;
@@ -21,11 +26,16 @@ import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;
+import org.eclipse.core.resources.IWorkspaceRoot;
+import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
import org.eclipse.debug.ui.AbstractLaunchConfigurationTab;
+import org.eclipse.debug.ui.ILaunchConfigurationTab;
import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.wizard.WizardDialog;
import org.eclipse.linuxtools.internal.systemtap.ui.ide.IDEPlugin;
import org.eclipse.linuxtools.systemtap.graphingapi.core.datasets.IDataSet;
@@ -56,12 +66,16 @@ import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.swt.widgets.Text;
+import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.ide.ResourceUtil;
import org.eclipse.ui.plugin.AbstractUIPlugin;
+import org.eclipse.ui.texteditor.IDocumentProvider;
+import org.eclipse.ui.texteditor.ITextEditor;
public class SystemTapScriptGraphOptionsTab extends
- AbstractLaunchConfigurationTab {
+ AbstractLaunchConfigurationTab {
/**
* The maximum number of regular expressions that can be stored in a configuration.
@@ -90,50 +104,10 @@ public class SystemTapScriptGraphOptionsTab extends
protected Pattern pattern;
protected Matcher matcher;
- private ModifyListener regexListener = new ModifyListener() {
- @Override
- public void modifyText(ModifyEvent event) {
- if (!textListenersEnabled || regularExpressionCombo.getSelectionIndex() != -1) {
- return;
- }
- regularExpressionCombo.setItem(selectedRegex, regularExpressionCombo.getText());
- regularExpressionCombo.select(selectedRegex);
- refreshRegexRows();
- updateLaunchConfigurationDialog();
- }
- };
-
- private ModifyListener sampleOutputListener = new ModifyListener() {
- @Override
- public void modifyText(ModifyEvent event) {
- if (!textListenersEnabled) {
- return;
- }
- outputList.set(selectedRegex, sampleOutputText.getText());
- refreshRegexRows();
- updateLaunchConfigurationDialog();
- }
- };
-
- private ModifyListener columnNameListener = new ModifyListener() {
- @Override
- public void modifyText(ModifyEvent event) {
- if (!textListenersEnabled) {
- return;
- }
-
- ArrayList<String> columnNames = new ArrayList<String>();
- Control[] children = textFieldsComposite.getChildren();
- for (int i = 0; i < numberOfVisibleColumns; i++) {
- columnNames.add(((Text)children[i*2]).getText());
- }
- columnNamesList.set(selectedRegex, columnNames);
- updateLaunchConfigurationDialog();
- }
- };
-
private Combo regularExpressionCombo;
private Button removeRegexButton;
+ private Button generateExpsButton;
+
private Text sampleOutputText;
private Composite textFieldsComposite;
@@ -202,6 +176,292 @@ public class SystemTapScriptGraphOptionsTab extends
*/
private List<GraphData> badGraphs = new LinkedList<GraphData>();
+ private ModifyListener regexListener = new ModifyListener() {
+ @Override
+ public void modifyText(ModifyEvent event) {
+ if (!textListenersEnabled || regularExpressionCombo.getSelectionIndex() != -1) {
+ return;
+ }
+ regularExpressionCombo.setItem(selectedRegex, regularExpressionCombo.getText());
+ regularExpressionCombo.select(selectedRegex);
+ refreshRegexRows();
+ updateLaunchConfigurationDialog();
+ }
+ };
+
+ private ModifyListener sampleOutputListener = new ModifyListener() {
+ @Override
+ public void modifyText(ModifyEvent event) {
+ if (!textListenersEnabled) {
+ return;
+ }
+ outputList.set(selectedRegex, sampleOutputText.getText());
+ refreshRegexRows();
+ updateLaunchConfigurationDialog();
+ }
+ };
+
+ private ModifyListener columnNameListener = new ModifyListener() {
+ @Override
+ public void modifyText(ModifyEvent event) {
+ if (!textListenersEnabled) {
+ return;
+ }
+
+ ArrayList<String> columnNames = new ArrayList<String>();
+ Control[] children = textFieldsComposite.getChildren();
+ for (int i = 0; i < numberOfVisibleColumns; i++) {
+ columnNames.add(((Text)children[i*2]).getText());
+ }
+ columnNamesList.set(selectedRegex, columnNames);
+ updateLaunchConfigurationDialog();
+ }
+ };
+
+ private SelectionAdapter regexGenerator = new SelectionAdapter() {
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ MessageDialog dialog;
+ IWorkbench workbench = PlatformUI.getWorkbench();
+ IPath scriptPath = null;
+ for (ILaunchConfigurationTab tab : getLaunchConfigurationDialog().getTabs()) {
+ if (tab instanceof SystemTapScriptLaunchConfigurationTab) {
+ scriptPath = ((SystemTapScriptLaunchConfigurationTab) tab).getScriptPath();
+ break;
+ }
+ }
+ if (scriptPath == null) {
+ dialog = new MessageDialog(workbench
+ .getActiveWorkbenchWindow().getShell(), Messages.SystemTapScriptGraphOptionsTab_generateFromPrintsErrorTitle, null,
+ Messages.SystemTapScriptGraphOptionsTab_generateFromPrintsError,
+ MessageDialog.ERROR, new String[]{"OK"}, 0); //$NON-NLS-1$
+ dialog.open();
+ return;
+ }
+
+ dialog = new MessageDialog(workbench
+ .getActiveWorkbenchWindow().getShell(), Messages.SystemTapScriptGraphOptionsTab_generateFromPrintsTitle, null,
+ Messages.SystemTapScriptGraphOptionsTab_generateFromPrintsMessage,
+ MessageDialog.QUESTION, new String[]{"Yes", "Cancel"}, 0); //$NON-NLS-1$ //$NON-NLS-2$
+ int result = dialog.open();
+ if (result != 0) { // Cancel
+ return;
+ }
+
+ textListenersEnabled = false;
+ // If editor of this file is open, take current file contents.
+ String contents = null;
+ IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
+ IEditorPart editor = ResourceUtil.findEditor(workbench.getActiveWorkbenchWindow().getActivePage(), root.getFile(scriptPath.makeRelativeTo(root.getLocation())));
+ if (editor != null) {
+ ITextEditor t_editor = (ITextEditor) editor.getAdapter(ITextEditor.class);
+ if (t_editor != null) {
+ IDocumentProvider provider = t_editor.getDocumentProvider();
+ IDocument document = provider.getDocument(t_editor.getEditorInput());
+ contents = document.get();
+ }
+ }
+
+ // If chosen file is not being edited or is outside of the workspace, use the saved contents of the file itself.
+ if (contents == null) {
+ try {
+ File scriptFile = scriptPath.toFile();
+ FileInputStream f = new FileInputStream(scriptFile);
+ byte[] data = new byte[(int)scriptFile.length()];
+ f.read(data);
+ f.close();
+ contents = new String(data, Charset.defaultCharset());
+ } catch (IOException e1) {
+ dialog = new MessageDialog(workbench
+ .getActiveWorkbenchWindow().getShell(), Messages.SystemTapScriptGraphOptionsTab_generateFromPrintsErrorTitle, null,
+ Messages.SystemTapScriptGraphOptionsTab_generateFromPrintsError,
+ MessageDialog.ERROR, new String[]{"OK"}, 0); //$NON-NLS-1$
+ dialog.open();
+ return;
+ }
+ }
+
+ // Delete comments from the file contents. Ignore comment markers between quotes.
+ contents = CommentRemover.exec(contents);
+
+ // Now actually search the contents for "printf(...)" statements. (^|[\s({;])printf\("(.+?)",.+\)
+ Pattern pattern = Pattern.compile("(?<![a-zA-Z])printf\\(\"(.+?)\",.+\\)"); //$NON-NLS-1$
+ Matcher matcher = pattern.matcher(contents);
+ boolean firstfound = false;
+ while (matcher.find() && (!firstfound || getNumberOfRegexs() < MAX_NUMBER_OF_REGEXS)) {
+ String regex = null;
+
+ // Note: allow optional "long" modifier 'l'. Not captured because it doesn't impact output format.
+ // Also, don't support variable width/precision modifiers (*).
+ // TODO: Consider %m & %M support.
+ Pattern format = Pattern.compile("%([-\\+ \\#0])?(\\d+)?(\\.\\d*)?l?([bcdiopsuxX%])"); //$NON-NLS-1$
+
+ // Only capture until newlines to preserve the "column" format.
+ // Don't try gluing together output from multiple printfs
+ // since asynchronous prints would make things messy.
+ String[] printls = matcher.group(1).split("\\\\n"); //$NON-NLS-1$
+ for (int i = 0; i < printls.length; i++) {
+ String printl = printls[i];
+ // Ignore newlines if they are escaped ("\\n").
+ if (printl.endsWith("\\")) { //$NON-NLS-1$
+ printls[i+1] = printl.concat("\\n" + printls[i+1]); //$NON-NLS-1$
+ continue;
+ }
+
+ Matcher fmatch = format.matcher(printl);
+ int lastend = 0;
+ ArrayList<String> columnNames = new ArrayList<String>();
+ int r = 0;
+
+ while (fmatch.find()) {
+ char chr = fmatch.group(4) == null ? '\0' : fmatch.group(4).charAt(0);
+ if (chr == '\0') {
+ // Skip this statement if an invalid regex is found.
+ regex = null;
+ break;
+ }
+ char flag = fmatch.group(1) == null ? '\0' : fmatch.group(1).charAt(0);
+ int width = fmatch.group(2) == null ? 0 : Integer.parseInt(fmatch.group(2));
+ String precision = fmatch.group(3) == null ? null : fmatch.group(3).substring(1);
+
+ // First, add any non-capturing characters.
+ String pre = addRegexEscapes(printl.substring(lastend, fmatch.start()));
+ regex = lastend > 0 ? regex.concat(pre) : pre;
+ lastend = fmatch.end();
+
+ // Now add what will be captured.
+ String target = "("; //$NON-NLS-1$
+ if (chr == 'u' || (flag != '#' && chr == 'o')) {
+ target = target.concat("\\d+"); //$NON-NLS-1$
+ }
+ else if (chr == 'd' || chr == 'i') {
+ if (flag == '+') {
+ target = target.concat("\\+|"); //$NON-NLS-1$
+ } else if (flag == ' ') {
+ target = target.concat(" |"); //$NON-NLS-1$
+ }
+ target = target.concat("-?\\d+"); //$NON-NLS-1$
+ }
+ else if (flag == '#' && chr == 'o') {
+ target = target.concat("0\\d+"); //$NON-NLS-1$
+ }
+ else if (chr == 'p') {
+ target = target.concat("0x[a-f0-9]+"); //$NON-NLS-1$
+ }
+ else if (chr == 'x') {
+ if (flag == '#') {
+ target = target.concat("0x"); //$NON-NLS-1$
+ }
+ target = target.concat("[a-f0-9]+"); //$NON-NLS-1$
+ }
+ else if (chr == 'X') {
+ if (flag == '#') {
+ target = target.concat("0X"); //$NON-NLS-1$
+ }
+ target = target.concat("[A-F0-9]+"); //$NON-NLS-1$
+ }
+ else if (chr == 'b') {
+ target = target.concat("."); //$NON-NLS-1$
+ }
+ else if (chr == 'c') {
+ if (flag != '#') {
+ target = target.concat("."); //$NON-NLS-1$
+ } else {
+ target = target.concat("\\([a-z]|[0-9]{3})|.|\\\\"); //$NON-NLS-1$
+ }
+ }
+ else if (chr == 's') {
+ if (precision != null) {
+ target = target.concat(".{" + precision + "}"); //$NON-NLS-1$ //$NON-NLS-2$
+ } else {
+ target = target.concat(".+"); //$NON-NLS-1$
+ }
+ }
+ else {
+ // Invalid or unhandled format specifier. Skip this regex.
+ regex = null;
+ break;
+ }
+
+ target = target.concat(")"); //$NON-NLS-1$
+
+ // Handle the optional width specifier.
+ // Ignore it for %b, which uses the width value in a different way.
+ if (chr != 'b' && --width > 0) {
+ if (flag == '-') {
+ target = target.concat(" {0," + width + "}"); //$NON-NLS-1$ //$NON-NLS-2$
+ } else if (flag != '0' || chr == 's' || chr == 'c'){
+ target = " {0," + width + "}".concat(target); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ }
+
+ regex = regex.concat(target);
+ columnNames.add(MessageFormat.format(Messages.SystemTapScriptGraphOptionsTab_defaultColumnTitleBase, ++r));
+ }
+ if (regex != null) {
+ if (!firstfound) {
+ // Since script output has been found, reset the configuration's regexs.
+ // Only reset once/if something is found, and do it only one time.
+ regularExpressionCombo.removeAll();
+ outputList.clear();
+ regexErrorMessages.clear();
+ columnNamesList.clear();
+ cachedNamesList.clear();
+ graphsTable.removeAll();
+ graphsDataList.clear();
+ badGraphs.clear();
+ firstfound = true;
+ }
+ // Finally, add the uncaptured remainder of the print statement to the regex.
+ regex = regex.concat(addRegexEscapes(printl.substring(lastend)));
+
+ regularExpressionCombo.add(regex);
+ outputList.add(""); //$NON-NLS-1$ //For empty "sample output" entry.
+ regexErrorMessages.add(null);
+ columnNamesList.add(columnNames);
+ cachedNamesList.add(new Stack<String>());
+ graphsDataList.add(new LinkedList<GraphData>());
+ }
+ }
+ }
+ textListenersEnabled = true;
+
+ if (!firstfound) {
+ dialog = new MessageDialog(workbench
+ .getActiveWorkbenchWindow().getShell(), Messages.SystemTapScriptGraphOptionsTab_generateFromPrintsErrorTitle, null,
+ Messages.SystemTapScriptGraphOptionsTab_generateFromPrintsEmpty,
+ MessageDialog.ERROR, new String[]{"OK"}, 0); //$NON-NLS-1$
+ dialog.open();
+ return;
+ }
+
+ if (getNumberOfRegexs() < MAX_NUMBER_OF_REGEXS) {
+ regularExpressionCombo.add(Messages.SystemTapScriptGraphOptionsTab_regexAddNew);
+ }
+
+ removeRegexButton.setEnabled(getNumberOfRegexs() > 1);
+ regularExpressionCombo.select(0);
+ updateRegexSelection(0, true);
+ checkAllOtherErrors(); // Check for errors in case there was a problem with regex generation
+ updateLaunchConfigurationDialog();
+ }
+
+ /**
+ * This escapes all special regex characters in a string. Escapes must be added
+ * to the generated regexs to capture printf output that doesn't
+ * come from format specifiers (aka literal strings).
+ * @param s The string to add escapes to.
+ * @return The same string, after it has been modified with escapes.
+ */
+ private String addRegexEscapes(String s) {
+ String schars = "[^$.|?*+(){}"; //$NON-NLS-1$
+ for (int i = 0; i < schars.length(); i++) {
+ s = s.replaceAll("(\\" + schars.substring(i,i+1) + ")", "\\\\$1"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ }
+ return s;
+ }
+ };
+
/**
* Returns the list of the names given to reach regular expression.
* @param configuration
@@ -380,12 +640,25 @@ public class SystemTapScriptGraphOptionsTab extends
GridLayout layout = new GridLayout();
parent.setLayout(layout);
+ GridLayout oneColumn = new GridLayout();
+ oneColumn.numColumns = 1;
+
GridLayout twoColumns = new GridLayout();
twoColumns.numColumns = 2;
GridLayout threeColumns = new GridLayout();
threeColumns.numColumns = 3;
+ Composite topLayout = new Composite(parent, SWT.NONE);
+ topLayout.setLayout(oneColumn);
+ topLayout.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false));
+
+ generateExpsButton = new Button(topLayout, SWT.PUSH);
+ generateExpsButton.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+ generateExpsButton.setText(Messages.SystemTapScriptGraphOptionsTab_generateFromPrintsButton);
+ generateExpsButton.setToolTipText(Messages.SystemTapScriptGraphOptionsTab_generateFromPrintsTooltip);
+ generateExpsButton.addSelectionListener(regexGenerator);
+
Composite regexButtonLayout = new Composite(parent, SWT.NONE);
regexButtonLayout.setLayout(threeColumns);
regexButtonLayout.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
@@ -461,7 +734,7 @@ public class SystemTapScriptGraphOptionsTab extends
.getActiveWorkbenchWindow().getShell(), Messages.SystemTapScriptGraphOptionsTab_removeRegexTitle, null,
MessageFormat.format(Messages.SystemTapScriptGraphOptionsTab_removeRegexAsk,
regularExpressionCombo.getItem(selectedRegex)),
- MessageDialog.QUESTION, new String[]{"Yes", "No"}, 0); //$NON-NLS-1$ //$NON-NLS-2$
+ MessageDialog.QUESTION, new String[]{"Yes", "No"}, 0); //$NON-NLS-1$ //$NON-NLS-2$
int result = dialog.open();
if (result == 0) { //Yes
removeRegex(true);
@@ -1269,7 +1542,7 @@ public class SystemTapScriptGraphOptionsTab extends
private void setControlEnabled(Composite composite, boolean enabled){
composite.setEnabled(enabled);
for (Control child : composite.getChildren()) {
- child.setEnabled(enabled);
+ child.setEnabled(enabled);
if(child instanceof Composite){
setControlEnabled((Composite)child, enabled);
}
diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/launcher/SystemTapScriptLaunchConfigurationTab.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/launcher/SystemTapScriptLaunchConfigurationTab.java
index b1d14cb..08d9a6b 100644
--- a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/launcher/SystemTapScriptLaunchConfigurationTab.java
+++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/launcher/SystemTapScriptLaunchConfigurationTab.java
@@ -72,7 +72,7 @@ public class SystemTapScriptLaunchConfigurationTab extends
* @return The path of the chosen script the Run Configuration will be applied to,
* or <code>null</code> if no file exists at the given path.
*/
- private IPath getScriptPath() {
+ IPath getScriptPath() {
IPath scriptPath = new Path(scriptPathText.getText());
return scriptPath.toFile().exists() ? scriptPath : null;
}
diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/launcher/messages.properties b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/launcher/messages.properties
index c8f38c9..c9d37a9 100644
--- a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/launcher/messages.properties
+++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/launcher/messages.properties
@@ -52,6 +52,15 @@ SystemTapScriptGraphOptionsTab_sampleOutputTooltip=Enter a line of output simila
SystemTapScriptGraphOptionsTab_sampleOutputNoMatch=<no match found>
SystemTapScriptGraphOptionsTab_sampleOutputIsEmpty=<no sample output entered>
+SystemTapScriptGraphOptionsTab_generateFromPrintsButton=Click here to generate regular expressions from printf statements.
+SystemTapScriptGraphOptionsTab_generateFromPrintsTooltip=This will create a set of regexs that will capture data output by your script's printf statements.\n\
+It is a quick way to graph whatever data your script outputs, without having to write your own regexs.
+SystemTapScriptGraphOptionsTab_generateFromPrintsTitle=Generate Regular Expressions
+SystemTapScriptGraphOptionsTab_generateFromPrintsMessage=Generate regular expressions from format strings in your script's printf statements? Doing so will delete all existing graphs and expressions.
+SystemTapScriptGraphOptionsTab_generateFromPrintsErrorTitle=Generate Regular Expressions - Error
+SystemTapScriptGraphOptionsTab_generateFromPrintsError=There was a error in finding the script for this Run Configuration. Check if the path to the file is correct.
+SystemTapScriptGraphOptionsTab_generateFromPrintsEmpty=No valid printf statements could be found. Make sure they contain format specifiers (like %d) to be captured and graphed.
+
SystemTapScriptLaunchConfigurationTab_0=Systemtap Script:
SystemTapScriptLaunchConfigurationTab_1=Browse...
SystemTapScriptLaunchConfigurationTab_2=Execute script as current user.
@@ -83,4 +92,4 @@ SystemTapScriptOptionsTab_targetToolTip=Select a target executable to be passed
SystemTapScriptLaunchError_graph=An error exists in this launch's graph settings. Please use the Run Configurations->Graphing menu to fix them.
SystemTapScriptLaunchError_fileNotFound=No Systemtap script exists at the path {0}. Please use the Run Configurations->General menu to set the path of the script to run.
SystemTapScriptLaunchError_fileNotStp={0} is not a Systemtap script file. Please use the Run Configurations->General menu to select a file with extension ".stp".
-SystemTapScriptLaunchError_waitForConsoles=Please wait for all existing SystemTap launches to be initialized before starting another one. \ No newline at end of file
+SystemTapScriptLaunchError_waitForConsoles=Please wait for all existing SystemTap launches to be initialized before starting another one.