From f52f13b7f628dab0eb49752606715b468a926899 Mon Sep 17 00:00:00 2001 From: Andrew Ferrazzutti Date: Wed, 9 Oct 2013 16:56:28 -0400 Subject: Systemtap: Generate regexs with printfs. 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 Reviewed-on: https://git.eclipse.org/r/18911 Reviewed-by: Jeff Johnston IP-Clean: Jeff Johnston Tested-by: Jeff Johnston --- .../ide/test/swtbot/TestCreateSystemtapScript.java | 71 +++- .../systemtap/ui/ide/launcher/CommentRemover.java | 57 ++++ .../systemtap/ui/ide/launcher/Messages.java | 8 + .../launcher/SystemTapScriptGraphOptionsTab.java | 363 ++++++++++++++++++--- .../SystemTapScriptLaunchConfigurationTab.java | 2 +- .../systemtap/ui/ide/launcher/messages.properties | 11 +- 6 files changed, 460 insertions(+), 52 deletions(-) create mode 100644 systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/launcher/CommentRemover.java 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 58e70188bc..a36e03998d 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 0000000000..bd8e283764 --- /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 e7abe00ab0..faf31261a3 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 aac030b9e2..4f1aced6b7 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 columnNames = new ArrayList(); - 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 badGraphs = new LinkedList(); + 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 columnNames = new ArrayList(); + 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("(? columnNames = new ArrayList(); + 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()); + graphsDataList.add(new LinkedList()); + } + } + } + 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 b1d14cb765..08d9a6b14e 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 null 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 c8f38c93f8..c9d37a9b87 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= SystemTapScriptGraphOptionsTab_sampleOutputIsEmpty= +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. -- cgit v1.2.3