Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrew Ferrazzutti2014-04-25 14:05:37 +0000
committerAlexander Kurtakov2014-04-26 05:35:49 +0000
commit9f5e0ed5dfda7ac2bf14f4b59228135bdbcb6a10 (patch)
tree6460ae9326e2948a1c746798febd00f82321f638 /systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui
parentfe48cecc1b6ba671cf0a70014e760413dae4cce9 (diff)
downloadorg.eclipse.linuxtools-9f5e0ed5dfda7ac2bf14f4b59228135bdbcb6a10.tar.gz
org.eclipse.linuxtools-9f5e0ed5dfda7ac2bf14f4b59228135bdbcb6a10.tar.xz
org.eclipse.linuxtools-9f5e0ed5dfda7ac2bf14f4b59228135bdbcb6a10.zip
Change tabs to spaces; elim trailing whitespace.
To comply with Sonar style requirements, replace all tab characters with four whitespace characters/spaces, and remove all trailing whitespace. Perform this change to all Java and XML files. Also replace tabs with "\t" in test strings that require tabs, and edit STPIndenterTest so that it doesn't rely on indented comments. Change-Id: I48c3c5449a58fe5310967d998a05df1a28fbcbb0 Signed-off-by: Andrew Ferrazzutti <aferrazz@redhat.com> Reviewed-on: https://git.eclipse.org/r/25561 Reviewed-by: Alexander Kurtakov <akurtako@redhat.com> Tested-by: Alexander Kurtakov <akurtako@redhat.com>
Diffstat (limited to 'systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui')
-rw-r--r--systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/CommentRemover.java168
-rw-r--r--systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/IDECloseMonitor.java28
-rw-r--r--systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/IDEPerspective.java54
-rw-r--r--systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/IDEPlugin.java154
-rw-r--r--systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/IDESessionSettings.java288
-rw-r--r--systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/Localization.java24
-rw-r--r--systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/StringOutputStream.java18
-rw-r--r--systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/actions/BrowserViewAction.java92
-rw-r--r--systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/actions/ExportDataSetHandler.java54
-rw-r--r--systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/actions/FunctionBrowserAction.java62
-rw-r--r--systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/actions/ImportDataSetHandler.java86
-rw-r--r--systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/actions/ImportTapsetHandler.java20
-rw-r--r--systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/actions/IndentHandler.java898
-rw-r--r--systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/actions/KernelSourceAction.java100
-rw-r--r--systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/actions/Messages.java36
-rw-r--r--systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/actions/ProbeAliasAction.java110
-rw-r--r--systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/actions/RunScriptChartHandler.java68
-rw-r--r--systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/actions/RunScriptHandler.java940
-rw-r--r--systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/actions/ToggleCommentHandler.java538
-rw-r--r--systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/actions/TreeExpandCollapseAction.java110
-rw-r--r--systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/CodeFormatterUtil.java12
-rw-r--r--systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/DocumentCharacterIterator.java422
-rw-r--r--systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/IndentUtil.java594
-rw-r--r--systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/Messages.java22
-rw-r--r--systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/STPAutoEditStrategy.java2084
-rw-r--r--systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/STPColorConstants.java14
-rw-r--r--systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/STPCompletionProcessor.java912
-rw-r--r--systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/STPConfiguration.java222
-rw-r--r--systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/STPDefaultCodeFormatterConstants.java792
-rw-r--r--systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/STPDocumentProvider.java48
-rw-r--r--systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/STPEditor.java172
-rw-r--r--systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/STPElementScanner.java156
-rw-r--r--systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/STPHeuristicScanner.java2070
-rw-r--r--systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/STPIndenter.java4588
-rw-r--r--systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/STPMetadataSingleton.java202
-rw-r--r--systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/STPPartitionScanner.java130
-rw-r--r--systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/STPPartitioner.java24
-rw-r--r--systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/STPProbeScanner.java48
-rw-r--r--systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/STPReconcilingStrategy.java320
-rw-r--r--systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/STPSymbols.java118
-rw-r--r--systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/handlers/AddStapProbeHandler.java192
-rw-r--r--systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/handlers/DefinitionHandler.java94
-rw-r--r--systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/handlers/DefinitionMenuTester.java14
-rw-r--r--systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/handlers/Messages.java22
-rw-r--r--systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/launcher/Messages.java188
-rw-r--r--systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/launcher/SystemTapScriptGraphOptionsTab.java3134
-rw-r--r--systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/launcher/SystemTapScriptLaunch.java160
-rw-r--r--systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/launcher/SystemTapScriptLaunchConfigurationDelegate.java264
-rw-r--r--systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/launcher/SystemTapScriptLaunchConfigurationTab.java586
-rw-r--r--systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/launcher/SystemTapScriptLaunchConfigurationTabGroup.java24
-rw-r--r--systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/launcher/SystemTapScriptLaunchShortcut.java222
-rw-r--r--systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/launcher/SystemTapScriptOptionsTab.java478
-rw-r--r--systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/preferences/CodeAssistPreferencePage.java82
-rw-r--r--systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/preferences/ConditionalExpressionValidator.java52
-rw-r--r--systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/preferences/ConditionalFilterPreferencePage.java28
-rw-r--r--systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/preferences/DirectoryValidator.java46
-rw-r--r--systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/preferences/EditorPreferencePage.java40
-rw-r--r--systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/preferences/EnvironmentVariablesPreferencePage.java256
-rw-r--r--systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/preferences/IDEPreferenceConstants.java108
-rw-r--r--systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/preferences/IDEPreferencePage.java40
-rw-r--r--systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/preferences/ListEditor.java38
-rw-r--r--systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/preferences/LocalRemoteDirectoryEditor.java74
-rw-r--r--systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/preferences/Messages.java36
-rw-r--r--systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/preferences/PathPreferencePage.java88
-rw-r--r--systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/preferences/PreferenceConstants.java14
-rw-r--r--systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/preferences/PreferenceInitializer.java174
-rw-r--r--systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/preferences/SyntaxColoringPreferencePage.java192
-rw-r--r--systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/preferences/SystemTapPreferencePage.java36
-rw-r--r--systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/preferences/TapsetsPreferencePage.java40
-rw-r--r--systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/FuncparamNodeData.java40
-rw-r--r--systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/FunctionNodeData.java80
-rw-r--r--systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/FunctionParser.java298
-rw-r--r--systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/ISearchableNode.java4
-rw-r--r--systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/ISingleTypedNode.java2
-rw-r--r--systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/Messages.java26
-rw-r--r--systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/ProbeNodeData.java60
-rw-r--r--systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/ProbeParser.java516
-rw-r--r--systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/ProbevarNodeData.java78
-rw-r--r--systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/SharedParser.java92
-rw-r--r--systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/StapErrorParser.java106
-rw-r--r--systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/TapsetLibrary.java736
-rw-r--r--systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/TapsetParser.java292
-rw-r--r--systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/TreeSettings.java480
-rw-r--r--systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/views/BrowserView.java262
-rw-r--r--systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/views/FunctionBrowserView.java174
-rw-r--r--systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/views/KernelBrowserView.java376
-rw-r--r--systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/views/ProbeAliasBrowserView.java136
-rw-r--r--systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/wizards/StapNewWizard.java176
-rw-r--r--systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/wizards/StapNewWizardPage.java316
89 files changed, 13885 insertions, 13885 deletions
diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/CommentRemover.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/CommentRemover.java
index 5eb76a78a8..a4751e88e6 100644
--- a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/CommentRemover.java
+++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/CommentRemover.java
@@ -23,98 +23,98 @@ public final class CommentRemover {
private CommentRemover() {}
- /**
- * Remove comments from a .stp file in the filesystem.
- * @param filename The filename of the script to remove comments from.
- * @return The copy of the script with comments removed.
- */
- public static String execWithFile(String filename) {
- try (BufferedReader br = new BufferedReader(new FileReader(filename))) {
- StringBuffer buffer = new StringBuffer();
- String line;
- while ((line = br.readLine()) != null) {
- buffer.append(line.concat("\n")); //$NON-NLS-1$
- }
- // No need to format line breaks, since this did it already with newlines.
- return exec(buffer.toString(), false);
- } catch (IOException e) {
- return ""; //$NON-NLS-1$
- }
- }
+ /**
+ * Remove comments from a .stp file in the filesystem.
+ * @param filename The filename of the script to remove comments from.
+ * @return The copy of the script with comments removed.
+ */
+ public static String execWithFile(String filename) {
+ try (BufferedReader br = new BufferedReader(new FileReader(filename))) {
+ StringBuffer buffer = new StringBuffer();
+ String line;
+ while ((line = br.readLine()) != null) {
+ buffer.append(line.concat("\n")); //$NON-NLS-1$
+ }
+ // No need to format line breaks, since this did it already with newlines.
+ return exec(buffer.toString(), false);
+ } catch (IOException e) {
+ return ""; //$NON-NLS-1$
+ }
+ }
- /**
- * Remove comments from a .stp script. Also, line breaks will be formatted to newlines.
- * @param contents A complete .stp script.
- * @return A copy of the script with comments removed.
- */
- public static String exec(String contents) {
- return exec(contents, true);
- }
+ /**
+ * Remove comments from a .stp script. Also, line breaks will be formatted to newlines.
+ * @param contents A complete .stp script.
+ * @return A copy of the script with comments removed.
+ */
+ public static String exec(String contents) {
+ return exec(contents, true);
+ }
- private static String exec(String contents, boolean standardizeLineBreaks) {
- if (contents == null || contents.isEmpty()) {
- return ""; //$NON-NLS-1$
- }
- if (standardizeLineBreaks) {
- contents = doStandardizeLineBreaks(contents);
- }
+ private static String exec(String contents, boolean standardizeLineBreaks) {
+ if (contents == null || contents.isEmpty()) {
+ return ""; //$NON-NLS-1$
+ }
+ if (standardizeLineBreaks) {
+ contents = doStandardizeLineBreaks(contents);
+ }
- char curchar, nxtchar;
- boolean inQuotes = false;
- boolean inComment = false;
+ char curchar, nxtchar;
+ boolean inQuotes = false;
+ boolean inComment = false;
- int c = 0;
- StringBuffer buffer = new StringBuffer();
+ int c = 0;
+ StringBuffer buffer = new StringBuffer();
- do {
- curchar = contents.charAt(c++);
- nxtchar = c < contents.length() ? contents.charAt(c) : '\0';
+ 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 == '/')) {
- buffer.append('\n'); // Replace the rest of this line with a newline.
- c = contents.indexOf('\n', c); // Skip past the next newline, if one exists.
- if (c == -1) {
- break;
- }
- c++; // Skip the newline character on the next character scan.
- 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;
- }
- }
+ // Comment tags don't count if they are in a string.
+ if (!inQuotes) {
+ if (!inComment) {
+ if (curchar == '#' || (curchar == '/' && nxtchar == '/')) {
+ buffer.append('\n'); // Replace the rest of this line with a newline.
+ c = contents.indexOf('\n', c); // Skip past the next newline, if one exists.
+ if (c == -1) {
+ break;
+ }
+ c++; // Skip the newline character on the next character scan.
+ 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) {
- inQuotes = false;
- }
- buffer.append(curchar);
- }
- else if (curchar == '\n') {
- // Print the line breaks of multiline comments.
- buffer.append(curchar);
- }
+ // Quotes only count if they aren't commented out.
+ if (!inComment) {
+ if (curchar == '\"') {
+ inQuotes = !inQuotes;
+ }
+ else if (curchar == '\n' && inQuotes) {
+ inQuotes = false;
+ }
+ buffer.append(curchar);
+ }
+ else if (curchar == '\n') {
+ // Print the line breaks of multiline comments.
+ buffer.append(curchar);
+ }
- } while (c < contents.length());
+ } while (c < contents.length());
- return buffer.toString();
- }
+ return buffer.toString();
+ }
- private static String doStandardizeLineBreaks(String contents) {
- return contents.replaceAll("(\\r\\n)|(\\n)", "\n"); //$NON-NLS-1$ //$NON-NLS-2$
- }
+ private static String doStandardizeLineBreaks(String contents) {
+ return contents.replaceAll("(\\r\\n)|(\\n)", "\n"); //$NON-NLS-1$ //$NON-NLS-2$
+ }
} \ No newline at end of file
diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/IDECloseMonitor.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/IDECloseMonitor.java
index 2e5521247c..92c7520dee 100644
--- a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/IDECloseMonitor.java
+++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/IDECloseMonitor.java
@@ -27,20 +27,20 @@ import org.eclipse.ui.IWorkbenchWindow;
* @author Ryan Morse
*/
public class IDECloseMonitor implements IWorkbenchListener {
- @Override
- public boolean preShutdown(IWorkbench workbench, boolean forced) {
- boolean close = true;
- if(!forced) {
- IWorkbenchWindow window = workbench.getActiveWorkbenchWindow();
+ @Override
+ public boolean preShutdown(IWorkbench workbench, boolean forced) {
+ boolean close = true;
+ if(!forced) {
+ IWorkbenchWindow window = workbench.getActiveWorkbenchWindow();
- if(ScriptConsole.anyRunning()) {
- String msg = MessageFormat.format(Localization.getString("IDECloseMonitor.StillRunning"),(Object[]) null); //$NON-NLS-1$
- close = MessageDialog.openQuestion(window.getShell(), "Closing...", msg); //$NON-NLS-1$
- }
- }
- return close;
- }
+ if(ScriptConsole.anyRunning()) {
+ String msg = MessageFormat.format(Localization.getString("IDECloseMonitor.StillRunning"),(Object[]) null); //$NON-NLS-1$
+ close = MessageDialog.openQuestion(window.getShell(), "Closing...", msg); //$NON-NLS-1$
+ }
+ }
+ return close;
+ }
- @Override
- public void postShutdown(IWorkbench workbench) {}
+ @Override
+ public void postShutdown(IWorkbench workbench) {}
}
diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/IDEPerspective.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/IDEPerspective.java
index 5a0fd7abcd..2fd6152339 100644
--- a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/IDEPerspective.java
+++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/IDEPerspective.java
@@ -29,40 +29,40 @@ import org.eclipse.ui.console.IConsoleConstants;
* @author Ryan Morse
*/
public class IDEPerspective implements IPerspectiveFactory {
- public static String ID = "org.eclipse.linuxtools.systemtap.ui.ide.IDEPerspective"; //$NON-NLS-1$
+ public static String ID = "org.eclipse.linuxtools.systemtap.ui.ide.IDEPerspective"; //$NON-NLS-1$
- @Override
- public void createInitialLayout(IPageLayout layout) {
- String editorArea = layout.getEditorArea();
- layout.setEditorAreaVisible(true);
+ @Override
+ public void createInitialLayout(IPageLayout layout) {
+ String editorArea = layout.getEditorArea();
+ layout.setEditorAreaVisible(true);
- IFolderLayout browsers = layout.createFolder("browsers", IPageLayout.LEFT, 0.25f, editorArea); //$NON-NLS-1$
- browsers.addPlaceholder(ProbeAliasBrowserView.ID + ":*"); //$NON-NLS-1$
+ IFolderLayout browsers = layout.createFolder("browsers", IPageLayout.LEFT, 0.25f, editorArea); //$NON-NLS-1$
+ browsers.addPlaceholder(ProbeAliasBrowserView.ID + ":*"); //$NON-NLS-1$
- browsers.addView(ProbeAliasBrowserView.ID);
- browsers.addView(FunctionBrowserView.ID);
- browsers.addView(KernelBrowserView.ID);
- browsers.addView(IPageLayout.ID_PROJECT_EXPLORER);
+ browsers.addView(ProbeAliasBrowserView.ID);
+ browsers.addView(FunctionBrowserView.ID);
+ browsers.addView(KernelBrowserView.ID);
+ browsers.addView(IPageLayout.ID_PROJECT_EXPLORER);
- layout.getViewLayout(ProbeAliasBrowserView.ID).setCloseable(false);
- layout.getViewLayout(FunctionBrowserView.ID).setCloseable(false);
- layout.getViewLayout(KernelBrowserView.ID).setCloseable(false);
+ layout.getViewLayout(ProbeAliasBrowserView.ID).setCloseable(false);
+ layout.getViewLayout(FunctionBrowserView.ID).setCloseable(false);
+ layout.getViewLayout(KernelBrowserView.ID).setCloseable(false);
- IFolderLayout output = layout.createFolder("output", IPageLayout.BOTTOM, 0.75f, editorArea); //$NON-NLS-1$
- output.addPlaceholder(ErrorView.ID + ":*"); //$NON-NLS-1$
- output.addView(ErrorView.ID);
- output.addView(IConsoleConstants.ID_CONSOLE_VIEW);
+ IFolderLayout output = layout.createFolder("output", IPageLayout.BOTTOM, 0.75f, editorArea); //$NON-NLS-1$
+ output.addPlaceholder(ErrorView.ID + ":*"); //$NON-NLS-1$
+ output.addView(ErrorView.ID);
+ output.addView(IConsoleConstants.ID_CONSOLE_VIEW);
- layout.getViewLayout(IConsoleConstants.ID_CONSOLE_VIEW).setCloseable(false);
- layout.getViewLayout(ErrorView.ID).setCloseable(false);
+ layout.getViewLayout(IConsoleConstants.ID_CONSOLE_VIEW).setCloseable(false);
+ layout.getViewLayout(ErrorView.ID).setCloseable(false);
- layout.addShowViewShortcut(ProbeAliasBrowserView.ID);
- layout.addShowViewShortcut(FunctionBrowserView.ID);
- layout.addShowViewShortcut(KernelBrowserView.ID);
- layout.addShowViewShortcut(ErrorView.ID);
- layout.addShowViewShortcut(IConsoleConstants.ID_CONSOLE_VIEW);
+ layout.addShowViewShortcut(ProbeAliasBrowserView.ID);
+ layout.addShowViewShortcut(FunctionBrowserView.ID);
+ layout.addShowViewShortcut(KernelBrowserView.ID);
+ layout.addShowViewShortcut(ErrorView.ID);
+ layout.addShowViewShortcut(IConsoleConstants.ID_CONSOLE_VIEW);
- layout.addPerspectiveShortcut(ID);
- }
+ layout.addPerspectiveShortcut(ID);
+ }
}
diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/IDEPlugin.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/IDEPlugin.java
index de8824469d..efcf6ebe28 100644
--- a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/IDEPlugin.java
+++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/IDEPlugin.java
@@ -36,90 +36,90 @@ import org.osgi.framework.BundleContext;
* @author Ryan Morse
*/
public class IDEPlugin extends AbstractUIPlugin {
- private IWorkbenchListener workbenchListener;
- private static IDEPlugin plugin;
- public static final String PLUGIN_ID = "org.eclipse.linuxtools.systemtap.ui.ide"; //$NON-NLS-1$
- public static final String SPACE = "space"; //$NON-NLS-1$
- public static final String TAB = "tab"; //$NON-NLS-1$
+ private IWorkbenchListener workbenchListener;
+ private static IDEPlugin plugin;
+ public static final String PLUGIN_ID = "org.eclipse.linuxtools.systemtap.ui.ide"; //$NON-NLS-1$
+ public static final String SPACE = "space"; //$NON-NLS-1$
+ public static final String TAB = "tab"; //$NON-NLS-1$
- public IDEPlugin() {
- plugin = this;
- }
+ public IDEPlugin() {
+ plugin = this;
+ }
- /**
- * Called by the Eclipse Workbench at plugin activation time. Starts the plugin lifecycle.
- */
- @Override
- public void start(BundleContext context) throws Exception {
- super.start(context);
+ /**
+ * Called by the Eclipse Workbench at plugin activation time. Starts the plugin lifecycle.
+ */
+ @Override
+ public void start(BundleContext context) throws Exception {
+ super.start(context);
- workbenchListener = new IDECloseMonitor();
- plugin.getWorkbench().addWorkbenchListener(workbenchListener);
- TapsetLibrary.init();
- }
+ workbenchListener = new IDECloseMonitor();
+ plugin.getWorkbench().addWorkbenchListener(workbenchListener);
+ TapsetLibrary.init();
+ }
- /**
- * Called by the Eclipse Workbench to deactivate the plugin.
- */
- @Override
- public void stop(BundleContext context) throws Exception {
- super.stop(context);
- TapsetLibrary.stop();
- ScriptConsole.stopAll();
- plugin.getWorkbench().removeWorkbenchListener(workbenchListener);
- plugin = null;
- }
+ /**
+ * Called by the Eclipse Workbench to deactivate the plugin.
+ */
+ @Override
+ public void stop(BundleContext context) throws Exception {
+ super.stop(context);
+ TapsetLibrary.stop();
+ ScriptConsole.stopAll();
+ plugin.getWorkbench().removeWorkbenchListener(workbenchListener);
+ plugin = null;
+ }
- /**
- * Returns this plugin's instance.
- */
- public static IDEPlugin getDefault() {
- return plugin;
- }
+ /**
+ * Returns this plugin's instance.
+ */
+ public static IDEPlugin getDefault() {
+ return plugin;
+ }
- /**
- * Returns an image descriptor for the image file at the given
- * plug-in relative path.
- *
- * @param path the path
- * @return the image descriptor
- */
- public static ImageDescriptor getImageDescriptor(String path) {
- return AbstractUIPlugin.imageDescriptorFromPlugin(PLUGIN_ID, path);
- }
+ /**
+ * Returns an image descriptor for the image file at the given
+ * plug-in relative path.
+ *
+ * @param path the path
+ * @return the image descriptor
+ */
+ public static ImageDescriptor getImageDescriptor(String path) {
+ return AbstractUIPlugin.imageDescriptorFromPlugin(PLUGIN_ID, path);
+ }
- /**
- * Create an uri to be used to connect to the remote machine
- */
- public URI createRemoteUri(String path) {
- IPreferenceStore p = ConsoleLogPlugin.getDefault().getPreferenceStore();
- String user = p.getString(ConsoleLogPreferenceConstants.SCP_USER);
- String host = p.getString(ConsoleLogPreferenceConstants.HOST_NAME);
- if (path == null)
- {
- path = ""; //$NON-NLS-1$
- }
- try {
- URI uri = new URI("ssh", user, host, -1, path, null, null); //$NON-NLS-1$
- return uri;
- } catch (URISyntaxException uri) {
- return null;
- }
- }
-
- public static void log(IStatus status) {
- ResourcesPlugin.getPlugin().getLog().log(status);
- }
+ /**
+ * Create an uri to be used to connect to the remote machine
+ */
+ public URI createRemoteUri(String path) {
+ IPreferenceStore p = ConsoleLogPlugin.getDefault().getPreferenceStore();
+ String user = p.getString(ConsoleLogPreferenceConstants.SCP_USER);
+ String host = p.getString(ConsoleLogPreferenceConstants.HOST_NAME);
+ if (path == null)
+ {
+ path = ""; //$NON-NLS-1$
+ }
+ try {
+ URI uri = new URI("ssh", user, host, -1, path, null, null); //$NON-NLS-1$
+ return uri;
+ } catch (URISyntaxException uri) {
+ return null;
+ }
+ }
- public static void log(Throwable e) {
- if (e instanceof InvocationTargetException)
- e = ((InvocationTargetException) e).getTargetException();
- IStatus status = null;
- if (e instanceof CoreException)
- status = ((CoreException) e).getStatus();
- else
- status = new Status(IStatus.ERROR, PLUGIN_ID, IStatus.OK, e.getMessage(), e);
- log(status);
- }
+ public static void log(IStatus status) {
+ ResourcesPlugin.getPlugin().getLog().log(status);
+ }
+
+ public static void log(Throwable e) {
+ if (e instanceof InvocationTargetException)
+ e = ((InvocationTargetException) e).getTargetException();
+ IStatus status = null;
+ if (e instanceof CoreException)
+ status = ((CoreException) e).getStatus();
+ else
+ status = new Status(IStatus.ERROR, PLUGIN_ID, IStatus.OK, e.getMessage(), e);
+ log(status);
+ }
}
diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/IDESessionSettings.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/IDESessionSettings.java
index 6c790f19b2..7c71890c83 100644
--- a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/IDESessionSettings.java
+++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/IDESessionSettings.java
@@ -34,148 +34,148 @@ import org.eclipse.ui.dialogs.ListDialog;
* @author Ryan Morse
*/
public class IDESessionSettings {
- public static String tapsetLocation = ""; //$NON-NLS-1$
-
- /**
- * Use {@link IDESessionSettings#setActiveSTPEditor(STPEditor)} and
- * {@link IDESessionSettings#getActiveSTPEditor()}
- */
- private static STPEditor activeSTPEditor = null;
-
- /**
- * Returns the most recent active {@link STPEditor} script editor if one was
- * set. If one was not set and there is only one {@link STPEditor} script editor
- * open then that one is returned. Otherwise returns null.
- * @return The most recent active {@link STPEditor}
- * @since 1.2
- */
- public static STPEditor getActiveSTPEditor() {
- if (activeSTPEditor == null) {
- // If no active editor is et and there is only one
- // opened stap script editor, set it to be the active editor.
- IEditorReference[] editors = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().getEditorReferences();
- STPEditor stpEditor = null;
- for (IEditorReference editor: editors) {
- if (editor.getId().equals(STPEditor.ID)) {
- if (stpEditor == null) {
- stpEditor = (STPEditor) editor.getEditor(true);
- } else {
- return null;
- }
- }
- }
- activeSTPEditor = stpEditor;
- }
- return activeSTPEditor;
- }
-
- /**
- * Sets the current active editor.
- * @param editor the active editor.
- * @since 1.2
- */
- public static void setActiveSTPEditor(STPEditor editor) {
- activeSTPEditor = editor;
- }
-
- /**
- * Restore and return an STPEditor based on the user's choice.
- * @param checkCurrent Set to <code>true</code> if the currently active editor may be returned
- * if it is an {@link STPEditor}.
- * @return
- */
- public static STPEditor getOrAskForActiveSTPEditor(boolean checkCurrent) {
- STPEditor stpEditor;
- IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
- IWorkbenchPage page = window.getActivePage();
- if (checkCurrent) {
- IEditorPart editor = page.getActiveEditor();
- stpEditor = editor instanceof STPEditor ? (STPEditor) editor : askForSTPEditor(window);
- } else {
- stpEditor = askForSTPEditor(window);
- }
- if (stpEditor != null) {
- page.activate(stpEditor);
- }
- return stpEditor;
- }
-
- private static STPEditor askForSTPEditor(IWorkbenchWindow window) {
- final List<STPEditor> allEditors = new LinkedList<>();
- for (IEditorReference editor : window.getActivePage().getEditorReferences()) {
- if (editor.getId().equals(STPEditor.ID)) {
- allEditors.add((STPEditor) editor.getEditor(true));
- }
- }
-
- switch (allEditors.size()) {
- // If only one file is found, open it. Give user the option to open another file.
- case 1:
- MessageDialog messageDialog = new MessageDialog(window.getShell(),
- Localization.getString("GetEditorAction.DialogTitle"), null, //$NON-NLS-1$
- MessageFormat.format(Localization.getString("GetEditorAction.AskBeforeOpenMessage"), //$NON-NLS-1$
- allEditors.get(0).getEditorInput().getName() ),
- MessageDialog.QUESTION,
- new String[]{Localization.getString("GetEditorAction.AskBeforeOpenCancel"), //$NON-NLS-1$
- Localization.getString("GetEditorAction.AskBeforeOpenAnother"), //$NON-NLS-1$
- Localization.getString("GetEditorAction.AskBeforeOpenYes")}, 2); //$NON-NLS-1$
-
- switch (messageDialog.open()) {
- case 2:
- return allEditors.get(0);
-
- case 1:
- return openNewFile(window);
-
- default:
- return null;
- }
-
- // If no files found, prompt user to open a new file
- case 0:
- return openNewFile(window);
-
- // If multiple files found, prompt user to select one of them
- default:
- return openNewFileFromMultiple(window, allEditors);
- }
- }
-
- private static STPEditor openNewFileFromMultiple(IWorkbenchWindow window, final List<STPEditor> allEditors) {
- ListDialog listDialog = new ListDialog(window.getShell());
- listDialog.setTitle(Localization.getString("GetEditorAction.DialogTitle")); //$NON-NLS-1$
- listDialog.setContentProvider(new ArrayContentProvider());
-
- listDialog.setLabelProvider(new LabelProvider() {
- @Override
- public String getText(Object element) {
- int i = (Integer) element;
- return i != -1 ? allEditors.get(i).getEditorInput().getName()
- : Localization.getString("GetEditorAction.OtherFile"); //$NON-NLS-1$
- }
- });
-
- Integer[] editorIndexes = new Integer[allEditors.size() + 1];
- for (int i = 0; i < editorIndexes.length - 1; i++) {
- editorIndexes[i] = i;
- }
- editorIndexes[editorIndexes.length - 1] = -1;
- listDialog.setInput(editorIndexes);
- listDialog.setMessage(Localization.getString("GetEditorAction.SelectEditor")); //$NON-NLS-1$
- if (listDialog.open() == Window.OK) {
- int result = (Integer) listDialog.getResult()[0];
- return result != -1 ? allEditors.get(result) : openNewFile(window);
- }
- // Abort if user cancels
- return null;
- }
-
- private static STPEditor openNewFile(IWorkbenchWindow window) {
- NewFileAction action = new NewFileAction();
- action.run();
- if (action.isSuccessful()) {
- return (STPEditor) window.getActivePage().getActiveEditor();
- }
- return null;
- }
+ public static String tapsetLocation = ""; //$NON-NLS-1$
+
+ /**
+ * Use {@link IDESessionSettings#setActiveSTPEditor(STPEditor)} and
+ * {@link IDESessionSettings#getActiveSTPEditor()}
+ */
+ private static STPEditor activeSTPEditor = null;
+
+ /**
+ * Returns the most recent active {@link STPEditor} script editor if one was
+ * set. If one was not set and there is only one {@link STPEditor} script editor
+ * open then that one is returned. Otherwise returns null.
+ * @return The most recent active {@link STPEditor}
+ * @since 1.2
+ */
+ public static STPEditor getActiveSTPEditor() {
+ if (activeSTPEditor == null) {
+ // If no active editor is et and there is only one
+ // opened stap script editor, set it to be the active editor.
+ IEditorReference[] editors = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().getEditorReferences();
+ STPEditor stpEditor = null;
+ for (IEditorReference editor: editors) {
+ if (editor.getId().equals(STPEditor.ID)) {
+ if (stpEditor == null) {
+ stpEditor = (STPEditor) editor.getEditor(true);
+ } else {
+ return null;
+ }
+ }
+ }
+ activeSTPEditor = stpEditor;
+ }
+ return activeSTPEditor;
+ }
+
+ /**
+ * Sets the current active editor.
+ * @param editor the active editor.
+ * @since 1.2
+ */
+ public static void setActiveSTPEditor(STPEditor editor) {
+ activeSTPEditor = editor;
+ }
+
+ /**
+ * Restore and return an STPEditor based on the user's choice.
+ * @param checkCurrent Set to <code>true</code> if the currently active editor may be returned
+ * if it is an {@link STPEditor}.
+ * @return
+ */
+ public static STPEditor getOrAskForActiveSTPEditor(boolean checkCurrent) {
+ STPEditor stpEditor;
+ IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
+ IWorkbenchPage page = window.getActivePage();
+ if (checkCurrent) {
+ IEditorPart editor = page.getActiveEditor();
+ stpEditor = editor instanceof STPEditor ? (STPEditor) editor : askForSTPEditor(window);
+ } else {
+ stpEditor = askForSTPEditor(window);
+ }
+ if (stpEditor != null) {
+ page.activate(stpEditor);
+ }
+ return stpEditor;
+ }
+
+ private static STPEditor askForSTPEditor(IWorkbenchWindow window) {
+ final List<STPEditor> allEditors = new LinkedList<>();
+ for (IEditorReference editor : window.getActivePage().getEditorReferences()) {
+ if (editor.getId().equals(STPEditor.ID)) {
+ allEditors.add((STPEditor) editor.getEditor(true));
+ }
+ }
+
+ switch (allEditors.size()) {
+ // If only one file is found, open it. Give user the option to open another file.
+ case 1:
+ MessageDialog messageDialog = new MessageDialog(window.getShell(),
+ Localization.getString("GetEditorAction.DialogTitle"), null, //$NON-NLS-1$
+ MessageFormat.format(Localization.getString("GetEditorAction.AskBeforeOpenMessage"), //$NON-NLS-1$
+ allEditors.get(0).getEditorInput().getName() ),
+ MessageDialog.QUESTION,
+ new String[]{Localization.getString("GetEditorAction.AskBeforeOpenCancel"), //$NON-NLS-1$
+ Localization.getString("GetEditorAction.AskBeforeOpenAnother"), //$NON-NLS-1$
+ Localization.getString("GetEditorAction.AskBeforeOpenYes")}, 2); //$NON-NLS-1$
+
+ switch (messageDialog.open()) {
+ case 2:
+ return allEditors.get(0);
+
+ case 1:
+ return openNewFile(window);
+
+ default:
+ return null;
+ }
+
+ // If no files found, prompt user to open a new file
+ case 0:
+ return openNewFile(window);
+
+ // If multiple files found, prompt user to select one of them
+ default:
+ return openNewFileFromMultiple(window, allEditors);
+ }
+ }
+
+ private static STPEditor openNewFileFromMultiple(IWorkbenchWindow window, final List<STPEditor> allEditors) {
+ ListDialog listDialog = new ListDialog(window.getShell());
+ listDialog.setTitle(Localization.getString("GetEditorAction.DialogTitle")); //$NON-NLS-1$
+ listDialog.setContentProvider(new ArrayContentProvider());
+
+ listDialog.setLabelProvider(new LabelProvider() {
+ @Override
+ public String getText(Object element) {
+ int i = (Integer) element;
+ return i != -1 ? allEditors.get(i).getEditorInput().getName()
+ : Localization.getString("GetEditorAction.OtherFile"); //$NON-NLS-1$
+ }
+ });
+
+ Integer[] editorIndexes = new Integer[allEditors.size() + 1];
+ for (int i = 0; i < editorIndexes.length - 1; i++) {
+ editorIndexes[i] = i;
+ }
+ editorIndexes[editorIndexes.length - 1] = -1;
+ listDialog.setInput(editorIndexes);
+ listDialog.setMessage(Localization.getString("GetEditorAction.SelectEditor")); //$NON-NLS-1$
+ if (listDialog.open() == Window.OK) {
+ int result = (Integer) listDialog.getResult()[0];
+ return result != -1 ? allEditors.get(result) : openNewFile(window);
+ }
+ // Abort if user cancels
+ return null;
+ }
+
+ private static STPEditor openNewFile(IWorkbenchWindow window) {
+ NewFileAction action = new NewFileAction();
+ action.run();
+ if (action.isSuccessful()) {
+ return (STPEditor) window.getActivePage().getActiveEditor();
+ }
+ return null;
+ }
}
diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/Localization.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/Localization.java
index b8194956e5..581386db5a 100644
--- a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/Localization.java
+++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/Localization.java
@@ -15,19 +15,19 @@ import java.util.MissingResourceException;
import java.util.ResourceBundle;
public class Localization {
- private static final String BUNDLE_NAME = "org.eclipse.linuxtools.internal.systemtap.ui.ide.localization"; //$NON-NLS-1$
+ private static final String BUNDLE_NAME = "org.eclipse.linuxtools.internal.systemtap.ui.ide.localization"; //$NON-NLS-1$
- private static final ResourceBundle RESOURCE_BUNDLE = ResourceBundle
- .getBundle(BUNDLE_NAME);
+ private static final ResourceBundle RESOURCE_BUNDLE = ResourceBundle
+ .getBundle(BUNDLE_NAME);
- private Localization() {
- }
+ private Localization() {
+ }
- public static String getString(String key) {
- try {
- return RESOURCE_BUNDLE.getString(key);
- } catch (MissingResourceException e) {
- return '!' + key + '!';
- }
- }
+ public static String getString(String key) {
+ try {
+ return RESOURCE_BUNDLE.getString(key);
+ } catch (MissingResourceException e) {
+ return '!' + key + '!';
+ }
+ }
}
diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/StringOutputStream.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/StringOutputStream.java
index 30b629105b..4e3139f9a3 100644
--- a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/StringOutputStream.java
+++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/StringOutputStream.java
@@ -14,15 +14,15 @@ package org.eclipse.linuxtools.internal.systemtap.ui.ide;
import java.io.OutputStream;
public class StringOutputStream extends OutputStream {
- private StringBuffer str = new StringBuffer();
+ private StringBuffer str = new StringBuffer();
- @Override
- public String toString() {
- return str.toString();
- }
+ @Override
+ public String toString() {
+ return str.toString();
+ }
- @Override
- public void write(int b) {
- str.append((char)b);
- }
+ @Override
+ public void write(int b) {
+ str.append((char)b);
+ }
}
diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/actions/BrowserViewAction.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/actions/BrowserViewAction.java
index aba71c915c..601164969b 100644
--- a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/actions/BrowserViewAction.java
+++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/actions/BrowserViewAction.java
@@ -22,56 +22,56 @@ import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.IWorkbenchWindow;
public abstract class BrowserViewAction extends Action implements ISelectionListener, IDoubleClickListener {
- private final IWorkbenchWindow window;
- private final BrowserView viewer;
- private IStructuredSelection selection;
- private TreeExpandCollapseAction expandAction;
+ private final IWorkbenchWindow window;
+ private final BrowserView viewer;
+ private IStructuredSelection selection;
+ private TreeExpandCollapseAction expandAction;
- /**
- * The Default Constructor. Takes the <code>IWorkbenchWindow</code> that it effects
- * as well as the <code>BrowserView</code> that will fire this action.
- * @param window window effected by this event
- * @param browser browser that fires this action
- */
- public BrowserViewAction(IWorkbenchWindow window, BrowserView browser) {
- this.window = window;
- window.getSelectionService().addSelectionListener(this);
- viewer = browser;
- expandAction = new TreeExpandCollapseAction(viewer);
- }
+ /**
+ * The Default Constructor. Takes the <code>IWorkbenchWindow</code> that it effects
+ * as well as the <code>BrowserView</code> that will fire this action.
+ * @param window window effected by this event
+ * @param browser browser that fires this action
+ */
+ public BrowserViewAction(IWorkbenchWindow window, BrowserView browser) {
+ this.window = window;
+ window.getSelectionService().addSelectionListener(this);
+ viewer = browser;
+ expandAction = new TreeExpandCollapseAction(viewer);
+ }
- public void dispose() {
- window.getSelectionService().removeSelectionListener(this);
- selection = null;
- expandAction.dispose();
- expandAction = null;
- }
+ public void dispose() {
+ window.getSelectionService().removeSelectionListener(this);
+ selection = null;
+ expandAction.dispose();
+ expandAction = null;
+ }
- /**
- * Updates <code>selection</code> with the current selection whenever the user changes
- * the current selection.
- */
- @Override
- public void selectionChanged(IWorkbenchPart part, ISelection incoming) {
- if (incoming instanceof IStructuredSelection) {
- selection = (IStructuredSelection) incoming;
- setEnabled(selection.size() == 1);
- } else {
- // Other selections, for example containing text or of other kinds.
- setEnabled(false);
- }
- }
+ /**
+ * Updates <code>selection</code> with the current selection whenever the user changes
+ * the current selection.
+ */
+ @Override
+ public void selectionChanged(IWorkbenchPart part, ISelection incoming) {
+ if (incoming instanceof IStructuredSelection) {
+ selection = (IStructuredSelection) incoming;
+ setEnabled(selection.size() == 1);
+ } else {
+ // Other selections, for example containing text or of other kinds.
+ setEnabled(false);
+ }
+ }
- @Override
- public void doubleClick(DoubleClickEvent event) {
- run();
- }
+ @Override
+ public void doubleClick(DoubleClickEvent event) {
+ run();
+ }
- protected Object getSelectedElement() {
- return ((IStructuredSelection) viewer.getViewer().getSelection()).getFirstElement();
- }
+ protected Object getSelectedElement() {
+ return ((IStructuredSelection) viewer.getViewer().getSelection()).getFirstElement();
+ }
- protected void runExpandAction() {
- expandAction.run();
- }
+ protected void runExpandAction() {
+ expandAction.run();
+ }
} \ No newline at end of file
diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/actions/ExportDataSetHandler.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/actions/ExportDataSetHandler.java
index c36a4ab0fa..2e1e2fbf60 100644
--- a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/actions/ExportDataSetHandler.java
+++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/actions/ExportDataSetHandler.java
@@ -26,32 +26,32 @@ import org.eclipse.ui.PlatformUI;
*/
public class ExportDataSetHandler extends AbstractHandler {
- private GraphSelectorEditor getActiveGraphEditor() {
- IEditorPart editor = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().getActiveEditor();
- return editor instanceof GraphSelectorEditor ? (GraphSelectorEditor) editor : null;
- }
-
- @Override
- public Object execute(ExecutionEvent event) {
- GraphSelectorEditor editor = getActiveGraphEditor();
- if (editor == null) {
- return null;
- }
- FileDialog dialog = new FileDialog(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(), SWT.SAVE);
- dialog.setOverwrite(true);
- dialog.setFilterExtensions(new String[]{Messages.DataSetFileExtension});
- dialog.setText(MessageFormat.format(Messages.ExportDataSetAction_DialogTitle, editor.getActiveTitle()));
- dialog.setFileName(editor.getActiveTitle().replaceAll(" ", "")); //$NON-NLS-1$ //$NON-NLS-2$
- String path = dialog.open();
- if (path != null) {
- editor.getActiveDisplaySet().getDataSet().writeToFile(new File(path));
- }
- return null;
- }
-
- @Override
- public boolean isEnabled() {
- return getActiveGraphEditor() != null;
- }
+ private GraphSelectorEditor getActiveGraphEditor() {
+ IEditorPart editor = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().getActiveEditor();
+ return editor instanceof GraphSelectorEditor ? (GraphSelectorEditor) editor : null;
+ }
+
+ @Override
+ public Object execute(ExecutionEvent event) {
+ GraphSelectorEditor editor = getActiveGraphEditor();
+ if (editor == null) {
+ return null;
+ }
+ FileDialog dialog = new FileDialog(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(), SWT.SAVE);
+ dialog.setOverwrite(true);
+ dialog.setFilterExtensions(new String[]{Messages.DataSetFileExtension});
+ dialog.setText(MessageFormat.format(Messages.ExportDataSetAction_DialogTitle, editor.getActiveTitle()));
+ dialog.setFileName(editor.getActiveTitle().replaceAll(" ", "")); //$NON-NLS-1$ //$NON-NLS-2$
+ String path = dialog.open();
+ if (path != null) {
+ editor.getActiveDisplaySet().getDataSet().writeToFile(new File(path));
+ }
+ return null;
+ }
+
+ @Override
+ public boolean isEnabled() {
+ return getActiveGraphEditor() != null;
+ }
}
diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/actions/FunctionBrowserAction.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/actions/FunctionBrowserAction.java
index ceeec32046..8f09de3340 100644
--- a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/actions/FunctionBrowserAction.java
+++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/actions/FunctionBrowserAction.java
@@ -34,38 +34,38 @@ import org.eclipse.ui.IWorkbenchWindow;
* @see org.eclipse.linuxtools.internal.systemtap.ui.ide.actions.TreeExpandCollapseAction
*/
public class FunctionBrowserAction extends BrowserViewAction {
- private static final String ID = "org.eclipse.linuxtools.systemtap.ui.ide.FunctionAction"; //$NON-NLS-1$
+ private static final String ID = "org.eclipse.linuxtools.systemtap.ui.ide.FunctionAction"; //$NON-NLS-1$
- public FunctionBrowserAction(IWorkbenchWindow window, FunctionBrowserView browser) {
- super(window, browser);
- setId(ID);
- setActionDefinitionId(ID);
- setText(Localization.getString("FunctionBrowserAction.Insert")); //$NON-NLS-1$
- setToolTipText(Localization
- .getString("FunctionBrowserAction.InsertFunction")); //$NON-NLS-1$
- }
+ public FunctionBrowserAction(IWorkbenchWindow window, FunctionBrowserView browser) {
+ super(window, browser);
+ setId(ID);
+ setActionDefinitionId(ID);
+ setText(Localization.getString("FunctionBrowserAction.Insert")); //$NON-NLS-1$
+ setToolTipText(Localization
+ .getString("FunctionBrowserAction.InsertFunction")); //$NON-NLS-1$
+ }
- /**
- * The main action code, invoked when this action is fired. This code checks the current
- * selection's clickable property, and either invokes the <code>TreeExpandCollapseAction</code> if
- * the selection is not clickable (i.e. the selection is not a function, but a category of functions),
- * or it inserts text for a function call to the selected function in the active STPEditor
- * (creating a new editor if there is not one currently open).
- */
- @Override
- public void run() {
- Object o = getSelectedElement();
- if (o instanceof TreeNode) {
- TreeNode t = (TreeNode) o;
- if (t.isClickable()) {
- STPEditor stpeditor = IDESessionSettings.getOrAskForActiveSTPEditor(true);
- if (stpeditor != null) {
- stpeditor.insertTextAtCurrent(t.toString() + "\n"); //$NON-NLS-1$
- }
- } else {
- runExpandAction();
- }
- }
- }
+ /**
+ * The main action code, invoked when this action is fired. This code checks the current
+ * selection's clickable property, and either invokes the <code>TreeExpandCollapseAction</code> if
+ * the selection is not clickable (i.e. the selection is not a function, but a category of functions),
+ * or it inserts text for a function call to the selected function in the active STPEditor
+ * (creating a new editor if there is not one currently open).
+ */
+ @Override
+ public void run() {
+ Object o = getSelectedElement();
+ if (o instanceof TreeNode) {
+ TreeNode t = (TreeNode) o;
+ if (t.isClickable()) {
+ STPEditor stpeditor = IDESessionSettings.getOrAskForActiveSTPEditor(true);
+ if (stpeditor != null) {
+ stpeditor.insertTextAtCurrent(t.toString() + "\n"); //$NON-NLS-1$
+ }
+ } else {
+ runExpandAction();
+ }
+ }
+ }
}
diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/actions/ImportDataSetHandler.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/actions/ImportDataSetHandler.java
index 13b549f6c8..99f974d8b2 100644
--- a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/actions/ImportDataSetHandler.java
+++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/actions/ImportDataSetHandler.java
@@ -42,52 +42,52 @@ import org.eclipse.ui.WorkbenchException;
*/
public class ImportDataSetHandler extends AbstractHandler {
- @Override
- public Object execute(ExecutionEvent event) {
- FileDialog dialog = new FileDialog(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(), SWT.OPEN);
- dialog.setFilterExtensions(new String[]{Messages.DataSetFileExtension});
- dialog.setText(Messages.ImportDataSetAction_DialogTitle);
- String path = dialog.open();
- if (path == null) {
- return null;
- }
+ @Override
+ public Object execute(ExecutionEvent event) {
+ FileDialog dialog = new FileDialog(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(), SWT.OPEN);
+ dialog.setFilterExtensions(new String[]{Messages.DataSetFileExtension});
+ dialog.setText(Messages.ImportDataSetAction_DialogTitle);
+ String path = dialog.open();
+ if (path == null) {
+ return null;
+ }
- IFilteredDataSet dataset = null;
- File file = new File(path);
- try (InputStreamReader fr = new InputStreamReader(new FileInputStream(file), Charset.defaultCharset());
- BufferedReader br = new BufferedReader(fr)) {
- String id = br.readLine();
- String[] titles = br.readLine().split(", "); //$NON-NLS-1$
+ IFilteredDataSet dataset = null;
+ File file = new File(path);
+ try (InputStreamReader fr = new InputStreamReader(new FileInputStream(file), Charset.defaultCharset());
+ BufferedReader br = new BufferedReader(fr)) {
+ String id = br.readLine();
+ String[] titles = br.readLine().split(", "); //$NON-NLS-1$
- if (id == null && titles == null) {
- throw new IOException();
- } else if (id.equals(RowDataSet.ID)) {
- dataset = new FilteredRowDataSet(titles);
- } else if (id.equals(TableDataSet.ID)) {
- dataset = new FilteredTableDataSet(titles);
- } else {
- throw new IOException();
- }
- dataset.readFromFile(file);
+ if (id == null && titles == null) {
+ throw new IOException();
+ } else if (id.equals(RowDataSet.ID)) {
+ dataset = new FilteredRowDataSet(titles);
+ } else if (id.equals(TableDataSet.ID)) {
+ dataset = new FilteredTableDataSet(titles);
+ } else {
+ throw new IOException();
+ }
+ dataset.readFromFile(file);
- String title = path.substring(path.lastIndexOf('/')+1);
- IWorkbenchPage p = PlatformUI.getWorkbench().showPerspective(IDEPerspective.ID, PlatformUI.getWorkbench().getActiveWorkbenchWindow());
- GraphSelectorEditor ivp = (GraphSelectorEditor)p.openEditor(new GraphSelectorEditorInput(title), GraphSelectorEditor.ID);
- ivp.createScriptSets(path, Arrays.asList(title), Arrays.asList(dataset));
- } catch (FileNotFoundException fnfe) {
- ExceptionErrorDialog.openError(Messages.ImportDataSetAction_FileNotFound, fnfe);
- } catch (IOException ioe) {
- ExceptionErrorDialog.openError(Messages.ImportDataSetAction_FileInvalid, ioe);
- } catch (WorkbenchException we) {
- ExceptionErrorDialog.openError(Messages.RunScriptChartAction_couldNotSwitchToGraphicPerspective, we);
- }
+ String title = path.substring(path.lastIndexOf('/')+1);
+ IWorkbenchPage p = PlatformUI.getWorkbench().showPerspective(IDEPerspective.ID, PlatformUI.getWorkbench().getActiveWorkbenchWindow());
+ GraphSelectorEditor ivp = (GraphSelectorEditor)p.openEditor(new GraphSelectorEditorInput(title), GraphSelectorEditor.ID);
+ ivp.createScriptSets(path, Arrays.asList(title), Arrays.asList(dataset));
+ } catch (FileNotFoundException fnfe) {
+ ExceptionErrorDialog.openError(Messages.ImportDataSetAction_FileNotFound, fnfe);
+ } catch (IOException ioe) {
+ ExceptionErrorDialog.openError(Messages.ImportDataSetAction_FileInvalid, ioe);
+ } catch (WorkbenchException we) {
+ ExceptionErrorDialog.openError(Messages.RunScriptChartAction_couldNotSwitchToGraphicPerspective, we);
+ }
- return null;
- }
+ return null;
+ }
- @Override
- public boolean isEnabled() {
- return PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().
- getPerspective().getId().equals(IDEPerspective.ID);
- }
+ @Override
+ public boolean isEnabled() {
+ return PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().
+ getPerspective().getId().equals(IDEPerspective.ID);
+ }
}
diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/actions/ImportTapsetHandler.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/actions/ImportTapsetHandler.java
index 731c564e66..d26794f053 100644
--- a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/actions/ImportTapsetHandler.java
+++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/actions/ImportTapsetHandler.java
@@ -19,16 +19,16 @@ import org.eclipse.ui.handlers.HandlerUtil;
public class ImportTapsetHandler extends AbstractHandler {
- @Override
- public Object execute(ExecutionEvent event) {
- String pageID = "org.eclipse.linuxtools.systemtap.prefs.ide.tapsets"; //$NON-NLS-1$
- PreferencesUtil.createPreferenceDialogOn(HandlerUtil.getActiveShell(event), pageID, new String[]{pageID}, null).open();
- return null;
- }
+ @Override
+ public Object execute(ExecutionEvent event) {
+ String pageID = "org.eclipse.linuxtools.systemtap.prefs.ide.tapsets"; //$NON-NLS-1$
+ PreferencesUtil.createPreferenceDialogOn(HandlerUtil.getActiveShell(event), pageID, new String[]{pageID}, null).open();
+ return null;
+ }
- @Override
- public boolean isEnabled() {
- return true;
- }
+ @Override
+ public boolean isEnabled() {
+ return true;
+ }
}
diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/actions/IndentHandler.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/actions/IndentHandler.java
index 845dd84f76..449ee316c4 100644
--- a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/actions/IndentHandler.java
+++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/actions/IndentHandler.java
@@ -51,459 +51,459 @@ import org.eclipse.ui.texteditor.ITextEditor;
* complete AST must be present, the indentation is computed using heuristics.
* The algorithm used is fast for single lines, but does not store any
* information and therefore not so efficient for large line ranges.
- *
+ *
* @see org.eclipse.linuxtools.internal.systemtap.ui.ide.editors.stp.STPHeuristicScanner
* @see org.eclipse.linuxtools.internal.systemtap.ui.ide.editors.stp.STPIndenter
*/
public class IndentHandler extends AbstractHandler {
- /** The caret offset after an indent operation. */
- private int fCaretOffset;
-
- private class STPRunnable implements Runnable {
- private ITextEditor editor;
-
- public STPRunnable(ITextEditor editor) {
- this.editor = editor;
- }
-
- public ITextEditor getTextEditor() {
- return editor;
- }
-
- @Override
- public void run() {
- }
- }
-
- /**
- * Whether this is the action invoked by TAB. When <code>true</code>,
- * indentation behaves differently to accommodate normal TAB operation.
- */
- private final boolean fIsTabAction = false;
-
- @Override
- public Object execute(ExecutionEvent event) { // Update has been called by
- // the framework
- if (!isEnabled())
- return null;
-
- ITextEditor editor = (ITextEditor) HandlerUtil.getActiveEditor(event);
- if (editor == null || !editor.isEditable()) {
- return null;
- }
-
- ITextSelection selection = getSelection(editor);
- final IDocument document = getDocument(editor);
-
- if (document != null) {
- final int offset = selection.getOffset();
- final int length = selection.getLength();
- final Position end = new Position(offset + length);
- final int firstLine, nLines;
- fCaretOffset = -1;
-
- try {
- firstLine = document.getLineOfOffset(offset);
- // check for marginal (zero-length) lines
- int minusOne = length == 0 ? 0 : 1;
- nLines = document.getLineOfOffset(offset + length - minusOne)
- - firstLine + 1;
- document.addPosition(end);
- } catch (BadLocationException e) {
- // will only happen on concurrent modification
- IDEPlugin.log(new Status(IStatus.ERROR,
- IDEPlugin.PLUGIN_ID, IStatus.OK, "", e)); //$NON-NLS-1$
- return null;
- }
-
- Runnable runnable = new STPRunnable(editor) {
- @Override
- public void run() {
- IRewriteTarget target = (IRewriteTarget) getTextEditor()
- .getAdapter(IRewriteTarget.class);
- if (target != null) {
- target.beginCompoundChange();
- }
-
- try {
- STPHeuristicScanner scanner = new STPHeuristicScanner(
- document);
- STPIndenter indenter = new STPIndenter(document,
- scanner, getProject(getTextEditor()));
- final boolean multiLine = nLines > 1;
- boolean hasChanged = false;
- for (int i = 0; i < nLines; i++) {
+ /** The caret offset after an indent operation. */
+ private int fCaretOffset;
+
+ private class STPRunnable implements Runnable {
+ private ITextEditor editor;
+
+ public STPRunnable(ITextEditor editor) {
+ this.editor = editor;
+ }
+
+ public ITextEditor getTextEditor() {
+ return editor;
+ }
+
+ @Override
+ public void run() {
+ }
+ }
+
+ /**
+ * Whether this is the action invoked by TAB. When <code>true</code>,
+ * indentation behaves differently to accommodate normal TAB operation.
+ */
+ private final boolean fIsTabAction = false;
+
+ @Override
+ public Object execute(ExecutionEvent event) { // Update has been called by
+ // the framework
+ if (!isEnabled())
+ return null;
+
+ ITextEditor editor = (ITextEditor) HandlerUtil.getActiveEditor(event);
+ if (editor == null || !editor.isEditable()) {
+ return null;
+ }
+
+ ITextSelection selection = getSelection(editor);
+ final IDocument document = getDocument(editor);
+
+ if (document != null) {
+ final int offset = selection.getOffset();
+ final int length = selection.getLength();
+ final Position end = new Position(offset + length);
+ final int firstLine, nLines;
+ fCaretOffset = -1;
+
+ try {
+ firstLine = document.getLineOfOffset(offset);
+ // check for marginal (zero-length) lines
+ int minusOne = length == 0 ? 0 : 1;
+ nLines = document.getLineOfOffset(offset + length - minusOne)
+ - firstLine + 1;
+ document.addPosition(end);
+ } catch (BadLocationException e) {
+ // will only happen on concurrent modification
+ IDEPlugin.log(new Status(IStatus.ERROR,
+ IDEPlugin.PLUGIN_ID, IStatus.OK, "", e)); //$NON-NLS-1$
+ return null;
+ }
+
+ Runnable runnable = new STPRunnable(editor) {
+ @Override
+ public void run() {
+ IRewriteTarget target = (IRewriteTarget) getTextEditor()
+ .getAdapter(IRewriteTarget.class);
+ if (target != null) {
+ target.beginCompoundChange();
+ }
+
+ try {
+ STPHeuristicScanner scanner = new STPHeuristicScanner(
+ document);
+ STPIndenter indenter = new STPIndenter(document,
+ scanner, getProject(getTextEditor()));
+ final boolean multiLine = nLines > 1;
+ boolean hasChanged = false;
+ for (int i = 0; i < nLines; i++) {
hasChanged |= indentLine(document, firstLine + i,
offset, indenter, scanner, multiLine);
- }
-
- // update caret position: move to new position when
- // indenting just one line
- // keep selection when indenting multiple
- int newOffset, newLength;
- if (!fIsTabAction && multiLine) {
- newOffset = offset;
- newLength = end.getOffset() - offset;
- } else {
- newOffset = fCaretOffset;
- newLength = 0;
- }
-
- // always reset the selection if anything was replaced
- // but not when we had a single line non-tab invocation
- if (newOffset != -1
- && (hasChanged || newOffset != offset || newLength != length))
- selectAndReveal(getTextEditor(), newOffset,
- newLength);
-
- } catch (BadLocationException e) {
- // will only happen on concurrent modification
- IDEPlugin.log(new Status(IStatus.ERROR, IDEPlugin
- .PLUGIN_ID, IStatus.OK,
- "ConcurrentModification in IndentAction", e)); //$NON-NLS-1$
- } finally {
- document.removePosition(end);
- if (target != null) {
- target.endCompoundChange();
- }
- }
- }
- };
-
- if (nLines > 50) {
- Display display = editor.getEditorSite().getWorkbenchWindow()
- .getShell().getDisplay();
- BusyIndicator.showWhile(display, runnable);
- } else {
- runnable.run();
- }
- }
-
- return null;
- }
-
- /**
- * Selects the given range on the editor.
- *
- * @param newOffset
- * the selection offset
- * @param newLength
- * the selection range
- */
- private void selectAndReveal(ITextEditor editor, int newOffset,
- int newLength) {
- Assert.isTrue(newOffset >= 0);
- Assert.isTrue(newLength >= 0);
- if (editor instanceof STPEditor) {
- ISourceViewer viewer = ((STPEditor) editor).getMySourceViewer();
- if (viewer != null) {
- viewer.setSelectedRange(newOffset, newLength);
- }
- } else {
- // this is too intrusive, but will never get called anyway
- editor.selectAndReveal(newOffset, newLength);
- }
- }
-
- /**
- * Indents a single line using the heuristic scanner. Multiline comments are
- * indented as specified by the <code>CCommentAutoIndentStrategy</code>.
- *
- * @param document
- * the document
- * @param line
- * the line to be indented
- * @param caret
- * the caret position
- * @param indenter
- * the indenter
- * @param scanner
- * the heuristic scanner
- * @param multiLine
- * <code>true</code> if more than one line is being indented
- * @return <code>true</code> if <code>document</code> was modified,
- * <code>false</code> otherwise
- * @throws BadLocationException
- * if the document got changed concurrently
- */
- private boolean indentLine(IDocument document,
- int line, int caret, STPIndenter indenter,
- STPHeuristicScanner scanner, boolean multiLine)
- throws BadLocationException {
- IRegion currentLine = document.getLineInformation(line);
- int offset = currentLine.getOffset();
- int wsStart = offset; // where we start searching for non-WS; after the
- // "//" in single line comments
-
- String indent = null;
- if (offset < document.getLength()) {
- ITypedRegion partition = TextUtilities.getPartition(document,
- STPPartitionScanner.STP_PARTITIONING, offset, true);
- ITypedRegion startingPartition = TextUtilities.getPartition(
- document, STPPartitionScanner.STP_PARTITIONING, offset,
- false);
- String type = partition.getType();
- if (type.equals(STPPartitionScanner.STP_MULTILINE_COMMENT)) {
- indent = computeCommentIndent(document, line, scanner,
- startingPartition);
- } else if (startingPartition.getType().equals(
- STPPartitionScanner.STP_CONDITIONAL)) {
- indent = computePreprocessorIndent(document, line,
- startingPartition);
- } else if (startingPartition.getType().equals(
- STPPartitionScanner.STP_STRING)
- && offset > startingPartition.getOffset()) {
- // don't indent inside (raw-)string
- return false;
- } else if (!fIsTabAction
- && startingPartition.getOffset() == offset
- && startingPartition.getType().equals(
- STPPartitionScanner.STP_COMMENT)) {
- // line comment starting at position 0 -> indent inside
- if (indentInsideLineComments()) {
- int max = document.getLength() - offset;
- int slashes = 2;
- while (slashes < max - 1
- && document.get(offset + slashes, 2).equals("//")) //$NON-NLS-1$
- slashes += 2;
-
- wsStart = offset + slashes;
-
- StringBuilder computed = indenter
- .computeIndentation(offset);
- if (computed == null)
- computed = new StringBuilder(0);
- int tabSize = getTabSize();
- while (slashes > 0 && computed.length() > 0) {
- char c = computed.charAt(0);
- if (c == '\t') {
- if (slashes > tabSize) {
- slashes -= tabSize;
- } else {
- break;
- }
- } else if (c == ' ') {
- slashes--;
- } else {
- break;
- }
-
- computed.deleteCharAt(0);
- }
-
- indent = document.get(offset, wsStart - offset) + computed;
- }
- }
- }
-
- // standard C code indentation
- if (indent == null) {
- StringBuilder computed = indenter.computeIndentation(offset);
- if (computed != null) {
- indent = computed.toString();
- } else {
- indent = ""; //$NON-NLS-1$
- }
- }
-
- // change document:
- // get current white space
- int lineLength = currentLine.getLength();
- int end = scanner.findNonWhitespaceForwardInAnyPartition(wsStart,
- offset + lineLength);
- if (end == STPHeuristicScanner.NOT_FOUND) {
- // an empty line
- end = offset + lineLength;
- if (multiLine && !indentEmptyLines()) {
- indent = ""; //$NON-NLS-1$
- }
- }
- int length = end - offset;
- String currentIndent = document.get(offset, length);
-
- // set the caret offset so it can be used when setting the selection
- if (caret >= offset && caret <= end) {
- fCaretOffset = offset + indent.length();
- } else {
- fCaretOffset = -1;
- }
-
- // only change the document if it is a real change
- if (!indent.equals(currentIndent)) {
- document.replace(offset, length, indent);
- return true;
- }
- return false;
- }
-
- /**
- * Computes and returns the indentation for a block comment line.
- *
- * @param document
- * the document
- * @param line
- * the line in document
- * @param scanner
- * the scanner
- * @param partition
- * the comment partition
- * @return the indent, or <code>null</code> if not computable
- * @throws BadLocationException
- */
- private String computeCommentIndent(IDocument document, int line,
- STPHeuristicScanner scanner, ITypedRegion partition)
- throws BadLocationException {
- return IndentUtil.computeCommentIndent(document, line, scanner,
- partition);
- }
-
- /**
- * Computes and returns the indentation for a preprocessor line.
- *
- * @param document
- * the document
- * @param line
- * the line in document
- * @param partition
- * the comment partition
- * @return the indent, or <code>null</code> if not computable
- * @throws BadLocationException
- */
- private String computePreprocessorIndent(IDocument document, int line,
- ITypedRegion partition) throws BadLocationException {
- return IndentUtil.computePreprocessorIndent(document, line, partition);
- }
-
- /**
- * Returns the tab size used by the editor, which is deduced from the
- * formatter preferences.
- *
- * @return the tab size as defined in the current formatter preferences
- */
- private int getTabSize() {
- return getCoreFormatterOption(
- STPDefaultCodeFormatterConstants.FORMATTER_TAB_SIZE, 4);
- }
-
- /**
- * Returns <code>true</code> if empty lines should be indented,
- * <code>false</code> otherwise.
- *
- * @return <code>true</code> if empty lines should be indented,
- * <code>false</code> otherwise
- */
- private boolean indentEmptyLines() {
- return STPDefaultCodeFormatterConstants.TRUE
- .equals(getCoreFormatterOption(STPDefaultCodeFormatterConstants.FORMATTER_INDENT_EMPTY_LINES));
- }
-
- /**
- * Returns <code>true</code> if line comments at column 0 should be indented
- * inside, <code>false</code> otherwise.
- *
- * @return <code>true</code> if line comments at column 0 should be indented
- * inside, <code>false</code> otherwise.
- */
- private boolean indentInsideLineComments() {
- return STPDefaultCodeFormatterConstants.TRUE
- .equals(getCoreFormatterOption(STPDefaultCodeFormatterConstants.FORMATTER_INDENT_INSIDE_LINE_COMMENTS));
- }
-
- /**
- * Returns the possibly project-specific core preference defined under
- * <code>key</code>.
- *
- * @param key
- * the key of the preference
- * @return the value of the preference
- */
- private String getCoreFormatterOption(String key) {
- return "false"; //$NON-NLS-1$
- }
-
- /**
- * Returns the possibly project-specific core preference defined under
- * <code>key</code>, or <code>def</code> if the value is not a integer.
- *
- * @param key
- * the key of the preference
- * @param def
- * the default value
- * @return the value of the preference
- */
- private int getCoreFormatterOption(String key, int def) {
- try {
- return Integer.parseInt(getCoreFormatterOption(key));
- } catch (NumberFormatException e) {
- return def;
- }
- }
-
- /**
- * Returns the <code>IProject</code> of the current editor input, or
- * <code>null</code> if it cannot be found.
- *
- * @return the <code>IProject</code> of the current editor input, or
- * <code>null</code> if it cannot be found
- */
- private IProject getProject(ITextEditor editor) {
- if (editor == null)
- return null;
-
- IEditorInput input = editor.getEditorInput();
- if (input instanceof IFileEditorInput)
- return ((IFileEditorInput) input).getFile().getProject();
- return null;
- }
-
- /**
- * Returns the editor's selection provider.
- *
- * @return the editor's selection provider or <code>null</code>
- */
- private ISelectionProvider getSelectionProvider(ITextEditor editor) {
- if (editor != null) {
- return editor.getSelectionProvider();
- }
- return null;
- }
-
- /*
- * @see org.eclipse.ui.texteditor.IUpdate#update()
- */
-
- /**
- * Returns the document currently displayed in the editor, or
- * <code>null</code> if none can be obtained.
- *
- * @return the current document or <code>null</code>
- */
- private IDocument getDocument(ITextEditor editor) {
- if (editor != null) {
- IDocumentProvider provider = editor.getDocumentProvider();
- IEditorInput input = editor.getEditorInput();
- if (provider != null && input != null)
- return provider.getDocument(input);
-
- }
- return null;
- }
-
- /**
- * Returns the selection on the editor or an invalid selection if none can
- * be obtained. Returns never <code>null</code>.
- *
- * @return the current selection, never <code>null</code>
- */
- private ITextSelection getSelection(ITextEditor editor) {
- ISelectionProvider provider = getSelectionProvider(editor);
- if (provider != null) {
- ISelection selection = provider.getSelection();
- if (selection instanceof ITextSelection)
- return (ITextSelection) selection;
- }
-
- // null object
- return TextSelection.emptySelection();
- }
+ }
+
+ // update caret position: move to new position when
+ // indenting just one line
+ // keep selection when indenting multiple
+ int newOffset, newLength;
+ if (!fIsTabAction && multiLine) {
+ newOffset = offset;
+ newLength = end.getOffset() - offset;
+ } else {
+ newOffset = fCaretOffset;
+ newLength = 0;
+ }
+
+ // always reset the selection if anything was replaced
+ // but not when we had a single line non-tab invocation
+ if (newOffset != -1
+ && (hasChanged || newOffset != offset || newLength != length))
+ selectAndReveal(getTextEditor(), newOffset,
+ newLength);
+
+ } catch (BadLocationException e) {
+ // will only happen on concurrent modification
+ IDEPlugin.log(new Status(IStatus.ERROR, IDEPlugin
+ .PLUGIN_ID, IStatus.OK,
+ "ConcurrentModification in IndentAction", e)); //$NON-NLS-1$
+ } finally {
+ document.removePosition(end);
+ if (target != null) {
+ target.endCompoundChange();
+ }
+ }
+ }
+ };
+
+ if (nLines > 50) {
+ Display display = editor.getEditorSite().getWorkbenchWindow()
+ .getShell().getDisplay();
+ BusyIndicator.showWhile(display, runnable);
+ } else {
+ runnable.run();
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ * Selects the given range on the editor.
+ *
+ * @param newOffset
+ * the selection offset
+ * @param newLength
+ * the selection range
+ */
+ private void selectAndReveal(ITextEditor editor, int newOffset,
+ int newLength) {
+ Assert.isTrue(newOffset >= 0);
+ Assert.isTrue(newLength >= 0);
+ if (editor instanceof STPEditor) {
+ ISourceViewer viewer = ((STPEditor) editor).getMySourceViewer();
+ if (viewer != null) {
+ viewer.setSelectedRange(newOffset, newLength);
+ }
+ } else {
+ // this is too intrusive, but will never get called anyway
+ editor.selectAndReveal(newOffset, newLength);
+ }
+ }
+
+ /**
+ * Indents a single line using the heuristic scanner. Multiline comments are
+ * indented as specified by the <code>CCommentAutoIndentStrategy</code>.
+ *
+ * @param document
+ * the document
+ * @param line
+ * the line to be indented
+ * @param caret
+ * the caret position
+ * @param indenter
+ * the indenter
+ * @param scanner
+ * the heuristic scanner
+ * @param multiLine
+ * <code>true</code> if more than one line is being indented
+ * @return <code>true</code> if <code>document</code> was modified,
+ * <code>false</code> otherwise
+ * @throws BadLocationException
+ * if the document got changed concurrently
+ */
+ private boolean indentLine(IDocument document,
+ int line, int caret, STPIndenter indenter,
+ STPHeuristicScanner scanner, boolean multiLine)
+ throws BadLocationException {
+ IRegion currentLine = document.getLineInformation(line);
+ int offset = currentLine.getOffset();
+ int wsStart = offset; // where we start searching for non-WS; after the
+ // "//" in single line comments
+
+ String indent = null;
+ if (offset < document.getLength()) {
+ ITypedRegion partition = TextUtilities.getPartition(document,
+ STPPartitionScanner.STP_PARTITIONING, offset, true);
+ ITypedRegion startingPartition = TextUtilities.getPartition(
+ document, STPPartitionScanner.STP_PARTITIONING, offset,
+ false);
+ String type = partition.getType();
+ if (type.equals(STPPartitionScanner.STP_MULTILINE_COMMENT)) {
+ indent = computeCommentIndent(document, line, scanner,
+ startingPartition);
+ } else if (startingPartition.getType().equals(
+ STPPartitionScanner.STP_CONDITIONAL)) {
+ indent = computePreprocessorIndent(document, line,
+ startingPartition);
+ } else if (startingPartition.getType().equals(
+ STPPartitionScanner.STP_STRING)
+ && offset > startingPartition.getOffset()) {
+ // don't indent inside (raw-)string
+ return false;
+ } else if (!fIsTabAction
+ && startingPartition.getOffset() == offset
+ && startingPartition.getType().equals(
+ STPPartitionScanner.STP_COMMENT)) {
+ // line comment starting at position 0 -> indent inside
+ if (indentInsideLineComments()) {
+ int max = document.getLength() - offset;
+ int slashes = 2;
+ while (slashes < max - 1
+ && document.get(offset + slashes, 2).equals("//")) //$NON-NLS-1$
+ slashes += 2;
+
+ wsStart = offset + slashes;
+
+ StringBuilder computed = indenter
+ .computeIndentation(offset);
+ if (computed == null)
+ computed = new StringBuilder(0);
+ int tabSize = getTabSize();
+ while (slashes > 0 && computed.length() > 0) {
+ char c = computed.charAt(0);
+ if (c == '\t') {
+ if (slashes > tabSize) {
+ slashes -= tabSize;
+ } else {
+ break;
+ }
+ } else if (c == ' ') {
+ slashes--;
+ } else {
+ break;
+ }
+
+ computed.deleteCharAt(0);
+ }
+
+ indent = document.get(offset, wsStart - offset) + computed;
+ }
+ }
+ }
+
+ // standard C code indentation
+ if (indent == null) {
+ StringBuilder computed = indenter.computeIndentation(offset);
+ if (computed != null) {
+ indent = computed.toString();
+ } else {
+ indent = ""; //$NON-NLS-1$
+ }
+ }
+
+ // change document:
+ // get current white space
+ int lineLength = currentLine.getLength();
+ int end = scanner.findNonWhitespaceForwardInAnyPartition(wsStart,
+ offset + lineLength);
+ if (end == STPHeuristicScanner.NOT_FOUND) {
+ // an empty line
+ end = offset + lineLength;
+ if (multiLine && !indentEmptyLines()) {
+ indent = ""; //$NON-NLS-1$
+ }
+ }
+ int length = end - offset;
+ String currentIndent = document.get(offset, length);
+
+ // set the caret offset so it can be used when setting the selection
+ if (caret >= offset && caret <= end) {
+ fCaretOffset = offset + indent.length();
+ } else {
+ fCaretOffset = -1;
+ }
+
+ // only change the document if it is a real change
+ if (!indent.equals(currentIndent)) {
+ document.replace(offset, length, indent);
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Computes and returns the indentation for a block comment line.
+ *
+ * @param document
+ * the document
+ * @param line
+ * the line in document
+ * @param scanner
+ * the scanner
+ * @param partition
+ * the comment partition
+ * @return the indent, or <code>null</code> if not computable
+ * @throws BadLocationException
+ */
+ private String computeCommentIndent(IDocument document, int line,
+ STPHeuristicScanner scanner, ITypedRegion partition)
+ throws BadLocationException {
+ return IndentUtil.computeCommentIndent(document, line, scanner,
+ partition);
+ }
+
+ /**
+ * Computes and returns the indentation for a preprocessor line.
+ *
+ * @param document
+ * the document
+ * @param line
+ * the line in document
+ * @param partition
+ * the comment partition
+ * @return the indent, or <code>null</code> if not computable
+ * @throws BadLocationException
+ */
+ private String computePreprocessorIndent(IDocument document, int line,
+ ITypedRegion partition) throws BadLocationException {
+ return IndentUtil.computePreprocessorIndent(document, line, partition);
+ }
+
+ /**
+ * Returns the tab size used by the editor, which is deduced from the
+ * formatter preferences.
+ *
+ * @return the tab size as defined in the current formatter preferences
+ */
+ private int getTabSize() {
+ return getCoreFormatterOption(
+ STPDefaultCodeFormatterConstants.FORMATTER_TAB_SIZE, 4);
+ }
+
+ /**
+ * Returns <code>true</code> if empty lines should be indented,
+ * <code>false</code> otherwise.
+ *
+ * @return <code>true</code> if empty lines should be indented,
+ * <code>false</code> otherwise
+ */
+ private boolean indentEmptyLines() {
+ return STPDefaultCodeFormatterConstants.TRUE
+ .equals(getCoreFormatterOption(STPDefaultCodeFormatterConstants.FORMATTER_INDENT_EMPTY_LINES));
+ }
+
+ /**
+ * Returns <code>true</code> if line comments at column 0 should be indented
+ * inside, <code>false</code> otherwise.
+ *
+ * @return <code>true</code> if line comments at column 0 should be indented
+ * inside, <code>false</code> otherwise.
+ */
+ private boolean indentInsideLineComments() {
+ return STPDefaultCodeFormatterConstants.TRUE
+ .equals(getCoreFormatterOption(STPDefaultCodeFormatterConstants.FORMATTER_INDENT_INSIDE_LINE_COMMENTS));
+ }
+
+ /**
+ * Returns the possibly project-specific core preference defined under
+ * <code>key</code>.
+ *
+ * @param key
+ * the key of the preference
+ * @return the value of the preference
+ */
+ private String getCoreFormatterOption(String key) {
+ return "false"; //$NON-NLS-1$
+ }
+
+ /**
+ * Returns the possibly project-specific core preference defined under
+ * <code>key</code>, or <code>def</code> if the value is not a integer.
+ *
+ * @param key
+ * the key of the preference
+ * @param def
+ * the default value
+ * @return the value of the preference
+ */
+ private int getCoreFormatterOption(String key, int def) {
+ try {
+ return Integer.parseInt(getCoreFormatterOption(key));
+ } catch (NumberFormatException e) {
+ return def;
+ }
+ }
+
+ /**
+ * Returns the <code>IProject</code> of the current editor input, or
+ * <code>null</code> if it cannot be found.
+ *
+ * @return the <code>IProject</code> of the current editor input, or
+ * <code>null</code> if it cannot be found
+ */
+ private IProject getProject(ITextEditor editor) {
+ if (editor == null)
+ return null;
+
+ IEditorInput input = editor.getEditorInput();
+ if (input instanceof IFileEditorInput)
+ return ((IFileEditorInput) input).getFile().getProject();
+ return null;
+ }
+
+ /**
+ * Returns the editor's selection provider.
+ *
+ * @return the editor's selection provider or <code>null</code>
+ */
+ private ISelectionProvider getSelectionProvider(ITextEditor editor) {
+ if (editor != null) {
+ return editor.getSelectionProvider();
+ }
+ return null;
+ }
+
+ /*
+ * @see org.eclipse.ui.texteditor.IUpdate#update()
+ */
+
+ /**
+ * Returns the document currently displayed in the editor, or
+ * <code>null</code> if none can be obtained.
+ *
+ * @return the current document or <code>null</code>
+ */
+ private IDocument getDocument(ITextEditor editor) {
+ if (editor != null) {
+ IDocumentProvider provider = editor.getDocumentProvider();
+ IEditorInput input = editor.getEditorInput();
+ if (provider != null && input != null)
+ return provider.getDocument(input);
+
+ }
+ return null;
+ }
+
+ /**
+ * Returns the selection on the editor or an invalid selection if none can
+ * be obtained. Returns never <code>null</code>.
+ *
+ * @return the current selection, never <code>null</code>
+ */
+ private ITextSelection getSelection(ITextEditor editor) {
+ ISelectionProvider provider = getSelectionProvider(editor);
+ if (provider != null) {
+ ISelection selection = provider.getSelection();
+ if (selection instanceof ITextSelection)
+ return (ITextSelection) selection;
+ }
+
+ // null object
+ return TextSelection.emptySelection();
+ }
}
diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/actions/KernelSourceAction.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/actions/KernelSourceAction.java
index 6256a016c4..e0d3ba090c 100644
--- a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/actions/KernelSourceAction.java
+++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/actions/KernelSourceAction.java
@@ -35,57 +35,57 @@ import org.eclipse.ui.ide.FileStoreEditorInput;
* @see org.eclipse.linuxtools.internal.systemtap.ui.ide.views.KernelBrowserView
*/
public class KernelSourceAction extends BrowserViewAction {
- public final static String ID = "org.eclipse.linuxtools.systemtap.ui.ide.KBAction"; //$NON-NLS-1$
- private static final String CDT_EDITOR_ID = "org.eclipse.cdt.ui.editor.CEditor"; //$NON-NLS-1$
+ public final static String ID = "org.eclipse.linuxtools.systemtap.ui.ide.KBAction"; //$NON-NLS-1$
+ private static final String CDT_EDITOR_ID = "org.eclipse.cdt.ui.editor.CEditor"; //$NON-NLS-1$
- /**
- * The default constructor for the <code>KernelSourceAction</code>. Takes the window that it affects
- * and the <code>KernelBrowserView</code> that will fire the event as arguments.
- * @param window The <code>IWorkbenchWindow</code> that the action operates on.
- * @param browser The <code>KernelBrowserView</code> that fires this action.
- */
- public KernelSourceAction(IWorkbenchWindow window, KernelBrowserView browser) {
- super(window, browser);
- setId(ID);
- setActionDefinitionId(ID);
- setText(Localization.getString("KernelSourceAction.Insert")); //$NON-NLS-1$
- setToolTipText(Localization
- .getString("KernelSourceAction.InsertSelectedFunction")); //$NON-NLS-1$
- }
+ /**
+ * The default constructor for the <code>KernelSourceAction</code>. Takes the window that it affects
+ * and the <code>KernelBrowserView</code> that will fire the event as arguments.
+ * @param window The <code>IWorkbenchWindow</code> that the action operates on.
+ * @param browser The <code>KernelBrowserView</code> that fires this action.
+ */
+ public KernelSourceAction(IWorkbenchWindow window, KernelBrowserView browser) {
+ super(window, browser);
+ setId(ID);
+ setActionDefinitionId(ID);
+ setText(Localization.getString("KernelSourceAction.Insert")); //$NON-NLS-1$
+ setToolTipText(Localization
+ .getString("KernelSourceAction.InsertSelectedFunction")); //$NON-NLS-1$
+ }
- /**
- * The main code body for this action. Causes one of the following to occur:
- * <ul>
- * <li>If the selected node is clickable, as specified in <code>TreeNode.isClickable</code>
- * the browser creates an instance of <code>CEditor</code> on the file specified in the selection
- * (<code>KernelBrowserView</code>'s tree only marks clickable on files, not folders) and
- * opens it on the current window</li>
- * <li>If the selected node is not clickable, the code runs the action specified in
- * <code>TreeExpandCollapseAction</code></li>
- * @see org.eclipse.linuxtools.internal.systemtap.ui.ide.editors.c.CEditor
- * @see TreeNode#isClickable()
- * @see TreeExpandCollapseAction
- */
- @Override
- public void run() {
- IWorkbench wb = PlatformUI.getWorkbench();
- Object o = getSelectedElement();
- if (o instanceof TreeNode) {
- TreeNode t = (TreeNode) o;
- if (t.isClickable()) {
- IFileStore fs = (IFileStore) t.getData();
- if (fs != null) {
- IEditorInput input = new FileStoreEditorInput(fs);
- try {
- wb.getActiveWorkbenchWindow().getActivePage().openEditor(input, CDT_EDITOR_ID);
- } catch (PartInitException e) {
- ExceptionErrorDialog.openError(Messages.ScriptRunAction_errorDialogTitle, e);
- }
- }
- } else {
- runExpandAction();
- }
- }
- }
+ /**
+ * The main code body for this action. Causes one of the following to occur:
+ * <ul>
+ * <li>If the selected node is clickable, as specified in <code>TreeNode.isClickable</code>
+ * the browser creates an instance of <code>CEditor</code> on the file specified in the selection
+ * (<code>KernelBrowserView</code>'s tree only marks clickable on files, not folders) and
+ * opens it on the current window</li>
+ * <li>If the selected node is not clickable, the code runs the action specified in
+ * <code>TreeExpandCollapseAction</code></li>
+ * @see org.eclipse.linuxtools.internal.systemtap.ui.ide.editors.c.CEditor
+ * @see TreeNode#isClickable()
+ * @see TreeExpandCollapseAction
+ */
+ @Override
+ public void run() {
+ IWorkbench wb = PlatformUI.getWorkbench();
+ Object o = getSelectedElement();
+ if (o instanceof TreeNode) {
+ TreeNode t = (TreeNode) o;
+ if (t.isClickable()) {
+ IFileStore fs = (IFileStore) t.getData();
+ if (fs != null) {
+ IEditorInput input = new FileStoreEditorInput(fs);
+ try {
+ wb.getActiveWorkbenchWindow().getActivePage().openEditor(input, CDT_EDITOR_ID);
+ } catch (PartInitException e) {
+ ExceptionErrorDialog.openError(Messages.ScriptRunAction_errorDialogTitle, e);
+ }
+ }
+ } else {
+ runExpandAction();
+ }
+ }
+ }
}
diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/actions/Messages.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/actions/Messages.java
index 6d3de68a58..ee86c74c1e 100644
--- a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/actions/Messages.java
+++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/actions/Messages.java
@@ -17,24 +17,24 @@ import org.eclipse.osgi.util.NLS;
* @since 2.0
*/
public class Messages extends NLS {
- private static final String BUNDLE_NAME = "org.eclipse.linuxtools.internal.systemtap.ui.ide.actions.messages"; //$NON-NLS-1$
- public static String ScriptRunAction_InvalidScriptTitle;
- public static String ScriptRunAction_InvalidScriptTMessage;
- public static String ScriptRunAction_errorDialogTitle;
- public static String RunScriptAction_alreadyRunningDialogTitle;
- public static String RunScriptAction_alreadyRunningDialogMessage;
- public static String RunScriptChartAction_couldNotSwitchToGraphicPerspective;
- public static String DataSetFileExtension;
- public static String ExportDataSetAction_DialogTitle;
- public static String ImportDataSetAction_DialogTitle;
- public static String ImportDataSetAction_FileInvalid;
- public static String ImportDataSetAction_FileNotFound;
+ private static final String BUNDLE_NAME = "org.eclipse.linuxtools.internal.systemtap.ui.ide.actions.messages"; //$NON-NLS-1$
+ public static String ScriptRunAction_InvalidScriptTitle;
+ public static String ScriptRunAction_InvalidScriptTMessage;
+ public static String ScriptRunAction_errorDialogTitle;
+ public static String RunScriptAction_alreadyRunningDialogTitle;
+ public static String RunScriptAction_alreadyRunningDialogMessage;
+ public static String RunScriptChartAction_couldNotSwitchToGraphicPerspective;
+ public static String DataSetFileExtension;
+ public static String ExportDataSetAction_DialogTitle;
+ public static String ImportDataSetAction_DialogTitle;
+ public static String ImportDataSetAction_FileInvalid;
+ public static String ImportDataSetAction_FileNotFound;
- static {
- // initialize resource bundle
- NLS.initializeMessages(BUNDLE_NAME, Messages.class);
- }
+ static {
+ // initialize resource bundle
+ NLS.initializeMessages(BUNDLE_NAME, Messages.class);
+ }
- private Messages() {
- }
+ private Messages() {
+ }
}
diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/actions/ProbeAliasAction.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/actions/ProbeAliasAction.java
index 7de9559ac3..9b6d75f789 100644
--- a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/actions/ProbeAliasAction.java
+++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/actions/ProbeAliasAction.java
@@ -33,63 +33,63 @@ import org.eclipse.ui.IWorkbenchWindow;
* @see org.eclipse.jface.action.Action
*/
public class ProbeAliasAction extends BrowserViewAction {
- private static final String ID = "org.eclipse.linuxtools.systemtap.ui.ide.ProbeAliasAction"; //$NON-NLS-1$
+ private static final String ID = "org.eclipse.linuxtools.systemtap.ui.ide.ProbeAliasAction"; //$NON-NLS-1$
- public ProbeAliasAction(IWorkbenchWindow window, ProbeAliasBrowserView view) {
- super(window, view);
- setId(ID);
- setActionDefinitionId(ID);
- setText(Localization.getString("ProbeAliasAction.Insert")); //$NON-NLS-1$
- setToolTipText(Localization
- .getString("ProbeAliasAction.InsertSelectedProbe")); //$NON-NLS-1$
- }
+ public ProbeAliasAction(IWorkbenchWindow window, ProbeAliasBrowserView view) {
+ super(window, view);
+ setId(ID);
+ setActionDefinitionId(ID);
+ setText(Localization.getString("ProbeAliasAction.Insert")); //$NON-NLS-1$
+ setToolTipText(Localization
+ .getString("ProbeAliasAction.InsertSelectedProbe")); //$NON-NLS-1$
+ }
- /**
- * The main body of the action. This method checks for the current editor, creating one
- * if there is no active <code>STPEditor</code>, and then inserts a template probe for the
- * item that the user clicked on.
- */
- @Override
- public void run() {
- Object o = getSelectedElement();
- if (o instanceof TreeNode) {
- TreeNode t = (TreeNode) o;
- if (t.isClickable()) {
- STPEditor stpeditor = IDESessionSettings.getOrAskForActiveSTPEditor(true);
- if (stpeditor != null) {
- stpeditor.insertText(buildString((TreeNode) o));
- }
- } else {
- runExpandAction();
- }
- }
- }
+ /**
+ * The main body of the action. This method checks for the current editor, creating one
+ * if there is no active <code>STPEditor</code>, and then inserts a template probe for the
+ * item that the user clicked on.
+ */
+ @Override
+ public void run() {
+ Object o = getSelectedElement();
+ if (o instanceof TreeNode) {
+ TreeNode t = (TreeNode) o;
+ if (t.isClickable()) {
+ STPEditor stpeditor = IDESessionSettings.getOrAskForActiveSTPEditor(true);
+ if (stpeditor != null) {
+ stpeditor.insertText(buildString((TreeNode) o));
+ }
+ } else {
+ runExpandAction();
+ }
+ }
+ }
- private String buildString(TreeNode t) {
- //build the string
- StringBuilder s = new StringBuilder("\nprobe " + t.toString()); //$NON-NLS-1$
- if (t.getChildCount() > 0 && t.getChildAt(0).getData() instanceof ProbeNodeData) {
- s.append(".*"); //$NON-NLS-1$
- }
- s.append("\n{\n"); //$NON-NLS-1$
- if (t.getChildCount() > 0 && t.getChildAt(0).getData() instanceof ProbevarNodeData) {
- s.append("\t/*\n\t * " + //$NON-NLS-1$
- Localization
- .getString("ProbeAliasAction.AvailableVariables") + //$NON-NLS-1$
- "\n\t * "); //$NON-NLS-1$
- boolean first = true;
- for(int i = 0; i < t.getChildCount(); i++) {
- if(first) {
- first = false;
- } else {
- s.append(", "); //$NON-NLS-1$
- }
- s.append(t.getChildAt(i).toString());
- }
- s.append("\n\t */\n"); //$NON-NLS-1$
- }
- s.append("\n}\n"); //$NON-NLS-1$
- return s.toString();
- }
+ private String buildString(TreeNode t) {
+ //build the string
+ StringBuilder s = new StringBuilder("\nprobe " + t.toString()); //$NON-NLS-1$
+ if (t.getChildCount() > 0 && t.getChildAt(0).getData() instanceof ProbeNodeData) {
+ s.append(".*"); //$NON-NLS-1$
+ }
+ s.append("\n{\n"); //$NON-NLS-1$
+ if (t.getChildCount() > 0 && t.getChildAt(0).getData() instanceof ProbevarNodeData) {
+ s.append("\t/*\n\t * " + //$NON-NLS-1$
+ Localization
+ .getString("ProbeAliasAction.AvailableVariables") + //$NON-NLS-1$
+ "\n\t * "); //$NON-NLS-1$
+ boolean first = true;
+ for(int i = 0; i < t.getChildCount(); i++) {
+ if(first) {
+ first = false;
+ } else {
+ s.append(", "); //$NON-NLS-1$
+ }
+ s.append(t.getChildAt(i).toString());
+ }
+ s.append("\n\t */\n"); //$NON-NLS-1$
+ }
+ s.append("\n}\n"); //$NON-NLS-1$
+ return s.toString();
+ }
}
diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/actions/RunScriptChartHandler.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/actions/RunScriptChartHandler.java
index c8b04659ac..62ba6d47b0 100644
--- a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/actions/RunScriptChartHandler.java
+++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/actions/RunScriptChartHandler.java
@@ -34,44 +34,44 @@ import org.eclipse.ui.WorkbenchException;
*/
public class RunScriptChartHandler extends RunScriptHandler {
- private List<IDataSetParser> parsers;
- private List<IFilteredDataSet> dataSets;
- private List<String> names;
- private List<LinkedList<GraphData>> graphs;
+ private List<IDataSetParser> parsers;
+ private List<IFilteredDataSet> dataSets;
+ private List<String> names;
+ private List<LinkedList<GraphData>> graphs;
- public RunScriptChartHandler(List<IDataSetParser> parsers, List<IFilteredDataSet> dataSet, List<String> names, List<LinkedList<GraphData>> graphs) {
- super();
- this.parsers = parsers;
- this.dataSets = dataSet;
- this.names = names;
- this.graphs = graphs;
- }
+ public RunScriptChartHandler(List<IDataSetParser> parsers, List<IFilteredDataSet> dataSet, List<String> names, List<LinkedList<GraphData>> graphs) {
+ super();
+ this.parsers = parsers;
+ this.dataSets = dataSet;
+ this.names = names;
+ this.graphs = graphs;
+ }
- @Override
- protected void scriptConsoleInitialized(ScriptConsole console){
- int n = parsers.size();
- for (int i = 0; i < n; i++) {
- console.getCommand().addInputStreamListener(new ChartStreamDaemon(dataSets.get(i), parsers.get(i)));
- }
- try {
- String name = console.getName();
- String title = name.substring(name.lastIndexOf('/')+1);
+ @Override
+ protected void scriptConsoleInitialized(ScriptConsole console){
+ int n = parsers.size();
+ for (int i = 0; i < n; i++) {
+ console.getCommand().addInputStreamListener(new ChartStreamDaemon(dataSets.get(i), parsers.get(i)));
+ }
+ try {
+ String name = console.getName();
+ String title = name.substring(name.lastIndexOf('/')+1);
- IWorkbenchPage p = PlatformUI.getWorkbench().showPerspective(IDEPerspective.ID, PlatformUI.getWorkbench().getActiveWorkbenchWindow());
- GraphSelectorEditor ivp = (GraphSelectorEditor)p.openEditor(new GraphSelectorEditorInput(title), GraphSelectorEditor.ID);
+ IWorkbenchPage p = PlatformUI.getWorkbench().showPerspective(IDEPerspective.ID, PlatformUI.getWorkbench().getActiveWorkbenchWindow());
+ GraphSelectorEditor ivp = (GraphSelectorEditor)p.openEditor(new GraphSelectorEditorInput(title), GraphSelectorEditor.ID);
- String scriptName = console.getName();
- ivp.createScriptSets(scriptName, names, dataSets);
+ String scriptName = console.getName();
+ ivp.createScriptSets(scriptName, names, dataSets);
- for (int i = 0; i < n; i++) {
- for (GraphData graph : graphs.get(i)) {
- ivp.getDisplaySet(i).addGraph(graph);
- }
- }
- } catch(WorkbenchException we) {
- ExceptionErrorDialog.openError(Messages.RunScriptChartAction_couldNotSwitchToGraphicPerspective, we);
- }
- super.scriptConsoleInitialized(console);
- }
+ for (int i = 0; i < n; i++) {
+ for (GraphData graph : graphs.get(i)) {
+ ivp.getDisplaySet(i).addGraph(graph);
+ }
+ }
+ } catch(WorkbenchException we) {
+ ExceptionErrorDialog.openError(Messages.RunScriptChartAction_couldNotSwitchToGraphicPerspective, we);
+ }
+ super.scriptConsoleInitialized(console);
+ }
}
diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/actions/RunScriptHandler.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/actions/RunScriptHandler.java
index 8838a5da03..d46d43094e 100644
--- a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/actions/RunScriptHandler.java
+++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/actions/RunScriptHandler.java
@@ -76,475 +76,475 @@ import com.jcraft.jsch.JSchException;
public class RunScriptHandler extends AbstractHandler {
- /**
- * @since 2.0
- */
- protected boolean continueRun = true;
- private RemoteScriptOptions remoteOptions = null;
- private IEditorPart ed = null;
- private String fileName = null;
- private String tmpfileName = null;
- private String serverfileName = null;
- private IPath path;
- private IProject project;
- private SystemTapScriptLaunch launch;
- private final List<String> cmdList;
-
-
- public RunScriptHandler(){
- this.cmdList = new ArrayList<>();
- }
-
- /**
- * @since 2.0
- */
- public void setPath(IPath path){
- this.path = path;
- URI uri = URIUtil.toURI(path);
- IFile[] files = ResourcesPlugin.getWorkspace().getRoot().findFilesForLocationURI(uri);
- if (files.length > 0) {
- this.project = files[0].getProject();
- }
- }
-
- /**
- * @since 2.1
- */
- public IProject getProject() {
- return project;
- }
-
- /**
- * @since 2.3
- */
- public void setLaunch(SystemTapScriptLaunch launch){
- this.launch = launch;
- }
-
- /**
- * Finds the editor containing the target script to run, so the script can be saved
- * when it is run, if appropriate.
- * The script is saved when it is run with the "simple" run button on the toolbar (path == null),
- * or if the script is outside of a project (working with a PathEditorInput).
- */
- private void findTargetEditor() {
- ed = null;
-
- if (path == null) {
- IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
- ed = window.getActivePage().getActiveEditor();
- return;
- }
-
- for (IWorkbenchWindow window : PlatformUI.getWorkbench().getWorkbenchWindows()) {
- IEditorPart edTest = window.getActivePage().getActiveEditor();
- if (edTest != null && matchesEditor(edTest.getEditorInput(), edTest)) {
- return;
- }
- for (IEditorReference ref : window.getActivePage().getEditorReferences()) {
- try {
- if (matchesEditor(ref.getEditorInput(), ref.getEditor(false))) {
- return;
- }
- } catch (PartInitException e) {
- continue;
- }
- }
- }
- }
-
- private boolean matchesEditor(IEditorInput input, IEditorPart editor) {
- if (input instanceof IPathEditorInput && ((IPathEditorInput) (input)).getPath().equals(this.path)) {
- // Only save the editor when working with a file without a project (PathEditorInput),
- // otherwise the editor isn't needed at all (saving is handled elsewhere in that case).
- if (input instanceof PathEditorInput) {
- this.ed = editor;
- }
- return true;
- }
- return false;
- }
-
- /**
- * The main body of this event. Starts by making sure the current editor is valid to run,
- * then builds the command line arguments for stap and retrieves the environment variables.
- * Finally, it gets an instance of <code>ScriptConsole</code> to run the script.
- */
- @Override
- public Object execute(ExecutionEvent event) throws ExecutionException {
- findTargetEditor();
- final boolean local = getRunLocal();
- if(isValid()) {
- if(!local && !prepareNonLocalScript()) {
- return null;
- }
- final String[] script = buildStandardScript();
- final String[] envVars = getEnvironmentVariables();
- if (continueRun) {
- Display.getDefault().asyncExec(new Runnable() {
- @Override
- public void run() {
- String name = !local ? serverfileName : fileName;
- if (ScriptConsole.instanceIsRunning(name)) {
- MessageDialog dialog = new MessageDialog(
- PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(),
- Messages.RunScriptAction_alreadyRunningDialogTitle, null,
- MessageFormat.format(Messages.RunScriptAction_alreadyRunningDialogMessage, fileName),
- MessageDialog.QUESTION, new String[]{"Yes", "No"}, 0); //$NON-NLS-1$ //$NON-NLS-2$
- if (dialog.open() != Window.OK) {
- if (launch != null) {
- launch.forceRemove();
- }
- return;
- }
- }
- final ScriptConsole console;
- if (!local) {
- console = ScriptConsole.getInstance(serverfileName);
- } else {
- console = ScriptConsole.getInstance(fileName);
- }
- synchronized (console) {
- if (!local) {
- console.run(script, envVars, remoteOptions, new StapErrorParser());
- } else {
- console.runLocally(script, envVars, new StapErrorParser(), getProject());
- }
- scriptConsoleInitialized(console);
- }
- }
- });
- }
- }
-
- return null;
- }
-
- /**
- * Attempts to set up a channel for a script that runs on a non-local host or user.
- * @return <code>true</code> on success, <code>false</code> on failure.
- * @throws ExecutionException If failure occurs during a (non-simple) launch,
- * this will throw an exception instead of returning <code>false</code>.
- */
- private boolean prepareNonLocalScript() throws ExecutionException {
- try {
- ScpClient scpclient = new ScpClient(remoteOptions);
- serverfileName = fileName.substring(fileName.lastIndexOf('/')+1);
- tmpfileName="/tmp/"+ serverfileName; //$NON-NLS-1$
- scpclient.transfer(fileName,tmpfileName);
- } catch (final JSchException | IOException e) {
- final String message = e instanceof JSchException ? Localization.getString("RunScriptHandler.checkCredentials") //$NON-NLS-1$
- : Localization.getString("RunScriptHandler.ioError"); //$NON-NLS-1$
- if (launch == null) {
- Display.getDefault().asyncExec(new Runnable() {
- @Override
- public void run() {
- if (e instanceof JSchException) {
- ErrorDialog.openError(PlatformUI.getWorkbench()
- .getActiveWorkbenchWindow().getShell(),
- Localization.getString("RunScriptHandler.serverError"), Localization.getString("RunScriptHandler.serverError"), //$NON-NLS-1$ //$NON-NLS-2$
- new Status(IStatus.ERROR, IDEPlugin.PLUGIN_ID, message));
- } else {
- ExceptionErrorDialog.openError(Localization.getString("RunScriptHandler.ioError"), e); //$NON-NLS-1$
- }
- }
- });
- return false;
- } else {
- throw new ExecutionException(message, e);
- }
- }
- return true;
- }
-
- /**
- * Once a console for running the script has been created this
- * function is called so that observers can be added for example
- * @param console
- * @since 2.0
- */
- protected void scriptConsoleInitialized(ScriptConsole console){
- if (launch != null && path != null) {
- launch.setConsole(console);
- }
- }
-
- /**
- * Returns the path that was set for this action. If one was not set it
- * returns the path of the current editor in the window this action is
- * associated with.
- *
- * @return The string representation of the path of the script to run.
- */
- protected String getFilePath() {
- if (path != null){
- return path.toOSString();
- }
- if (ed == null) {
- return ""; //$NON-NLS-1$
- }
- if(ed.getEditorInput() instanceof PathEditorInput){
- return ((PathEditorInput)ed.getEditorInput()).getPath().toString();
- } else {
- return ResourceUtil.getFile(ed.getEditorInput()).getLocation().toString();
- }
- }
-
- /**
- * Checks if the current editor is operating on a file that actually exists and can be
- * used as an argument to stap (as opposed to an unsaved buffer).
- * @return True if the file is valid.
- */
- private boolean isValid() {
- // If the path is not set this action will run the script from
- // the active editor
- if(!tryEditorSave()){
- if (this.path == null){
- Display.getDefault().asyncExec(new Runnable() {
- @Override
- public void run() {
- String msg = MessageFormat.format(Localization.getString("RunScriptAction.NoScriptFile"),(Object[]) null); //$NON-NLS-1$
- MessageDialog.openWarning(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(), Localization.getString("RunScriptAction.Problem"), msg); //$NON-NLS-1$
- }
- });
- return false;
- }
- }
- String filePath = this.getFilePath();
- return filePath.endsWith(".stp") //$NON-NLS-1$
- && isValidDirectory(filePath);
- }
-
- private boolean tryEditorSave() {
- if(null == ed) {
- return false;
- }
-
- if(ed.isDirty()) {
- Display.getDefault().syncExec(new Runnable() {
- @Override
- public void run() {
- ed.doSave(new ProgressMonitorPart(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(), new FillLayout()));
- }
- });
- }
-
- return true;
- }
-
- /**
- * Checks whether the directory to which the given file
- * belongs is a valid directory. Currently this function just
- * checks if the given file does not belong to the tapset
- * directory.
- * @param fileName
- * @return true if the given path is valid false otherwise.
- * @since 1.2
- */
- private boolean isValidDirectory(String fileName) {
- this.fileName = fileName;
- if(0 == IDESessionSettings.tapsetLocation.trim().length()){
- TapsetLibrary.getTapsetLocation(IDEPlugin.getDefault().getPreferenceStore());
- }
-
- if(fileName.contains(IDESessionSettings.tapsetLocation)) {
- Display.getDefault().asyncExec(new Runnable() {
- @Override
- public void run() {
- String msg = MessageFormat.format(Localization.getString("RunScriptAction.TapsetDirectoryRun"),(Object []) null); //$NON-NLS-1$
- MessageDialog.openWarning(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(), Localization.getString("RunScriptAction.Error"), msg); //$NON-NLS-1$
- }
- });
- return false;
- }
- return true;
- }
-
- /**
- * Adds the given String to the list of commands to be
- * passed to systemtap when running the command
- * @param option
- */
- public void addComandLineOptions(String option){
- this.cmdList.add(option);
- }
-
- /**
- * The command line argument generation method used by <code>RunScriptAction</code>. This generates
- * a stap command line that includes the tapsets specified in user preferences, a guru mode flag
- * if necessary, and the path to the script on disk.
- * @return The command to invoke to start the script running in stap.
- * @since 2.0
- */
- private String[] buildStandardScript() {
- getImportedTapsets(cmdList);
-
- if(isGuru()) {
- cmdList.add("-g"); //$NON-NLS-1$
- }
-
- return finalizeScript(cmdList);
- }
-
- /**
- * Adds the tapsets that the user has added in preferences to the input <code>ArrayList</code>
- * @param cmdList The list to add the user-specified tapset locations to.
- * @since 2.0
- */
-
- private void getImportedTapsets(List<String> cmdList) {
- IPreferenceStore preferenceStore = IDEPlugin.getDefault().getPreferenceStore();
- String[] tapsets = preferenceStore.getString(IDEPreferenceConstants.P_TAPSETS).split(File.pathSeparator);
-
- //Get all imported tapsets
- if(tapsets.length > 0 && tapsets[0].trim().length() > 0) {
- for(int i=0; i<tapsets.length; i++) {
- cmdList.add("-I"); //$NON-NLS-1$
- cmdList.add(tapsets[i]);
- }
- }
- }
-
- /**
- * Checks the current script to determine if guru mode is required in order to run. This is determined
- * by the presence of embedded C.
- * @return True if the script contains embedded C code.
- */
- private boolean isGuru() {
- File f = new File(fileName);
- try (FileReader fr = new FileReader(f)){
- int curr = 0;
- int prev = 0;
- boolean front = false;
- boolean imbedded = false;
- boolean inLineComment = false;
- boolean inBlockComment = false;
- while(-1 != (curr = fr.read())) {
- if(!inLineComment && !inBlockComment && '%' == prev && '{' == curr) {
- front = true;
- } else if(!inLineComment && !inBlockComment && '%' == prev && '}' == curr && front) {
- imbedded = true;
- break;
- } else if(!inBlockComment && (('/' == prev && '/' == curr) || '#' == curr)) {
- inLineComment = true;
- } else if(!inLineComment && '/' == prev && '*' == curr) {
- inBlockComment = true;
- } else if('\n' == curr) {
- inLineComment = false;
- } else if('*' == prev && '/' == curr) {
- inBlockComment = false;
- }
- prev = curr;
- }
- fr.close();
- if(imbedded) {
- return true;
- }
- } catch (FileNotFoundException fnfe) {
- ExceptionErrorDialog.openError(Localization.getString("RunScriptHandler.couldNotOpenScriptFile"), fnfe); //$NON-NLS-1$
- } catch (IOException ie) {
- ExceptionErrorDialog.openError(Localization.getString("RunScriptHandler.fileIOError"), ie); //$NON-NLS-1$
- }
- return false;
- }
-
- /**
- * Produces a <code>String[]</code> from the <code>ArrayList</code> passed in with stap inserted
- * as the first entry, and the filename as the last entry. Used to convert the arguments generated
- * earlier in <code>buildStandardScript</code> such as tapset locations and guru mode into an actual
- * command line argument array that can be passed to <code>Runtime.exec</code>.
- * @param cmdList The list of arguments for stap for this script
- * @return An array suitable to pass to <code>Runtime.exec</code> to start stap on this file.
- * @since 2.0
- */
- private String[] finalizeScript(List<String> cmdList) {
-
- String[] script;
-
- script = new String[cmdList.size() + 4];
- script[0] = "stap"; //$NON-NLS-1$
-
- if(getRunLocal() == false) {
- script[script.length-1] = tmpfileName;
- } else {
- script[script.length-1] = fileName;
- }
-
- for(int i=0; i< cmdList.size(); i++) {
- script[i+1] = cmdList.get(i);
- }
- script[script.length-3]="-m"; //$NON-NLS-1$
-
- String modname;
- if(getRunLocal() == false) {
- modname = serverfileName.substring(0, serverfileName.lastIndexOf(".stp")); //$NON-NLS-1$
- }
- /* We need to remove the directory prefix here because in the case of
- * running the script remotely, this is already done. Not doing so
- * causes a modname error.
- */
- else {
- modname = fileName.substring(fileName.lastIndexOf('/')+1);
- modname = modname.substring(0, modname.lastIndexOf(".stp")); //$NON-NLS-1$
- }
-
- // Make sure script name only contains underscores and/or alphanumeric characters.
- Pattern validModName = Pattern.compile("^[a-z0-9_A-Z]+$"); //$NON-NLS-1$
- Matcher modNameMatch = validModName.matcher(modname);
- if (!modNameMatch.matches()) {
- continueRun = false;
- Display.getDefault().asyncExec(new Runnable() {
- @Override
- public void run() {
-
- Shell parent = PlatformUI.getWorkbench().getDisplay()
- .getActiveShell();
- MessageDialog.openError(parent,
- Messages.ScriptRunAction_InvalidScriptTitle,
- Messages.ScriptRunAction_InvalidScriptTMessage);
- }
- });
- return new String[0];
- }
-
- script[script.length-2]=modname;
- return script;
- }
-
- private String[] getEnvironmentVariables() {
- return EnvironmentVariablesPreferencePage.getEnvironmentVariables();
- }
-
- @Override
- public boolean isEnabled() {
- return (PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().getActiveEditor() instanceof STPEditor);
- }
-
- /**
- * Set the options for running the script remotely. If the script is to be run locally,
- * pass <code>null</code> as the only parameter.
- * @param remoteOptions The remote options of the script run, or <code>null</code> if the script
- * is to be run locally.
- * @since 3.0
- */
- public void setRemoteScriptOptions(RemoteScriptOptions remoteOptions) {
- this.remoteOptions = remoteOptions;
- }
-
- private boolean getRunLocal() {
- return remoteOptions == null;
- }
-
- @Override
- public void addHandlerListener(IHandlerListener handlerListener) {
- // TODO Auto-generated method stub
-
- }
-
- @Override
- public void removeHandlerListener(IHandlerListener handlerListener) {
- // TODO Auto-generated method stub
-
- }
+ /**
+ * @since 2.0
+ */
+ protected boolean continueRun = true;
+ private RemoteScriptOptions remoteOptions = null;
+ private IEditorPart ed = null;
+ private String fileName = null;
+ private String tmpfileName = null;
+ private String serverfileName = null;
+ private IPath path;
+ private IProject project;
+ private SystemTapScriptLaunch launch;
+ private final List<String> cmdList;
+
+
+ public RunScriptHandler(){
+ this.cmdList = new ArrayList<>();
+ }
+
+ /**
+ * @since 2.0
+ */
+ public void setPath(IPath path){
+ this.path = path;
+ URI uri = URIUtil.toURI(path);
+ IFile[] files = ResourcesPlugin.getWorkspace().getRoot().findFilesForLocationURI(uri);
+ if (files.length > 0) {
+ this.project = files[0].getProject();
+ }
+ }
+
+ /**
+ * @since 2.1
+ */
+ public IProject getProject() {
+ return project;
+ }
+
+ /**
+ * @since 2.3
+ */
+ public void setLaunch(SystemTapScriptLaunch launch){
+ this.launch = launch;
+ }
+
+ /**
+ * Finds the editor containing the target script to run, so the script can be saved
+ * when it is run, if appropriate.
+ * The script is saved when it is run with the "simple" run button on the toolbar (path == null),
+ * or if the script is outside of a project (working with a PathEditorInput).
+ */
+ private void findTargetEditor() {
+ ed = null;
+
+ if (path == null) {
+ IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
+ ed = window.getActivePage().getActiveEditor();
+ return;
+ }
+
+ for (IWorkbenchWindow window : PlatformUI.getWorkbench().getWorkbenchWindows()) {
+ IEditorPart edTest = window.getActivePage().getActiveEditor();
+ if (edTest != null && matchesEditor(edTest.getEditorInput(), edTest)) {
+ return;
+ }
+ for (IEditorReference ref : window.getActivePage().getEditorReferences()) {
+ try {
+ if (matchesEditor(ref.getEditorInput(), ref.getEditor(false))) {
+ return;
+ }
+ } catch (PartInitException e) {
+ continue;
+ }
+ }
+ }
+ }
+
+ private boolean matchesEditor(IEditorInput input, IEditorPart editor) {
+ if (input instanceof IPathEditorInput && ((IPathEditorInput) (input)).getPath().equals(this.path)) {
+ // Only save the editor when working with a file without a project (PathEditorInput),
+ // otherwise the editor isn't needed at all (saving is handled elsewhere in that case).
+ if (input instanceof PathEditorInput) {
+ this.ed = editor;
+ }
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * The main body of this event. Starts by making sure the current editor is valid to run,
+ * then builds the command line arguments for stap and retrieves the environment variables.
+ * Finally, it gets an instance of <code>ScriptConsole</code> to run the script.
+ */
+ @Override
+ public Object execute(ExecutionEvent event) throws ExecutionException {
+ findTargetEditor();
+ final boolean local = getRunLocal();
+ if(isValid()) {
+ if(!local && !prepareNonLocalScript()) {
+ return null;
+ }
+ final String[] script = buildStandardScript();
+ final String[] envVars = getEnvironmentVariables();
+ if (continueRun) {
+ Display.getDefault().asyncExec(new Runnable() {
+ @Override
+ public void run() {
+ String name = !local ? serverfileName : fileName;
+ if (ScriptConsole.instanceIsRunning(name)) {
+ MessageDialog dialog = new MessageDialog(
+ PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(),
+ Messages.RunScriptAction_alreadyRunningDialogTitle, null,
+ MessageFormat.format(Messages.RunScriptAction_alreadyRunningDialogMessage, fileName),
+ MessageDialog.QUESTION, new String[]{"Yes", "No"}, 0); //$NON-NLS-1$ //$NON-NLS-2$
+ if (dialog.open() != Window.OK) {
+ if (launch != null) {
+ launch.forceRemove();
+ }
+ return;
+ }
+ }
+ final ScriptConsole console;
+ if (!local) {
+ console = ScriptConsole.getInstance(serverfileName);
+ } else {
+ console = ScriptConsole.getInstance(fileName);
+ }
+ synchronized (console) {
+ if (!local) {
+ console.run(script, envVars, remoteOptions, new StapErrorParser());
+ } else {
+ console.runLocally(script, envVars, new StapErrorParser(), getProject());
+ }
+ scriptConsoleInitialized(console);
+ }
+ }
+ });
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ * Attempts to set up a channel for a script that runs on a non-local host or user.
+ * @return <code>true</code> on success, <code>false</code> on failure.
+ * @throws ExecutionException If failure occurs during a (non-simple) launch,
+ * this will throw an exception instead of returning <code>false</code>.
+ */
+ private boolean prepareNonLocalScript() throws ExecutionException {
+ try {
+ ScpClient scpclient = new ScpClient(remoteOptions);
+ serverfileName = fileName.substring(fileName.lastIndexOf('/')+1);
+ tmpfileName="/tmp/"+ serverfileName; //$NON-NLS-1$
+ scpclient.transfer(fileName,tmpfileName);
+ } catch (final JSchException | IOException e) {
+ final String message = e instanceof JSchException ? Localization.getString("RunScriptHandler.checkCredentials") //$NON-NLS-1$
+ : Localization.getString("RunScriptHandler.ioError"); //$NON-NLS-1$
+ if (launch == null) {
+ Display.getDefault().asyncExec(new Runnable() {
+ @Override
+ public void run() {
+ if (e instanceof JSchException) {
+ ErrorDialog.openError(PlatformUI.getWorkbench()
+ .getActiveWorkbenchWindow().getShell(),
+ Localization.getString("RunScriptHandler.serverError"), Localization.getString("RunScriptHandler.serverError"), //$NON-NLS-1$ //$NON-NLS-2$
+ new Status(IStatus.ERROR, IDEPlugin.PLUGIN_ID, message));
+ } else {
+ ExceptionErrorDialog.openError(Localization.getString("RunScriptHandler.ioError"), e); //$NON-NLS-1$
+ }
+ }
+ });
+ return false;
+ } else {
+ throw new ExecutionException(message, e);
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Once a console for running the script has been created this
+ * function is called so that observers can be added for example
+ * @param console
+ * @since 2.0
+ */
+ protected void scriptConsoleInitialized(ScriptConsole console){
+ if (launch != null && path != null) {
+ launch.setConsole(console);
+ }
+ }
+
+ /**
+ * Returns the path that was set for this action. If one was not set it
+ * returns the path of the current editor in the window this action is
+ * associated with.
+ *
+ * @return The string representation of the path of the script to run.
+ */
+ protected String getFilePath() {
+ if (path != null){
+ return path.toOSString();
+ }
+ if (ed == null) {
+ return ""; //$NON-NLS-1$
+ }
+ if(ed.getEditorInput() instanceof PathEditorInput){
+ return ((PathEditorInput)ed.getEditorInput()).getPath().toString();
+ } else {
+ return ResourceUtil.getFile(ed.getEditorInput()).getLocation().toString();
+ }
+ }
+
+ /**
+ * Checks if the current editor is operating on a file that actually exists and can be
+ * used as an argument to stap (as opposed to an unsaved buffer).
+ * @return True if the file is valid.
+ */
+ private boolean isValid() {
+ // If the path is not set this action will run the script from
+ // the active editor
+ if(!tryEditorSave()){
+ if (this.path == null){
+ Display.getDefault().asyncExec(new Runnable() {
+ @Override
+ public void run() {
+ String msg = MessageFormat.format(Localization.getString("RunScriptAction.NoScriptFile"),(Object[]) null); //$NON-NLS-1$
+ MessageDialog.openWarning(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(), Localization.getString("RunScriptAction.Problem"), msg); //$NON-NLS-1$
+ }
+ });
+ return false;
+ }
+ }
+ String filePath = this.getFilePath();
+ return filePath.endsWith(".stp") //$NON-NLS-1$
+ && isValidDirectory(filePath);
+ }
+
+ private boolean tryEditorSave() {
+ if(null == ed) {
+ return false;
+ }
+
+ if(ed.isDirty()) {
+ Display.getDefault().syncExec(new Runnable() {
+ @Override
+ public void run() {
+ ed.doSave(new ProgressMonitorPart(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(), new FillLayout()));
+ }
+ });
+ }
+
+ return true;
+ }
+
+ /**
+ * Checks whether the directory to which the given file
+ * belongs is a valid directory. Currently this function just
+ * checks if the given file does not belong to the tapset
+ * directory.
+ * @param fileName
+ * @return true if the given path is valid false otherwise.
+ * @since 1.2
+ */
+ private boolean isValidDirectory(String fileName) {
+ this.fileName = fileName;
+ if(0 == IDESessionSettings.tapsetLocation.trim().length()){
+ TapsetLibrary.getTapsetLocation(IDEPlugin.getDefault().getPreferenceStore());
+ }
+
+ if(fileName.contains(IDESessionSettings.tapsetLocation)) {
+ Display.getDefault().asyncExec(new Runnable() {
+ @Override
+ public void run() {
+ String msg = MessageFormat.format(Localization.getString("RunScriptAction.TapsetDirectoryRun"),(Object []) null); //$NON-NLS-1$
+ MessageDialog.openWarning(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(), Localization.getString("RunScriptAction.Error"), msg); //$NON-NLS-1$
+ }
+ });
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Adds the given String to the list of commands to be
+ * passed to systemtap when running the command
+ * @param option
+ */
+ public void addComandLineOptions(String option){
+ this.cmdList.add(option);
+ }
+
+ /**
+ * The command line argument generation method used by <code>RunScriptAction</code>. This generates
+ * a stap command line that includes the tapsets specified in user preferences, a guru mode flag
+ * if necessary, and the path to the script on disk.
+ * @return The command to invoke to start the script running in stap.
+ * @since 2.0
+ */
+ private String[] buildStandardScript() {
+ getImportedTapsets(cmdList);
+
+ if(isGuru()) {
+ cmdList.add("-g"); //$NON-NLS-1$
+ }
+
+ return finalizeScript(cmdList);
+ }
+
+ /**
+ * Adds the tapsets that the user has added in preferences to the input <code>ArrayList</code>
+ * @param cmdList The list to add the user-specified tapset locations to.
+ * @since 2.0
+ */
+
+ private void getImportedTapsets(List<String> cmdList) {
+ IPreferenceStore preferenceStore = IDEPlugin.getDefault().getPreferenceStore();
+ String[] tapsets = preferenceStore.getString(IDEPreferenceConstants.P_TAPSETS).split(File.pathSeparator);
+
+ //Get all imported tapsets
+ if(tapsets.length > 0 && tapsets[0].trim().length() > 0) {
+ for(int i=0; i<tapsets.length; i++) {
+ cmdList.add("-I"); //$NON-NLS-1$
+ cmdList.add(tapsets[i]);
+ }
+ }
+ }
+
+ /**
+ * Checks the current script to determine if guru mode is required in order to run. This is determined
+ * by the presence of embedded C.
+ * @return True if the script contains embedded C code.
+ */
+ private boolean isGuru() {
+ File f = new File(fileName);
+ try (FileReader fr = new FileReader(f)){
+ int curr = 0;
+ int prev = 0;
+ boolean front = false;
+ boolean imbedded = false;
+ boolean inLineComment = false;
+ boolean inBlockComment = false;
+ while(-1 != (curr = fr.read())) {
+ if(!inLineComment && !inBlockComment && '%' == prev && '{' == curr) {
+ front = true;
+ } else if(!inLineComment && !inBlockComment && '%' == prev && '}' == curr && front) {
+ imbedded = true;
+ break;
+ } else if(!inBlockComment && (('/' == prev && '/' == curr) || '#' == curr)) {
+ inLineComment = true;
+ } else if(!inLineComment && '/' == prev && '*' == curr) {
+ inBlockComment = true;
+ } else if('\n' == curr) {
+ inLineComment = false;
+ } else if('*' == prev && '/' == curr) {
+ inBlockComment = false;
+ }
+ prev = curr;
+ }
+ fr.close();
+ if(imbedded) {
+ return true;
+ }
+ } catch (FileNotFoundException fnfe) {
+ ExceptionErrorDialog.openError(Localization.getString("RunScriptHandler.couldNotOpenScriptFile"), fnfe); //$NON-NLS-1$
+ } catch (IOException ie) {
+ ExceptionErrorDialog.openError(Localization.getString("RunScriptHandler.fileIOError"), ie); //$NON-NLS-1$
+ }
+ return false;
+ }
+
+ /**
+ * Produces a <code>String[]</code> from the <code>ArrayList</code> passed in with stap inserted
+ * as the first entry, and the filename as the last entry. Used to convert the arguments generated
+ * earlier in <code>buildStandardScript</code> such as tapset locations and guru mode into an actual
+ * command line argument array that can be passed to <code>Runtime.exec</code>.
+ * @param cmdList The list of arguments for stap for this script
+ * @return An array suitable to pass to <code>Runtime.exec</code> to start stap on this file.
+ * @since 2.0
+ */
+ private String[] finalizeScript(List<String> cmdList) {
+
+ String[] script;
+
+ script = new String[cmdList.size() + 4];
+ script[0] = "stap"; //$NON-NLS-1$
+
+ if(getRunLocal() == false) {
+ script[script.length-1] = tmpfileName;
+ } else {
+ script[script.length-1] = fileName;
+ }
+
+ for(int i=0; i< cmdList.size(); i++) {
+ script[i+1] = cmdList.get(i);
+ }
+ script[script.length-3]="-m"; //$NON-NLS-1$
+
+ String modname;
+ if(getRunLocal() == false) {
+ modname = serverfileName.substring(0, serverfileName.lastIndexOf(".stp")); //$NON-NLS-1$
+ }
+ /* We need to remove the directory prefix here because in the case of
+ * running the script remotely, this is already done. Not doing so
+ * causes a modname error.
+ */
+ else {
+ modname = fileName.substring(fileName.lastIndexOf('/')+1);
+ modname = modname.substring(0, modname.lastIndexOf(".stp")); //$NON-NLS-1$
+ }
+
+ // Make sure script name only contains underscores and/or alphanumeric characters.
+ Pattern validModName = Pattern.compile("^[a-z0-9_A-Z]+$"); //$NON-NLS-1$
+ Matcher modNameMatch = validModName.matcher(modname);
+ if (!modNameMatch.matches()) {
+ continueRun = false;
+ Display.getDefault().asyncExec(new Runnable() {
+ @Override
+ public void run() {
+
+ Shell parent = PlatformUI.getWorkbench().getDisplay()
+ .getActiveShell();
+ MessageDialog.openError(parent,
+ Messages.ScriptRunAction_InvalidScriptTitle,
+ Messages.ScriptRunAction_InvalidScriptTMessage);
+ }
+ });
+ return new String[0];
+ }
+
+ script[script.length-2]=modname;
+ return script;
+ }
+
+ private String[] getEnvironmentVariables() {
+ return EnvironmentVariablesPreferencePage.getEnvironmentVariables();
+ }
+
+ @Override
+ public boolean isEnabled() {
+ return (PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().getActiveEditor() instanceof STPEditor);
+ }
+
+ /**
+ * Set the options for running the script remotely. If the script is to be run locally,
+ * pass <code>null</code> as the only parameter.
+ * @param remoteOptions The remote options of the script run, or <code>null</code> if the script
+ * is to be run locally.
+ * @since 3.0
+ */
+ public void setRemoteScriptOptions(RemoteScriptOptions remoteOptions) {
+ this.remoteOptions = remoteOptions;
+ }
+
+ private boolean getRunLocal() {
+ return remoteOptions == null;
+ }
+
+ @Override
+ public void addHandlerListener(IHandlerListener handlerListener) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void removeHandlerListener(IHandlerListener handlerListener) {
+ // TODO Auto-generated method stub
+
+ }
}
diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/actions/ToggleCommentHandler.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/actions/ToggleCommentHandler.java
index 6a10a253ae..d1021ceae7 100644
--- a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/actions/ToggleCommentHandler.java
+++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/actions/ToggleCommentHandler.java
@@ -37,273 +37,273 @@ import org.eclipse.ui.texteditor.ITextEditor;
*/
public class ToggleCommentHandler extends AbstractHandler {
- /** The text operation target */
- private ITextOperationTarget operationTarget;
-
- /**
- * Checks if the selected lines are all commented or not and
- * uncomments/comments them respectively.
- */
- @Override
- public Object execute(ExecutionEvent event) {
- ITextEditor editor = (ITextEditor) HandlerUtil.getActiveEditor(event);
- if (editor == null || !editor.isEditable()) {
- return null;
- }
-
- updateOpTarget(editor);
- if (operationTarget == null) {
- return null;
- }
-
- ISelection selection = editor.getSelectionProvider().getSelection();
- IDocument document = editor.getDocumentProvider().getDocument(
- editor.getEditorInput());
-
- final int operationCode;
- if (isSelectionCommented(selection, document)) {
- operationCode = ITextOperationTarget.STRIP_PREFIX;
- } else {
- operationCode = ITextOperationTarget.PREFIX;
- }
-
- Shell shell = editor.getSite().getShell();
- if (!operationTarget.canDoOperation(operationCode)) {
- if (shell != null) {
- MessageDialog.openError(shell,
- Localization.getString("ToggleComment_error_title"), //$NON-NLS-1$
- Localization.getString("ToggleComment_error_message")); //$NON-NLS-1$
- }
- return null;
- }
-
- Display display = null;
- if (shell != null && !shell.isDisposed()) {
- display = shell.getDisplay();
- }
-
- BusyIndicator.showWhile(display, new Runnable() {
- @Override
- public void run() {
- operationTarget.doOperation(operationCode);
- }
- });
-
- return null;
- }
-
- /**
- * Creates a region describing the text block (something that starts at the
- * beginning of a line) completely containing the current selection.
- *
- * Note, the implementation has to match org.eclipse.jface.text.TextViewer;
- * .getTextBlockFromSelection().
- *
- * @param selection The selection to use
- * @param document The document
- * @return the region describing the text block comprising the given
- * selection
- * @throws BadLocationException
- */
- public IRegion getTextBlockFromSelection(ITextSelection selection,
- IDocument document) throws BadLocationException {
- int start = document.getLineOffset(selection.getStartLine());
- int end;
- int endLine = selection.getEndLine();
- if (document.getNumberOfLines() > endLine + 1) {
- end = document.getLineOffset(endLine + 1);
- } else {
- end = document.getLength();
- }
- return new Region(start, end - start);
- }
-
- /**
- * Is the given selection on the specified document single-line commented?
- *
- * @param selection Selection to check
- * @param document The document
- * @return <code>true</code> iff all selected lines are commented
- */
- public boolean isSelectionCommented(ISelection selection,
- IDocument document) {
-
- if (!(selection instanceof ITextSelection)) {
- return false;
- }
-
- ITextSelection textSelection = (ITextSelection) selection;
- if (textSelection.getStartLine() < 0 || textSelection.getEndLine() < 0) {
- return false;
- }
-
- try {
- IRegion block = getTextBlockFromSelection(textSelection, document);
- ITypedRegion[] regions = TextUtilities.computePartitioning(
- document, STPPartitionScanner.STP_PARTITIONING,
- block.getOffset(), block.getLength(), false);
-
- int[] lines = new int[regions.length * 2]; // [startline, endline,
- // startline, endline,
- // ...]
-
- // For each partition in the text selection, figure out the
- // startline and endline.
- // Count the number of lines that are selected.
- for (int i = 0, j = 0; i < regions.length; i++, j += 2) {
- // Start line of region
- lines[j] = getFirstCompleteLineOfRegion(regions[i], document);
- // End line of region
- int length = regions[i].getLength();
- int offset = regions[i].getOffset() + length;
- if (length > 0) {
- offset--;
- }
-
- // If there is no startline for this region (startline = -1),
- // then there is no endline,
- // otherwise, get the line number of the endline and store it in
- // the array.
- lines[j + 1] = (lines[j] == -1 ? -1 : document
- .getLineOfOffset(offset));
-
- assert i < regions.length;
- assert j < regions.length * 2;
- }
-
- // Perform the check
- boolean hasComment = false;
- for (int i = 0, j = 0; i < regions.length; i++, j += 2) {
- String prefix = "//"; //$NON-NLS-1$
- if (lines[j] >= 0 && lines[j + 1] >= 0) {
- if (isBlockCommented(lines[j], lines[j + 1], prefix,
- document)) {
- hasComment = true;
- } else if (!isBlockEmpty(lines[j], lines[j + 1], document)) {
- return false;
- }
- }
- }
- return hasComment;
- } catch (BadLocationException e) {
- ExceptionErrorDialog.openError(e.getLocalizedMessage(), e);
- }
-
- return false;
- }
-
- /**
- * Returns the index of the first line whose start offset is in the given
- * text range.
- *
- * @param region the text range in characters where to find the line
- * @param document The document
- * @return the first line whose start index is in the given range, -1 if
- * there is no such line
- */
- public int getFirstCompleteLineOfRegion(IRegion region, IDocument document) {
- try {
- int startLine = document.getLineOfOffset(region.getOffset());
-
- int offset = document.getLineOffset(startLine);
- if (offset >= region.getOffset()) {
- return startLine;
- }
-
- offset = document.getLineOffset(startLine + 1);
- return (offset > region.getOffset() + region.getLength() ? -1
- : startLine + 1);
- } catch (BadLocationException e) {
- ExceptionErrorDialog.openError(e.getLocalizedMessage(), e);
- }
-
- return -1;
- }
-
- /**
- * Determines whether each line is empty
- *
- * @param startLine Start line in document
- * @param endLine End line in document
- * @param document The document
- * @return <code>true</code> if each line from <code>startLine</code> to and
- * including <code>endLine</code> is empty
- */
- public boolean isBlockEmpty(int startLine, int endLine, IDocument document) {
- try {
- for (int i = startLine; i <= endLine; i++) {
- IRegion line = document.getLineInformation(i);
- String text = document.get(line.getOffset(), line.getLength());
-
- boolean isEmptyLine = text.trim().length() == 0;
- if (!isEmptyLine) {
- return false;
- }
- }
- return true;
- } catch (BadLocationException e) {
- ExceptionErrorDialog.openError(e.getLocalizedMessage(), e);
- }
-
- return false;
- }
-
- /**
- * Determines whether each line is prefixed by one of the prefixes.
- *
- * @param startLine Start line in document
- * @param endLine End line in document
- * @param prefix Comment prefix
- * @param document The document
- * @return <code>true</code> iff each line from <code>startLine</code> to
- * and including <code>endLine</code> is prepended by the
- * <code>prefix</code>, ignoring whitespace at the begin of line
- */
- public boolean isBlockCommented(int startLine, int endLine, String prefix,
- IDocument document) {
- try {
- // Check for occurrences of prefixes in the given lines
- boolean hasComment = false;
- for (int i = startLine; i <= endLine; i++) {
- IRegion line = document.getLineInformation(i);
- String text = document.get(line.getOffset(), line.getLength());
-
- boolean isEmptyLine = text.trim().length() == 0;
- if (isEmptyLine) {
- continue;
- }
-
- int prefixIndex = text.indexOf(prefix, 0);
-
- if (prefixIndex == -1) {
- // Found a line which is not commented
- return false;
- }
- String s = document.get(line.getOffset(), prefixIndex);
- s = s.trim();
- if (s.length() != 0) {
- // Found a line which is not commented
- return false;
- }
- hasComment = true;
- }
- return hasComment;
- } catch (BadLocationException e) {
- ExceptionErrorDialog.openError(e.getLocalizedMessage(), e);
- }
-
- return false;
- }
-
- /**
- * Update text operation target based on the specified text editor.
- *
- * @param editor ITextEditor editor to associate operation target to.
- */
- private void updateOpTarget(ITextEditor editor) {
- if (editor != null) {
- operationTarget = (ITextOperationTarget) editor
- .getAdapter(ITextOperationTarget.class);
- }
- }
+ /** The text operation target */
+ private ITextOperationTarget operationTarget;
+
+ /**
+ * Checks if the selected lines are all commented or not and
+ * uncomments/comments them respectively.
+ */
+ @Override
+ public Object execute(ExecutionEvent event) {
+ ITextEditor editor = (ITextEditor) HandlerUtil.getActiveEditor(event);
+ if (editor == null || !editor.isEditable()) {
+ return null;
+ }
+
+ updateOpTarget(editor);
+ if (operationTarget == null) {
+ return null;
+ }
+
+ ISelection selection = editor.getSelectionProvider().getSelection();
+ IDocument document = editor.getDocumentProvider().getDocument(
+ editor.getEditorInput());
+
+ final int operationCode;
+ if (isSelectionCommented(selection, document)) {
+ operationCode = ITextOperationTarget.STRIP_PREFIX;
+ } else {
+ operationCode = ITextOperationTarget.PREFIX;
+ }
+
+ Shell shell = editor.getSite().getShell();
+ if (!operationTarget.canDoOperation(operationCode)) {
+ if (shell != null) {
+ MessageDialog.openError(shell,
+ Localization.getString("ToggleComment_error_title"), //$NON-NLS-1$
+ Localization.getString("ToggleComment_error_message")); //$NON-NLS-1$
+ }
+ return null;
+ }
+
+ Display display = null;
+ if (shell != null && !shell.isDisposed()) {
+ display = shell.getDisplay();
+ }
+
+ BusyIndicator.showWhile(display, new Runnable() {
+ @Override
+ public void run() {
+ operationTarget.doOperation(operationCode);
+ }
+ });
+
+ return null;
+ }
+
+ /**
+ * Creates a region describing the text block (something that starts at the
+ * beginning of a line) completely containing the current selection.
+ *
+ * Note, the implementation has to match org.eclipse.jface.text.TextViewer;
+ * .getTextBlockFromSelection().
+ *
+ * @param selection The selection to use
+ * @param document The document
+ * @return the region describing the text block comprising the given
+ * selection
+ * @throws BadLocationException
+ */
+ public IRegion getTextBlockFromSelection(ITextSelection selection,
+ IDocument document) throws BadLocationException {
+ int start = document.getLineOffset(selection.getStartLine());
+ int end;
+ int endLine = selection.getEndLine();
+ if (document.getNumberOfLines() > endLine + 1) {
+ end = document.getLineOffset(endLine + 1);
+ } else {
+ end = document.getLength();
+ }
+ return new Region(start, end - start);
+ }
+
+ /**
+ * Is the given selection on the specified document single-line commented?
+ *
+ * @param selection Selection to check
+ * @param document The document
+ * @return <code>true</code> iff all selected lines are commented
+ */
+ public boolean isSelectionCommented(ISelection selection,
+ IDocument document) {
+
+ if (!(selection instanceof ITextSelection)) {
+ return false;
+ }
+
+ ITextSelection textSelection = (ITextSelection) selection;
+ if (textSelection.getStartLine() < 0 || textSelection.getEndLine() < 0) {
+ return false;
+ }
+
+ try {
+ IRegion block = getTextBlockFromSelection(textSelection, document);
+ ITypedRegion[] regions = TextUtilities.computePartitioning(
+ document, STPPartitionScanner.STP_PARTITIONING,
+ block.getOffset(), block.getLength(), false);
+
+ int[] lines = new int[regions.length * 2]; // [startline, endline,
+ // startline, endline,
+ // ...]
+
+ // For each partition in the text selection, figure out the
+ // startline and endline.
+ // Count the number of lines that are selected.
+ for (int i = 0, j = 0; i < regions.length; i++, j += 2) {
+ // Start line of region
+ lines[j] = getFirstCompleteLineOfRegion(regions[i], document);
+ // End line of region
+ int length = regions[i].getLength();
+ int offset = regions[i].getOffset() + length;
+ if (length > 0) {
+ offset--;
+ }
+
+ // If there is no startline for this region (startline = -1),
+ // then there is no endline,
+ // otherwise, get the line number of the endline and store it in
+ // the array.
+ lines[j + 1] = (lines[j] == -1 ? -1 : document
+ .getLineOfOffset(offset));
+
+ assert i < regions.length;
+ assert j < regions.length * 2;
+ }
+
+ // Perform the check
+ boolean hasComment = false;
+ for (int i = 0, j = 0; i < regions.length; i++, j += 2) {
+ String prefix = "//"; //$NON-NLS-1$
+ if (lines[j] >= 0 && lines[j + 1] >= 0) {
+ if (isBlockCommented(lines[j], lines[j + 1], prefix,
+ document)) {
+ hasComment = true;
+ } else if (!isBlockEmpty(lines[j], lines[j + 1], document)) {
+ return false;
+ }
+ }
+ }
+ return hasComment;
+ } catch (BadLocationException e) {
+ ExceptionErrorDialog.openError(e.getLocalizedMessage(), e);
+ }
+
+ return false;
+ }
+
+ /**
+ * Returns the index of the first line whose start offset is in the given
+ * text range.
+ *
+ * @param region the text range in characters where to find the line
+ * @param document The document
+ * @return the first line whose start index is in the given range, -1 if
+ * there is no such line
+ */
+ public int getFirstCompleteLineOfRegion(IRegion region, IDocument document) {
+ try {
+ int startLine = document.getLineOfOffset(region.getOffset());
+
+ int offset = document.getLineOffset(startLine);
+ if (offset >= region.getOffset()) {
+ return startLine;
+ }
+
+ offset = document.getLineOffset(startLine + 1);
+ return (offset > region.getOffset() + region.getLength() ? -1
+ : startLine + 1);
+ } catch (BadLocationException e) {
+ ExceptionErrorDialog.openError(e.getLocalizedMessage(), e);
+ }
+
+ return -1;
+ }
+
+ /**
+ * Determines whether each line is empty
+ *
+ * @param startLine Start line in document
+ * @param endLine End line in document
+ * @param document The document
+ * @return <code>true</code> if each line from <code>startLine</code> to and
+ * including <code>endLine</code> is empty
+ */
+ public boolean isBlockEmpty(int startLine, int endLine, IDocument document) {
+ try {
+ for (int i = startLine; i <= endLine; i++) {
+ IRegion line = document.getLineInformation(i);
+ String text = document.get(line.getOffset(), line.getLength());
+
+ boolean isEmptyLine = text.trim().length() == 0;
+ if (!isEmptyLine) {
+ return false;
+ }
+ }
+ return true;
+ } catch (BadLocationException e) {
+ ExceptionErrorDialog.openError(e.getLocalizedMessage(), e);
+ }
+
+ return false;
+ }
+
+ /**
+ * Determines whether each line is prefixed by one of the prefixes.
+ *
+ * @param startLine Start line in document
+ * @param endLine End line in document
+ * @param prefix Comment prefix
+ * @param document The document
+ * @return <code>true</code> iff each line from <code>startLine</code> to
+ * and including <code>endLine</code> is prepended by the
+ * <code>prefix</code>, ignoring whitespace at the begin of line
+ */
+ public boolean isBlockCommented(int startLine, int endLine, String prefix,
+ IDocument document) {
+ try {
+ // Check for occurrences of prefixes in the given lines
+ boolean hasComment = false;
+ for (int i = startLine; i <= endLine; i++) {
+ IRegion line = document.getLineInformation(i);
+ String text = document.get(line.getOffset(), line.getLength());
+
+ boolean isEmptyLine = text.trim().length() == 0;
+ if (isEmptyLine) {
+ continue;
+ }
+
+ int prefixIndex = text.indexOf(prefix, 0);
+
+ if (prefixIndex == -1) {
+ // Found a line which is not commented
+ return false;
+ }
+ String s = document.get(line.getOffset(), prefixIndex);
+ s = s.trim();
+ if (s.length() != 0) {
+ // Found a line which is not commented
+ return false;
+ }
+ hasComment = true;
+ }
+ return hasComment;
+ } catch (BadLocationException e) {
+ ExceptionErrorDialog.openError(e.getLocalizedMessage(), e);
+ }
+
+ return false;
+ }
+
+ /**
+ * Update text operation target based on the specified text editor.
+ *
+ * @param editor ITextEditor editor to associate operation target to.
+ */
+ private void updateOpTarget(ITextEditor editor) {
+ if (editor != null) {
+ operationTarget = (ITextOperationTarget) editor
+ .getAdapter(ITextOperationTarget.class);
+ }
+ }
}
diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/actions/TreeExpandCollapseAction.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/actions/TreeExpandCollapseAction.java
index 430f96cb05..4ff0e2ae5e 100644
--- a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/actions/TreeExpandCollapseAction.java
+++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/actions/TreeExpandCollapseAction.java
@@ -28,67 +28,67 @@ import org.eclipse.ui.PlatformUI;
* @author Ryan Morse
*/
public class TreeExpandCollapseAction extends Action implements
- ISelectionListener {
- private final IWorkbenchWindow fWindow;
- private IStructuredSelection selection;
- private final BrowserView viewer;
+ ISelectionListener {
+ private final IWorkbenchWindow fWindow;
+ private IStructuredSelection selection;
+ private final BrowserView viewer;
- /**
- * The default constructor. Takes a <code>Class</code> representing the viewer that it is to expand
- * or collapse, as there is only one in the workbench at a time.
- * @param cls <code>Class</code> of the viewer to expand/collapse
- */
- public TreeExpandCollapseAction(BrowserView view) {
- super();
- fWindow = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
- fWindow.getSelectionService().addSelectionListener(this);
- this.viewer = view;
- }
+ /**
+ * The default constructor. Takes a <code>Class</code> representing the viewer that it is to expand
+ * or collapse, as there is only one in the workbench at a time.
+ * @param cls <code>Class</code> of the viewer to expand/collapse
+ */
+ public TreeExpandCollapseAction(BrowserView view) {
+ super();
+ fWindow = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
+ fWindow.getSelectionService().addSelectionListener(this);
+ this.viewer = view;
+ }
- /**
- * Updates <code>selection</code> with the current selection whenever the user changes
- * the current selection.
- */
- @Override
- public void selectionChanged(IWorkbenchPart part, ISelection incoming) {
- if (incoming instanceof IStructuredSelection) {
- selection = (IStructuredSelection) incoming;
- setEnabled(selection.size() == 1);
- } else {
- // Other selections, for example containing text or of other kinds.
- setEnabled(false);
- }
- }
+ /**
+ * Updates <code>selection</code> with the current selection whenever the user changes
+ * the current selection.
+ */
+ @Override
+ public void selectionChanged(IWorkbenchPart part, ISelection incoming) {
+ if (incoming instanceof IStructuredSelection) {
+ selection = (IStructuredSelection) incoming;
+ setEnabled(selection.size() == 1);
+ } else {
+ // Other selections, for example containing text or of other kinds.
+ setEnabled(false);
+ }
+ }
- public void dispose() {
- fWindow.getSelectionService().removeSelectionListener(this);
- }
+ public void dispose() {
+ fWindow.getSelectionService().removeSelectionListener(this);
+ }
- /**
- * The main body of the action. Expands or Collapses the viewer specified at construction to
- * the level of the current selection.
- */
- @Override
- public void run() {
- ISelection incoming = viewer.getViewer().getSelection();
- IStructuredSelection selection = (IStructuredSelection)incoming;
- Object o = selection.getFirstElement();
+ /**
+ * The main body of the action. Expands or Collapses the viewer specified at construction to
+ * the level of the current selection.
+ */
+ @Override
+ public void run() {
+ ISelection incoming = viewer.getViewer().getSelection();
+ IStructuredSelection selection = (IStructuredSelection)incoming;
+ Object o = selection.getFirstElement();
- if(o == null) {
- return;
- }
+ if(o == null) {
+ return;
+ }
- Object[] objs = viewer.getViewer().getVisibleExpandedElements();
- boolean doExpand = true;
+ Object[] objs = viewer.getViewer().getVisibleExpandedElements();
+ boolean doExpand = true;
- for(int i = 0; i < objs.length; i++)
- if(objs[i] == o)
- doExpand = false;
+ for(int i = 0; i < objs.length; i++)
+ if(objs[i] == o)
+ doExpand = false;
- if(doExpand) {
- viewer.getViewer().expandToLevel(o,1);
- } else {
- viewer.getViewer().collapseToLevel(o,1);
- }
- }
+ if(doExpand) {
+ viewer.getViewer().expandToLevel(o,1);
+ } else {
+ viewer.getViewer().collapseToLevel(o,1);
+ }
+ }
}
diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/CodeFormatterUtil.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/CodeFormatterUtil.java
index 59ae5b77c0..eb8df0add8 100644
--- a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/CodeFormatterUtil.java
+++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/CodeFormatterUtil.java
@@ -13,12 +13,12 @@ package org.eclipse.linuxtools.internal.systemtap.ui.ide.editors.stp;
public class CodeFormatterUtil {
- public static int getTabWidth() {
- return 4;
- }
+ public static int getTabWidth() {
+ return 4;
+ }
- public static int getIndentWidth() {
- return 4;
- }
+ public static int getIndentWidth() {
+ return 4;
+ }
}
diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/DocumentCharacterIterator.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/DocumentCharacterIterator.java
index ea027dcad2..92e8df3fc6 100644
--- a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/DocumentCharacterIterator.java
+++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/DocumentCharacterIterator.java
@@ -32,215 +32,215 @@ import org.eclipse.jface.text.IDocument;
*/
public class DocumentCharacterIterator implements CharacterIterator, CharSequence {
- private int fIndex= -1;
- private final IDocument fDocument;
- private final int fFirst;
- private final int fLast;
-
- private void invariant() {
- Assert.isTrue(fIndex >= fFirst);
- Assert.isTrue(fIndex <= fLast);
- }
-
- /**
- * Creates an iterator for the entire document.
- *
- * @param document the document backing this iterator
- */
- public DocumentCharacterIterator(IDocument document) {
- this(document, 0);
- }
-
- /**
- * Creates an iterator, starting at offset <code>first</code>.
- *
- * @param document the document backing this iterator
- * @param first the first character to consider
- * @throws IllegalArgumentException if the indices are out of bounds
- */
- public DocumentCharacterIterator(IDocument document, int first) {
- this(document, first, document.getLength());
- }
-
- /**
- * Creates an iterator for the document contents from <code>first</code>
- * (inclusive) to <code>last</code> (exclusive).
- *
- * @param document the document backing this iterator
- * @param first the first character to consider
- * @param last the last character index to consider
- * @throws IllegalArgumentException if the indices are out of bounds
- */
- public DocumentCharacterIterator(IDocument document, int first, int last) {
- if (document == null)
- throw new NullPointerException();
- if (first < 0 || first > last)
- throw new IllegalArgumentException();
- if (last > document.getLength())
- throw new IllegalArgumentException();
- fDocument= document;
- fFirst= first;
- fLast= last;
- fIndex= first;
- invariant();
- }
-
- /*
- * @see java.text.CharacterIterator#first()
- */
- @Override
- public char first() {
- return setIndex(getBeginIndex());
- }
-
- /*
- * @see java.text.CharacterIterator#last()
- */
- @Override
- public char last() {
- if (fFirst == fLast)
- return setIndex(getEndIndex());
- return setIndex(getEndIndex() - 1);
- }
-
- /*
- * @see java.text.CharacterIterator#current()
- */
- @Override
- public char current() {
- if (fIndex >= fFirst && fIndex < fLast)
- try {
- return fDocument.getChar(fIndex);
- } catch (BadLocationException e) {
- // ignore
- }
- return DONE;
- }
-
- /*
- * @see java.text.CharacterIterator#next()
- */
- @Override
- public char next() {
- return setIndex(Math.min(fIndex + 1, getEndIndex()));
- }
-
- /*
- * @see java.text.CharacterIterator#previous()
- */
- @Override
- public char previous() {
- if (fIndex > getBeginIndex()) {
- return setIndex(fIndex - 1);
- }
- return DONE;
- }
-
- /*
- * @see java.text.CharacterIterator#setIndex(int)
- */
- @Override
- public char setIndex(int position) {
- if (position >= getBeginIndex() && position <= getEndIndex())
- fIndex= position;
- else
- throw new IllegalArgumentException();
-
- invariant();
- return current();
- }
-
- /*
- * @see java.text.CharacterIterator#getBeginIndex()
- */
- @Override
- public int getBeginIndex() {
- return fFirst;
- }
-
- /*
- * @see java.text.CharacterIterator#getEndIndex()
- */
- @Override
- public int getEndIndex() {
- return fLast;
- }
-
- /*
- * @see java.text.CharacterIterator#getIndex()
- */
- @Override
- public int getIndex() {
- return fIndex;
- }
-
- /*
- * @see java.text.CharacterIterator#clone()
- */
- @Override
- public Object clone() {
- try {
- return super.clone();
- } catch (CloneNotSupportedException e) {
- throw new InternalError();
- }
- }
-
- /*
- * @see java.lang.CharSequence#length()
- */
- @Override
- public int length() {
- return getEndIndex() - getBeginIndex();
- }
-
- /**
- * {@inheritDoc}
- * <p>
- * Note that, if the document is modified concurrently, this method may
- * return {@link CharacterIterator#DONE} if a {@link BadLocationException}
- * was thrown when accessing the backing document.
- * </p>
- *
- * @param index {@inheritDoc}
- * @return {@inheritDoc}
- */
- @Override
- public char charAt(int index) {
- if (index >= 0 && index < length())
- try {
- return fDocument.getChar(getBeginIndex() + index);
- } catch (BadLocationException e) {
- // ignore and return DONE
- return DONE;
- }
- throw new IndexOutOfBoundsException();
- }
-
- /*
- * @see java.lang.CharSequence#subSequence(int, int)
- */
- @Override
- public CharSequence subSequence(int start, int end) {
- if (start < 0)
- throw new IndexOutOfBoundsException();
- if (end < start)
- throw new IndexOutOfBoundsException();
- if (end > length())
- throw new IndexOutOfBoundsException();
- return new DocumentCharacterIterator(fDocument, getBeginIndex() + start, getBeginIndex() + end);
- }
-
- /*
- * @see java.lang.CharSequence#toString()
- */
- @Override
- public String toString() {
- int length = length();
- char[] chs = new char[length];
- for (int i=0; i<length; ++i) {
- chs[i] = charAt(i);
- }
- return new String(chs);
- }
+ private int fIndex= -1;
+ private final IDocument fDocument;
+ private final int fFirst;
+ private final int fLast;
+
+ private void invariant() {
+ Assert.isTrue(fIndex >= fFirst);
+ Assert.isTrue(fIndex <= fLast);
+ }
+
+ /**
+ * Creates an iterator for the entire document.
+ *
+ * @param document the document backing this iterator
+ */
+ public DocumentCharacterIterator(IDocument document) {
+ this(document, 0);
+ }
+
+ /**
+ * Creates an iterator, starting at offset <code>first</code>.
+ *
+ * @param document the document backing this iterator
+ * @param first the first character to consider
+ * @throws IllegalArgumentException if the indices are out of bounds
+ */
+ public DocumentCharacterIterator(IDocument document, int first) {
+ this(document, first, document.getLength());
+ }
+
+ /**
+ * Creates an iterator for the document contents from <code>first</code>
+ * (inclusive) to <code>last</code> (exclusive).
+ *
+ * @param document the document backing this iterator
+ * @param first the first character to consider
+ * @param last the last character index to consider
+ * @throws IllegalArgumentException if the indices are out of bounds
+ */
+ public DocumentCharacterIterator(IDocument document, int first, int last) {
+ if (document == null)
+ throw new NullPointerException();
+ if (first < 0 || first > last)
+ throw new IllegalArgumentException();
+ if (last > document.getLength())
+ throw new IllegalArgumentException();
+ fDocument= document;
+ fFirst= first;
+ fLast= last;
+ fIndex= first;
+ invariant();
+ }
+
+ /*
+ * @see java.text.CharacterIterator#first()
+ */
+ @Override
+ public char first() {
+ return setIndex(getBeginIndex());
+ }
+
+ /*
+ * @see java.text.CharacterIterator#last()
+ */
+ @Override
+ public char last() {
+ if (fFirst == fLast)
+ return setIndex(getEndIndex());
+ return setIndex(getEndIndex() - 1);
+ }
+
+ /*
+ * @see java.text.CharacterIterator#current()
+ */
+ @Override
+ public char current() {
+ if (fIndex >= fFirst && fIndex < fLast)
+ try {
+ return fDocument.getChar(fIndex);
+ } catch (BadLocationException e) {
+ // ignore
+ }
+ return DONE;
+ }
+
+ /*
+ * @see java.text.CharacterIterator#next()
+ */
+ @Override
+ public char next() {
+ return setIndex(Math.min(fIndex + 1, getEndIndex()));
+ }
+
+ /*
+ * @see java.text.CharacterIterator#previous()
+ */
+ @Override
+ public char previous() {
+ if (fIndex > getBeginIndex()) {
+ return setIndex(fIndex - 1);
+ }
+ return DONE;
+ }
+
+ /*
+ * @see java.text.CharacterIterator#setIndex(int)
+ */
+ @Override
+ public char setIndex(int position) {
+ if (position >= getBeginIndex() && position <= getEndIndex())
+ fIndex= position;
+ else
+ throw new IllegalArgumentException();
+
+ invariant();
+ return current();
+ }
+
+ /*
+ * @see java.text.CharacterIterator#getBeginIndex()
+ */
+ @Override
+ public int getBeginIndex() {
+ return fFirst;
+ }
+
+ /*
+ * @see java.text.CharacterIterator#getEndIndex()
+ */
+ @Override
+ public int getEndIndex() {
+ return fLast;
+ }
+
+ /*
+ * @see java.text.CharacterIterator#getIndex()
+ */
+ @Override
+ public int getIndex() {
+ return fIndex;
+ }
+
+ /*
+ * @see java.text.CharacterIterator#clone()
+ */
+ @Override
+ public Object clone() {
+ try {
+ return super.clone();
+ } catch (CloneNotSupportedException e) {
+ throw new InternalError();
+ }
+ }
+
+ /*
+ * @see java.lang.CharSequence#length()
+ */
+ @Override
+ public int length() {
+ return getEndIndex() - getBeginIndex();
+ }
+
+ /**
+ * {@inheritDoc}
+ * <p>
+ * Note that, if the document is modified concurrently, this method may
+ * return {@link CharacterIterator#DONE} if a {@link BadLocationException}
+ * was thrown when accessing the backing document.
+ * </p>
+ *
+ * @param index {@inheritDoc}
+ * @return {@inheritDoc}
+ */
+ @Override
+ public char charAt(int index) {
+ if (index >= 0 && index < length())
+ try {
+ return fDocument.getChar(getBeginIndex() + index);
+ } catch (BadLocationException e) {
+ // ignore and return DONE
+ return DONE;
+ }
+ throw new IndexOutOfBoundsException();
+ }
+
+ /*
+ * @see java.lang.CharSequence#subSequence(int, int)
+ */
+ @Override
+ public CharSequence subSequence(int start, int end) {
+ if (start < 0)
+ throw new IndexOutOfBoundsException();
+ if (end < start)
+ throw new IndexOutOfBoundsException();
+ if (end > length())
+ throw new IndexOutOfBoundsException();
+ return new DocumentCharacterIterator(fDocument, getBeginIndex() + start, getBeginIndex() + end);
+ }
+
+ /*
+ * @see java.lang.CharSequence#toString()
+ */
+ @Override
+ public String toString() {
+ int length = length();
+ char[] chs = new char[length];
+ for (int i=0; i<length; ++i) {
+ chs[i] = charAt(i);
+ }
+ return new String(chs);
+ }
}
diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/IndentUtil.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/IndentUtil.java
index e7da786141..15d6e125ea 100644
--- a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/IndentUtil.java
+++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/IndentUtil.java
@@ -27,301 +27,301 @@ import org.eclipse.jface.text.source.ILineRange;
*/
public final class IndentUtil {
- private static final String SLASHES= "//"; //$NON-NLS-1$
-
- /**
- * The result of an indentation operation. The result may be passed to
- * subsequent calls to
- * {@link IndentUtil#indentLines(IDocument, ILineRange, IProject, IndentUtil.IndentResult) indentLines}
- * to obtain consistent results with respect to the indentation of
- * line-comments.
- */
- public static final class IndentResult {
- private IndentResult(boolean[] commentLines) {
- commentLinesAtColumnZero= commentLines;
- }
- private boolean[] commentLinesAtColumnZero;
- }
-
- private IndentUtil() {
- // do not instantiate
- }
-
- /**
- * Indents the line range specified by <code>lines</code> in
- * <code>document</code>. The passed C project may be
- * <code>null</code>, it is used solely to obtain formatter preferences.
- *
- * @param document the document to be changed
- * @param lines the line range to be indented
- * @param project the C project to get the formatter preferences from, or
- * <code>null</code> if global preferences should be used
- * @param result the result from a previous call to <code>indentLines</code>,
- * in order to maintain comment line properties, or <code>null</code>.
- * Note that the passed result may be changed by the call.
- * @return an indent result that may be queried for changes and can be
- * reused in subsequent indentation operations
- * @throws BadLocationException if <code>lines</code> is not a valid line
- * range on <code>document</code>
- */
- public static IndentResult indentLines(IDocument document, ILineRange lines, IProject project, IndentResult result) throws BadLocationException {
- int numberOfLines= lines.getNumberOfLines();
-
- if (numberOfLines < 1)
- return new IndentResult(null);
-
- result= reuseOrCreateToken(result, numberOfLines);
-
- STPHeuristicScanner scanner= new STPHeuristicScanner(document);
- STPIndenter indenter= new STPIndenter(document, scanner, project);
- boolean indentInsideLineComments= true;
- for (int line= lines.getStartLine(), last= line + numberOfLines, i= 0; line < last; line++) {
- indentLine(document, line, indenter, scanner, result.commentLinesAtColumnZero, i++, indentInsideLineComments);
- }
-
- return result;
- }
-
- /**
- * Returns the indentation of the line <code>line</code> in <code>document</code>.
- * The returned string may contain pairs of leading slashes that are considered
- * part of the indentation.
- *
- * @param document the document
- * @param line the line
- * @param indentInsideLineComments option whether to indent inside line comments starting at column 0
- * @return the indentation of <code>line</code> in <code>document</code>
- * @throws BadLocationException if the document is changed concurrently
- */
- public static String getCurrentIndent(IDocument document, int line, boolean indentInsideLineComments) throws BadLocationException {
- IRegion region= document.getLineInformation(line);
- int from= region.getOffset();
- int endOffset= region.getOffset() + region.getLength();
-
- int to= from;
- if (indentInsideLineComments) {
- // go behind line comments
- while (to < endOffset - 2 && document.get(to, 2).equals(SLASHES))
- to += 2;
- }
-
- while (to < endOffset) {
- char ch= document.getChar(to);
- if (!Character.isWhitespace(ch))
- break;
- to++;
- }
-
- return document.get(from, to - from);
- }
-
- private static IndentResult reuseOrCreateToken(IndentResult token, int numberOfLines) {
- if (token == null)
- token= new IndentResult(new boolean[numberOfLines]);
- else if (token.commentLinesAtColumnZero == null)
- token.commentLinesAtColumnZero= new boolean[numberOfLines];
- else if (token.commentLinesAtColumnZero.length != numberOfLines) {
- boolean[] commentBooleans= new boolean[numberOfLines];
- System.arraycopy(token.commentLinesAtColumnZero, 0, commentBooleans, 0, Math.min(numberOfLines, token.commentLinesAtColumnZero.length));
- token.commentLinesAtColumnZero= commentBooleans;
- }
- return token;
- }
-
- /**
- * Indents a single line using the heuristic scanner. Multiline comments are
- * indented as specified by the <code>CCommentAutoIndentStrategy</code>.
- *
- * @param document the document
- * @param line the line to be indented
- * @param indenter the C indenter
- * @param scanner the heuristic scanner
- * @param commentLines the indent token comment booleans
- * @param lineIndex the zero-based line index
- * @param indentInsideLineComments option whether to indent inside line comments
- * starting at column 0
- * @throws BadLocationException if the document got changed concurrently
- */
- private static void indentLine(IDocument document, int line, STPIndenter indenter,
- STPHeuristicScanner scanner, boolean[] commentLines, int lineIndex,
- boolean indentInsideLineComments) throws BadLocationException {
- IRegion currentLine= document.getLineInformation(line);
- final int offset= currentLine.getOffset();
- int wsStart= offset; // where we start searching for non-WS; after the "//" in single line comments
-
- String indent= null;
- if (offset < document.getLength()) {
- ITypedRegion partition= TextUtilities.getPartition(document, STPPartitionScanner.STP_PARTITIONING, offset, true);
- ITypedRegion startingPartition= TextUtilities.getPartition(document, STPPartitionScanner.STP_PARTITIONING, offset, false);
- String type= partition.getType();
- if (type.equals(STPPartitionScanner.STP_MULTILINE_COMMENT)) {
- indent= computeCommentIndent(document, line, scanner, startingPartition);
- } else if (startingPartition.getType().equals(STPPartitionScanner.STP_CONDITIONAL)) {
- indent= computePreprocessorIndent(document, line, startingPartition);
- } else if (!commentLines[lineIndex] && startingPartition.getOffset() == offset && startingPartition.getType().equals(STPPartitionScanner.STP_COMMENT)) {
- return;
- }
- }
-
- // standard C code indentation
- if (indent == null) {
- StringBuilder computed= indenter.computeIndentation(offset);
- if (computed != null)
- indent= computed.toString();
- else
- indent= ""; //$NON-NLS-1$
- }
-
- // change document:
- // get current white space
- int lineLength= currentLine.getLength();
- int end= scanner.findNonWhitespaceForwardInAnyPartition(wsStart, offset + lineLength);
- if (end == STPHeuristicScanner.NOT_FOUND)
- end= offset + lineLength;
- int length= end - offset;
- String currentIndent= document.get(offset, length);
-
- // memorize the fact that a line is a single line comment (but not at column 0) and should be treated like code
- // as opposed to commented out code, which should keep its slashes at column 0
- // if 'indentInsideLineComments' is false, all comment lines are indented with the code
- if (length > 0 || !indentInsideLineComments) {
- ITypedRegion partition= TextUtilities.getPartition(document, STPPartitionScanner.STP_PARTITIONING, end, false);
- if (partition.getOffset() == end && STPPartitionScanner.STP_COMMENT.equals(partition.getType())) {
- commentLines[lineIndex]= true;
- }
- }
-
- // only change the document if it is a real change
- if (!indent.equals(currentIndent)) {
- document.replace(offset, length, indent);
- }
- }
-
- /**
- * Computes and returns the indentation for a source line.
- *
- * @param document the document
- * @param line the line in document
- * @param indenter the C indenter
- * @param scanner the scanner
- * @return the indent, never <code>null</code>
- * @throws BadLocationException
- */
- public static String computeIndent(IDocument document, int line, STPIndenter indenter, STPHeuristicScanner scanner) throws BadLocationException {
- IRegion currentLine= document.getLineInformation(line);
- final int offset= currentLine.getOffset();
-
- String indent= null;
- if (offset < document.getLength()) {
- ITypedRegion partition= TextUtilities.getPartition(document, STPPartitionScanner.STP_PARTITIONING, offset, true);
- ITypedRegion startingPartition= TextUtilities.getPartition(document, STPPartitionScanner.STP_PARTITIONING, offset, false);
- String type= partition.getType();
- if (type.equals(STPPartitionScanner.STP_COMMENT)) {
- indent= computeCommentIndent(document, line, scanner, startingPartition);
- } else if (startingPartition.getType().equals(STPPartitionScanner.STP_CONDITIONAL)) {
- indent= computePreprocessorIndent(document, line, startingPartition);
- }
- }
-
- // standard C code indentation
- if (indent == null) {
- StringBuilder computed= indenter.computeIndentation(offset);
- if (computed != null)
- indent= computed.toString();
- else
- indent= new String();
- }
- return indent;
- }
-
- /**
- * Computes and returns the indentation for a block comment line.
- *
- * @param document the document
- * @param line the line in document
- * @param scanner the scanner
- * @param partition the comment partition
- * @return the indent, or <code>null</code> if not computable
- * @throws BadLocationException
- */
- public static String computeCommentIndent(IDocument document, int line, STPHeuristicScanner scanner, ITypedRegion partition) throws BadLocationException {
- if (line == 0) // impossible - the first line is never inside a comment
- return null;
-
- // don't make any assumptions if the line does not start with \s*\* - it might be
- // commented out code, for which we don't want to change the indent
- final IRegion lineInfo= document.getLineInformation(line);
- final int lineStart= lineInfo.getOffset();
- final int lineLength= lineInfo.getLength();
- final int lineEnd= lineStart + lineLength;
- int nonWS= scanner.findNonWhitespaceForwardInAnyPartition(lineStart, lineEnd);
- if (nonWS == STPHeuristicScanner.NOT_FOUND || document.getChar(nonWS) != '*') {
- if (nonWS == STPHeuristicScanner.NOT_FOUND)
- return document.get(lineStart, lineLength);
- return document.get(lineStart, nonWS - lineStart);
- }
-
- // take the indent from the previous line and reuse
- IRegion previousLine= document.getLineInformation(line - 1);
- int previousLineStart= previousLine.getOffset();
- int previousLineLength= previousLine.getLength();
- int previousLineEnd= previousLineStart + previousLineLength;
-
- StringBuilder buf= new StringBuilder();
- int previousLineNonWS= scanner.findNonWhitespaceForwardInAnyPartition(previousLineStart, previousLineEnd);
- if (previousLineNonWS == STPHeuristicScanner.NOT_FOUND || document.getChar(previousLineNonWS) != '*') {
- // align with the comment start if the previous line is not an asterix line
- previousLine= document.getLineInformationOfOffset(partition.getOffset());
- previousLineStart= previousLine.getOffset();
- previousLineLength= previousLine.getLength();
- previousLineEnd= previousLineStart + previousLineLength;
- previousLineNonWS= scanner.findNonWhitespaceForwardInAnyPartition(previousLineStart, previousLineEnd);
- if (previousLineNonWS == STPHeuristicScanner.NOT_FOUND)
- previousLineNonWS= previousLineEnd;
-
- // add the initial space
- // TODO this may be controlled by a formatter preference in the future
- buf.append(' ');
- }
-
- String indentation= document.get(previousLineStart, previousLineNonWS - previousLineStart);
- buf.insert(0, indentation);
- return buf.toString();
- }
-
- /**
- * Computes and returns the indentation for a preprocessor line.
- *
- * @param document the document
- * @param line the line in document
- * @param partition the comment partition
- * @return the indent, or <code>null</code> if not computable
- * @throws BadLocationException
- */
- public static String computePreprocessorIndent(IDocument document, int line, ITypedRegion partition)
- throws BadLocationException {
- int ppFirstLine= document.getLineOfOffset(partition.getOffset());
- if (line == ppFirstLine) {
- return ""; //$NON-NLS-1$
- }
- STPHeuristicScanner ppScanner= new STPHeuristicScanner(document, STPPartitionScanner.STP_CONDITIONAL, partition.getType());
- STPIndenter ppIndenter= new STPIndenter(document, ppScanner);
- if (line == ppFirstLine + 1) {
- return ppIndenter.createReusingIndent(new StringBuilder(), ppIndenter.getContinuationLineIndent(), 0).toString();
- }
- StringBuilder computed= ppIndenter.computeIndentation(document.getLineOffset(line), false);
- if (computed != null) {
- return computed.toString();
- }
- // take the indent from the previous line and reuse
- IRegion previousLine= document.getLineInformation(line - 1);
- int previousLineStart= previousLine.getOffset();
- int previousLineLength= previousLine.getLength();
- int previousLineEnd= previousLineStart + previousLineLength;
-
- int previousLineNonWS= ppScanner.findNonWhitespaceForwardInAnyPartition(previousLineStart, previousLineEnd);
- String previousIndent= document.get(previousLineStart, previousLineNonWS - previousLineStart);
- computed= new StringBuilder(previousIndent);
- return computed.toString();
- }
+ private static final String SLASHES= "//"; //$NON-NLS-1$
+
+ /**
+ * The result of an indentation operation. The result may be passed to
+ * subsequent calls to
+ * {@link IndentUtil#indentLines(IDocument, ILineRange, IProject, IndentUtil.IndentResult) indentLines}
+ * to obtain consistent results with respect to the indentation of
+ * line-comments.
+ */
+ public static final class IndentResult {
+ private IndentResult(boolean[] commentLines) {
+ commentLinesAtColumnZero= commentLines;
+ }
+ private boolean[] commentLinesAtColumnZero;
+ }
+
+ private IndentUtil() {
+ // do not instantiate
+ }
+
+ /**
+ * Indents the line range specified by <code>lines</code> in
+ * <code>document</code>. The passed C project may be
+ * <code>null</code>, it is used solely to obtain formatter preferences.
+ *
+ * @param document the document to be changed
+ * @param lines the line range to be indented
+ * @param project the C project to get the formatter preferences from, or
+ * <code>null</code> if global preferences should be used
+ * @param result the result from a previous call to <code>indentLines</code>,
+ * in order to maintain comment line properties, or <code>null</code>.
+ * Note that the passed result may be changed by the call.
+ * @return an indent result that may be queried for changes and can be
+ * reused in subsequent indentation operations
+ * @throws BadLocationException if <code>lines</code> is not a valid line
+ * range on <code>document</code>
+ */
+ public static IndentResult indentLines(IDocument document, ILineRange lines, IProject project, IndentResult result) throws BadLocationException {
+ int numberOfLines= lines.getNumberOfLines();
+
+ if (numberOfLines < 1)
+ return new IndentResult(null);
+
+ result= reuseOrCreateToken(result, numberOfLines);
+
+ STPHeuristicScanner scanner= new STPHeuristicScanner(document);
+ STPIndenter indenter= new STPIndenter(document, scanner, project);
+ boolean indentInsideLineComments= true;
+ for (int line= lines.getStartLine(), last= line + numberOfLines, i= 0; line < last; line++) {
+ indentLine(document, line, indenter, scanner, result.commentLinesAtColumnZero, i++, indentInsideLineComments);
+ }
+
+ return result;
+ }
+
+ /**
+ * Returns the indentation of the line <code>line</code> in <code>document</code>.
+ * The returned string may contain pairs of leading slashes that are considered
+ * part of the indentation.
+ *
+ * @param document the document
+ * @param line the line
+ * @param indentInsideLineComments option whether to indent inside line comments starting at column 0
+ * @return the indentation of <code>line</code> in <code>document</code>
+ * @throws BadLocationException if the document is changed concurrently
+ */
+ public static String getCurrentIndent(IDocument document, int line, boolean indentInsideLineComments) throws BadLocationException {
+ IRegion region= document.getLineInformation(line);
+ int from= region.getOffset();
+ int endOffset= region.getOffset() + region.getLength();
+
+ int to= from;
+ if (indentInsideLineComments) {
+ // go behind line comments
+ while (to < endOffset - 2 && document.get(to, 2).equals(SLASHES))
+ to += 2;
+ }
+
+ while (to < endOffset) {
+ char ch= document.getChar(to);
+ if (!Character.isWhitespace(ch))
+ break;
+ to++;
+ }
+
+ return document.get(from, to - from);
+ }
+
+ private static IndentResult reuseOrCreateToken(IndentResult token, int numberOfLines) {
+ if (token == null)
+ token= new IndentResult(new boolean[numberOfLines]);
+ else if (token.commentLinesAtColumnZero == null)
+ token.commentLinesAtColumnZero= new boolean[numberOfLines];
+ else if (token.commentLinesAtColumnZero.length != numberOfLines) {
+ boolean[] commentBooleans= new boolean[numberOfLines];
+ System.arraycopy(token.commentLinesAtColumnZero, 0, commentBooleans, 0, Math.min(numberOfLines, token.commentLinesAtColumnZero.length));
+ token.commentLinesAtColumnZero= commentBooleans;
+ }
+ return token;
+ }
+
+ /**
+ * Indents a single line using the heuristic scanner. Multiline comments are
+ * indented as specified by the <code>CCommentAutoIndentStrategy</code>.
+ *
+ * @param document the document
+ * @param line the line to be indented
+ * @param indenter the C indenter
+ * @param scanner the heuristic scanner
+ * @param commentLines the indent token comment booleans
+ * @param lineIndex the zero-based line index
+ * @param indentInsideLineComments option whether to indent inside line comments
+ * starting at column 0
+ * @throws BadLocationException if the document got changed concurrently
+ */
+ private static void indentLine(IDocument document, int line, STPIndenter indenter,
+ STPHeuristicScanner scanner, boolean[] commentLines, int lineIndex,
+ boolean indentInsideLineComments) throws BadLocationException {
+ IRegion currentLine= document.getLineInformation(line);
+ final int offset= currentLine.getOffset();
+ int wsStart= offset; // where we start searching for non-WS; after the "//" in single line comments
+
+ String indent= null;
+ if (offset < document.getLength()) {
+ ITypedRegion partition= TextUtilities.getPartition(document, STPPartitionScanner.STP_PARTITIONING, offset, true);
+ ITypedRegion startingPartition= TextUtilities.getPartition(document, STPPartitionScanner.STP_PARTITIONING, offset, false);
+ String type= partition.getType();
+ if (type.equals(STPPartitionScanner.STP_MULTILINE_COMMENT)) {
+ indent= computeCommentIndent(document, line, scanner, startingPartition);
+ } else if (startingPartition.getType().equals(STPPartitionScanner.STP_CONDITIONAL)) {
+ indent= computePreprocessorIndent(document, line, startingPartition);
+ } else if (!commentLines[lineIndex] && startingPartition.getOffset() == offset && startingPartition.getType().equals(STPPartitionScanner.STP_COMMENT)) {
+ return;
+ }
+ }
+
+ // standard C code indentation
+ if (indent == null) {
+ StringBuilder computed= indenter.computeIndentation(offset);
+ if (computed != null)
+ indent= computed.toString();
+ else
+ indent= ""; //$NON-NLS-1$
+ }
+
+ // change document:
+ // get current white space
+ int lineLength= currentLine.getLength();
+ int end= scanner.findNonWhitespaceForwardInAnyPartition(wsStart, offset + lineLength);
+ if (end == STPHeuristicScanner.NOT_FOUND)
+ end= offset + lineLength;
+ int length= end - offset;
+ String currentIndent= document.get(offset, length);
+
+ // memorize the fact that a line is a single line comment (but not at column 0) and should be treated like code
+ // as opposed to commented out code, which should keep its slashes at column 0
+ // if 'indentInsideLineComments' is false, all comment lines are indented with the code
+ if (length > 0 || !indentInsideLineComments) {
+ ITypedRegion partition= TextUtilities.getPartition(document, STPPartitionScanner.STP_PARTITIONING, end, false);
+ if (partition.getOffset() == end && STPPartitionScanner.STP_COMMENT.equals(partition.getType())) {
+ commentLines[lineIndex]= true;
+ }
+ }
+
+ // only change the document if it is a real change
+ if (!indent.equals(currentIndent)) {
+ document.replace(offset, length, indent);
+ }
+ }
+
+ /**
+ * Computes and returns the indentation for a source line.
+ *
+ * @param document the document
+ * @param line the line in document
+ * @param indenter the C indenter
+ * @param scanner the scanner
+ * @return the indent, never <code>null</code>
+ * @throws BadLocationException
+ */
+ public static String computeIndent(IDocument document, int line, STPIndenter indenter, STPHeuristicScanner scanner) throws BadLocationException {
+ IRegion currentLine= document.getLineInformation(line);
+ final int offset= currentLine.getOffset();
+
+ String indent= null;
+ if (offset < document.getLength()) {
+ ITypedRegion partition= TextUtilities.getPartition(document, STPPartitionScanner.STP_PARTITIONING, offset, true);
+ ITypedRegion startingPartition= TextUtilities.getPartition(document, STPPartitionScanner.STP_PARTITIONING, offset, false);
+ String type= partition.getType();
+ if (type.equals(STPPartitionScanner.STP_COMMENT)) {
+ indent= computeCommentIndent(document, line, scanner, startingPartition);
+ } else if (startingPartition.getType().equals(STPPartitionScanner.STP_CONDITIONAL)) {
+ indent= computePreprocessorIndent(document, line, startingPartition);
+ }
+ }
+
+ // standard C code indentation
+ if (indent == null) {
+ StringBuilder computed= indenter.computeIndentation(offset);
+ if (computed != null)
+ indent= computed.toString();
+ else
+ indent= new String();
+ }
+ return indent;
+ }
+
+ /**
+ * Computes and returns the indentation for a block comment line.
+ *
+ * @param document the document
+ * @param line the line in document
+ * @param scanner the scanner
+ * @param partition the comment partition
+ * @return the indent, or <code>null</code> if not computable
+ * @throws BadLocationException
+ */
+ public static String computeCommentIndent(IDocument document, int line, STPHeuristicScanner scanner, ITypedRegion partition) throws BadLocationException {
+ if (line == 0) // impossible - the first line is never inside a comment
+ return null;
+
+ // don't make any assumptions if the line does not start with \s*\* - it might be
+ // commented out code, for which we don't want to change the indent
+ final IRegion lineInfo= document.getLineInformation(line);
+ final int lineStart= lineInfo.getOffset();
+ final int lineLength= lineInfo.getLength();
+ final int lineEnd= lineStart + lineLength;
+ int nonWS= scanner.findNonWhitespaceForwardInAnyPartition(lineStart, lineEnd);
+ if (nonWS == STPHeuristicScanner.NOT_FOUND || document.getChar(nonWS) != '*') {
+ if (nonWS == STPHeuristicScanner.NOT_FOUND)
+ return document.get(lineStart, lineLength);
+ return document.get(lineStart, nonWS - lineStart);
+ }
+
+ // take the indent from the previous line and reuse
+ IRegion previousLine= document.getLineInformation(line - 1);
+ int previousLineStart= previousLine.getOffset();
+ int previousLineLength= previousLine.getLength();
+ int previousLineEnd= previousLineStart + previousLineLength;
+
+ StringBuilder buf= new StringBuilder();
+ int previousLineNonWS= scanner.findNonWhitespaceForwardInAnyPartition(previousLineStart, previousLineEnd);
+ if (previousLineNonWS == STPHeuristicScanner.NOT_FOUND || document.getChar(previousLineNonWS) != '*') {
+ // align with the comment start if the previous line is not an asterix line
+ previousLine= document.getLineInformationOfOffset(partition.getOffset());
+ previousLineStart= previousLine.getOffset();
+ previousLineLength= previousLine.getLength();
+ previousLineEnd= previousLineStart + previousLineLength;
+ previousLineNonWS= scanner.findNonWhitespaceForwardInAnyPartition(previousLineStart, previousLineEnd);
+ if (previousLineNonWS == STPHeuristicScanner.NOT_FOUND)
+ previousLineNonWS= previousLineEnd;
+
+ // add the initial space
+ // TODO this may be controlled by a formatter preference in the future
+ buf.append(' ');
+ }
+
+ String indentation= document.get(previousLineStart, previousLineNonWS - previousLineStart);
+ buf.insert(0, indentation);
+ return buf.toString();
+ }
+
+ /**
+ * Computes and returns the indentation for a preprocessor line.
+ *
+ * @param document the document
+ * @param line the line in document
+ * @param partition the comment partition
+ * @return the indent, or <code>null</code> if not computable
+ * @throws BadLocationException
+ */
+ public static String computePreprocessorIndent(IDocument document, int line, ITypedRegion partition)
+ throws BadLocationException {
+ int ppFirstLine= document.getLineOfOffset(partition.getOffset());
+ if (line == ppFirstLine) {
+ return ""; //$NON-NLS-1$
+ }
+ STPHeuristicScanner ppScanner= new STPHeuristicScanner(document, STPPartitionScanner.STP_CONDITIONAL, partition.getType());
+ STPIndenter ppIndenter= new STPIndenter(document, ppScanner);
+ if (line == ppFirstLine + 1) {
+ return ppIndenter.createReusingIndent(new StringBuilder(), ppIndenter.getContinuationLineIndent(), 0).toString();
+ }
+ StringBuilder computed= ppIndenter.computeIndentation(document.getLineOffset(line), false);
+ if (computed != null) {
+ return computed.toString();
+ }
+ // take the indent from the previous line and reuse
+ IRegion previousLine= document.getLineInformation(line - 1);
+ int previousLineStart= previousLine.getOffset();
+ int previousLineLength= previousLine.getLength();
+ int previousLineEnd= previousLineStart + previousLineLength;
+
+ int previousLineNonWS= ppScanner.findNonWhitespaceForwardInAnyPartition(previousLineStart, previousLineEnd);
+ String previousIndent= document.get(previousLineStart, previousLineNonWS - previousLineStart);
+ computed= new StringBuilder(previousIndent);
+ return computed.toString();
+ }
}
diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/Messages.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/Messages.java
index b86f74750d..9ebd3a1633 100644
--- a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/Messages.java
+++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/Messages.java
@@ -14,16 +14,16 @@ package org.eclipse.linuxtools.internal.systemtap.ui.ide.editors.stp;
import org.eclipse.osgi.util.NLS;
public class Messages extends NLS {
- private static final String BUNDLE_NAME = "org.eclipse.linuxtools.internal.systemtap.ui.ide.editors.stp.messages"; //$NON-NLS-1$
- public static String STPCompletionProcessor_global;
- public static String STPCompletionProcessor_probe;
- public static String STPCompletionProcessor_function;
- public static String STPMetadataSingleton_noCompletions;
- static {
- // initialize resource bundle
- NLS.initializeMessages(BUNDLE_NAME, Messages.class);
- }
+ private static final String BUNDLE_NAME = "org.eclipse.linuxtools.internal.systemtap.ui.ide.editors.stp.messages"; //$NON-NLS-1$
+ public static String STPCompletionProcessor_global;
+ public static String STPCompletionProcessor_probe;
+ public static String STPCompletionProcessor_function;
+ public static String STPMetadataSingleton_noCompletions;
+ static {
+ // initialize resource bundle
+ NLS.initializeMessages(BUNDLE_NAME, Messages.class);
+ }
- private Messages() {
- }
+ private Messages() {
+ }
}
diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/STPAutoEditStrategy.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/STPAutoEditStrategy.java
index 26cf374a54..11efa8bcc1 100644
--- a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/STPAutoEditStrategy.java
+++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/STPAutoEditStrategy.java
@@ -30,1014 +30,1014 @@ import org.eclipse.linuxtools.internal.systemtap.ui.ide.editors.stp.STPIndenter.
* Very basic auto edit strategy simply completing opening with closing brackets and quotes.
*/
public class STPAutoEditStrategy extends
- DefaultIndentLineAutoEditStrategy {
- private static final String LINE_COMMENT= "//"; //$NON-NLS-1$
- private boolean fCloseBrace = true;
-
- private String fPartitioning;
- private IProject fProject;
-
- public STPAutoEditStrategy(String fPartitioning, IProject project) {
- this.fPartitioning = fPartitioning;
- this.fProject = project;
- }
-
- /**
- * Returns the block balance, i.e. zero if the blocks are balanced at
- * <code>offset</code>, a negative number if there are more closing than opening
- * braces, and a positive number if there are more opening than closing braces.
- *
- * @param document
- * @param offset
- * @param partitioning
- * @return the block balance
- */
- private static int getBlockBalance(IDocument document, int offset, String partitioning) {
- if (offset < 1)
- return -1;
- if (offset >= document.getLength())
- return 1;
-
- int begin = offset;
- int end = offset - 1;
-
- STPHeuristicScanner scanner = new STPHeuristicScanner(document);
-
- while (true) {
- begin = scanner.findOpeningPeer(begin - 1, '{', '}');
- end = scanner.findClosingPeer(end + 1, '{', '}');
- if (begin == -1 && end == -1)
- return 0;
- if (begin == -1)
- return -1;
- if (end == -1)
- return 1;
- }
- }
-
- @Override
- public void customizeDocumentCommand(IDocument document,
- DocumentCommand command) {
- boolean modified = false;
- boolean isNewLine= command.length == 0 && command.text != null
- && isLineDelimiter(document, command.text);
- if (isNewLine) {
- smartIndentAfterNewLine(document, command);
- } else if (command.text.length() == 1) {
- smartIndentOnKeypress(document, command);
- } else if (command.text.length() > 1
- && command.text.trim().length() != 0) {
- smartPaste(document, command); // no smart backspace for paste
- }
- if (command.text.equals("\"") && !inStringOrComment(document, command)) { //$NON-NLS-1$
- command.text = "\"\""; //$NON-NLS-1$
- modified = true;
- } else if (command.text.equals("(") && !inStringOrComment(document, command)) { //$NON-NLS-1$
- command.text = "()"; //$NON-NLS-1$
- modified = true;
- } else if (command.text.equals("[") && !inStringOrComment(document, command)) { //$NON-NLS-1$
- command.text = "[]"; //$NON-NLS-1$
- modified = true;
- }
-
- if (modified) {
- command.caretOffset = command.offset + 1;
- command.shiftsCaret = false;
- }
-
- super.customizeDocumentCommand(document, command);
- }
-
- private boolean inStringOrComment(IDocument d, DocumentCommand c) {
- int docLength = d.getLength();
- if (c.offset == -1 || docLength == 0)
- return false;
- try {
- ITypedRegion partition= TextUtilities.getPartition(d, fPartitioning, c.offset, false);
- String partitionType = partition.getType();
- if (c.offset > 0 &&
- (STPPartitionScanner.STP_COMMENT.equals(partitionType)
- || STPPartitionScanner.STP_MULTILINE_COMMENT.equals(partitionType)
- || STPPartitionScanner.STP_STRING.equals(partitionType))) {
- return true;
- }
- IRegion lineInfo = d.getLineInformationOfOffset(c.offset);
- int offset = lineInfo.getOffset();
- boolean inChar = false;
- boolean inString = false;
- boolean inComment = false;
- for (int i = offset; i < c.offset; ++i) {
- char ch = d.getChar(i);
- switch (ch) {
- case '\"':
- if (!inChar)
- inString = !inString;
- break;
- case '\'':
- if (!inString)
- inChar = !inChar;
- break;
- case '\\':
- ++i;
- break;
- case '/':
- if (!inString && !inChar) {
- ch = d.getChar(i + 1);
- if (ch == '/')
- return true; // We have a line comment
- else if (ch == '*')
- inComment = true;
- }
- break;
- case '#':
- if (!inString && !inChar)
- return true;
- break;
- case '*':
- if (!inString && !inChar) {
- if (inComment) {
- ch = d.getChar(i + 1);
- if (ch == '/')
- inComment = false;
- }
- }
- break;
- }
- }
- return inString || inChar || inComment;
-
- } catch (BadLocationException e) {
- IDEPlugin.log(e);
- }
- return false;
- }
-
-
- private void smartIndentAfterNewLine(IDocument d, DocumentCommand c) {
- int docLength = d.getLength();
- if (c.offset == -1 || docLength == 0)
- return;
-
- int addIndent= 0;
- STPHeuristicScanner scanner= new STPHeuristicScanner(d);
- try {
- ITypedRegion partition= TextUtilities.getPartition(d, fPartitioning, c.offset, false);
- if (STPPartitionScanner.STP_CONDITIONAL.equals(partition.getType()) && c.offset > 0 && d.getChar(c.offset-1) == '\\') {
- scanner = new STPHeuristicScanner(d, fPartitioning, STPPartitionScanner.STP_CONDITIONAL);
- addIndent= 1;
- }
-
- int line = d.getLineOfOffset(c.offset);
- IRegion reg = d.getLineInformation(line);
- int start = reg.getOffset();
- int lineEnd = start + reg.getLength();
-
- StringBuilder indent= null;
- STPIndenter indenter= new STPIndenter(d, scanner, fProject);
- indent= indenter.computeIndentation(c.offset);
- if (indent == null) {
- indent= new StringBuilder();
- }
- if (addIndent > 0 && indent.length() == 0) {
- indent= indenter.createReusingIndent(indent, addIndent, 0);
- }
-
- StringBuilder buf = new StringBuilder(c.text + indent);
- int contentStart = findEndOfWhiteSpace(d, c.offset, lineEnd);
- c.length = Math.max(contentStart - c.offset, 0);
-
- // insert closing brace on new line after an unclosed opening brace
- if (getBracketCount(d, start, c.offset, true) > 0 && fCloseBrace && !isClosedBrace(d, c.offset)) {
- c.caretOffset = c.offset + buf.length();
- c.shiftsCaret = false;
-
- // copy old content of line behind insertion point to new line
- // unless we think we are inserting an anonymous type definition
- if (c.offset == 0 || !(computeAnonymousPosition(d, c.offset - 1, fPartitioning, lineEnd) != -1)) {
- if (lineEnd - contentStart > 0) {
- c.length = lineEnd - c.offset;
- buf.append(d.get(contentStart, lineEnd - contentStart).toCharArray());
- }
- }
-
- buf.append(TextUtilities.getDefaultLineDelimiter(d));
- StringBuilder reference = null;
- int nonWS = findEndOfWhiteSpace(d, start, lineEnd);
- if (nonWS < c.offset && d.getChar(nonWS) == '{')
- reference = new StringBuilder(d.get(start, nonWS - start));
- else
- reference = indenter.getReferenceIndentation(c.offset);
- if (reference != null)
- buf.append(reference);
- buf.append('}');
- int bound= c.offset > 200 ? c.offset - 200 : STPHeuristicScanner.UNBOUND;
- int bracePos = scanner.findOpeningPeer(c.offset - 1, bound, '{', '}');
- if (bracePos != STPHeuristicScanner.NOT_FOUND) {
- if (scanner.looksLikeCompositeTypeDefinitionBackward(bracePos, bound) ||
- scanner.previousToken(bracePos - 1, bound) == STPSymbols.TokenEQUAL) {
- buf.append(';');
- }
- }
- }
- // insert extra line upon new line between two braces
- else if (c.offset > start && contentStart < lineEnd && d.getChar(contentStart) == '}') {
- int firstCharPos = scanner.findNonWhitespaceBackward(c.offset - 1, start);
- if (firstCharPos != STPHeuristicScanner.NOT_FOUND && d.getChar(firstCharPos) == '{') {
- c.caretOffset = c.offset + buf.length();
- c.shiftsCaret = false;
-
- StringBuilder reference = null;
- int nonWS = findEndOfWhiteSpace(d, start, lineEnd);
- if (nonWS < c.offset && d.getChar(nonWS) == '{')
- reference = new StringBuilder(d.get(start, nonWS - start));
- else
- reference = indenter.getReferenceIndentation(c.offset);
-
- buf.append(TextUtilities.getDefaultLineDelimiter(d));
-
- if (reference != null)
- buf.append(reference);
- }
- }
- c.text = buf.toString();
-
- } catch (BadLocationException e) {
- IDEPlugin.log(e);
- }
- }
-
- private void smartIndentUponE(IDocument doc, DocumentCommand c) {
- if (c.offset < 4 || doc.getLength() == 0)
- return;
-
- try {
- String content = doc.get(c.offset - 3, 3);
- if (content.equals("els")) { //$NON-NLS-1$
- STPHeuristicScanner scanner = new STPHeuristicScanner(doc);
- int p = c.offset - 3;
-
- // current line
- int line = doc.getLineOfOffset(p);
- int lineOffset = doc.getLineOffset(line);
-
- // make sure we don't have any leading comments etc.
- if (doc.get(lineOffset, p - lineOffset).trim().length() != 0)
- return;
-
- // Line of last C code
- int pos = scanner.findNonWhitespaceBackward(p - 1, STPHeuristicScanner.UNBOUND);
- if (pos == -1)
- return;
- int lastLine = doc.getLineOfOffset(pos);
-
- // Only shift if the last C line is further up and is a braceless block candidate
- if (lastLine < line) {
- STPIndenter indenter = new STPIndenter(doc, scanner, fProject);
- int ref = indenter.findReferencePosition(p, true, MatchMode.REGULAR);
- if (ref == STPHeuristicScanner.NOT_FOUND)
- return;
- int refLine = doc.getLineOfOffset(ref);
- String indent = getIndentOfLine(doc, refLine);
-
- if (indent != null) {
- c.text = indent + "else"; //$NON-NLS-1$
- c.length += c.offset - lineOffset;
- c.offset = lineOffset;
- }
- }
-
- return;
- }
-
- if (content.equals("cas")) { //$NON-NLS-1$
- STPHeuristicScanner scanner = new STPHeuristicScanner(doc);
- int p = c.offset - 3;
-
- // current line
- int line = doc.getLineOfOffset(p);
- int lineOffset = doc.getLineOffset(line);
-
- // make sure we don't have any leading comments etc.
- if (doc.get(lineOffset, p - lineOffset).trim().length() != 0)
- return;
-
- // Line of last C code
- int pos = scanner.findNonWhitespaceBackward(p - 1, STPHeuristicScanner.UNBOUND);
- if (pos == -1)
- return;
- int lastLine = doc.getLineOfOffset(pos);
-
- // Only shift if the last C line is further up and is a braceless block candidate
- if (lastLine < line) {
- STPIndenter indenter = new STPIndenter(doc, scanner, fProject);
- int ref = indenter.findReferencePosition(p, false, MatchMode.MATCH_CASE);
- if (ref == STPHeuristicScanner.NOT_FOUND)
- return;
- int refLine = doc.getLineOfOffset(ref);
- int nextToken = scanner.nextToken(ref, STPHeuristicScanner.UNBOUND);
- String indent;
- if (nextToken == STPSymbols.TokenCASE || nextToken == STPSymbols.TokenDEFAULT)
- indent = getIndentOfLine(doc, refLine);
- else // at the brace of the switch
- indent = indenter.computeIndentation(p).toString();
-
- if (indent != null) {
- c.text = indent.toString() + "case"; //$NON-NLS-1$
- c.length += c.offset - lineOffset;
- c.offset = lineOffset;
- }
- }
-
- return;
- }
- } catch (BadLocationException e) {
- IDEPlugin.log(e);
- }
- }
- /**
- * Computes an insert position for an opening brace if <code>offset</code> maps to a position in
- * <code>document</code> with a expression in parenthesis that will take a block after the closing parenthesis.
- *
- * @param document the document being modified
- * @param offset the offset of the caret position, relative to the line start.
- * @param partitioning the document partitioning
- * @param max the max position
- * @return an insert position relative to the line start if <code>line</code> contains a parenthesized expression that can be followed by a block, -1 otherwise
- */
- private static int computeAnonymousPosition(IDocument document, int offset, String partitioning, int max) {
- // find the opening parenthesis for every closing parenthesis on the current line after offset
- // return the position behind the closing parenthesis if it looks like a method declaration
- // or an expression for an if, while, for, catch statement
-
- STPHeuristicScanner scanner = new STPHeuristicScanner(document);
- int pos = offset;
- int length = max;
- int scanTo = scanner.scanForward(pos, length, '}');
- if (scanTo == -1)
- scanTo = length;
-
- int closingParen = findClosingParenToLeft(scanner, pos) - 1;
-
- while (true) {
- int startScan = closingParen + 1;
- closingParen = scanner.scanForward(startScan, scanTo, ')');
- if (closingParen == -1)
- break;
-
- int openingParen = scanner.findOpeningPeer(closingParen - 1, '(', ')');
-
- // no way an expression at the beginning of the document can mean anything
- if (openingParen < 1)
- break;
-
- // only select insert positions for parenthesis currently embracing the caret
- if (openingParen > pos)
- continue;
- }
-
- return -1;
- }
-
- /**
- * Finds a closing parenthesis to the left of <code>position</code> in document, where that parenthesis is only
- * separated by whitespace from <code>position</code>. If no such parenthesis can be found, <code>position</code> is returned.
- *
- * @param scanner the C heuristic scanner set up on the document
- * @param position the first character position in <code>document</code> to be considered
- * @return the position of a closing parenthesis left to <code>position</code> separated only by whitespace, or <code>position</code> if no parenthesis can be found
- */
- private static int findClosingParenToLeft(STPHeuristicScanner scanner, int position) {
- if (position < 1)
- return position;
-
- if (scanner.previousToken(position - 1, STPHeuristicScanner.UNBOUND) == STPSymbols.TokenRPAREN)
- return scanner.getPosition() + 1;
- return position;
- }
-
- private boolean isClosedBrace(IDocument document, int offset) {
- return getBlockBalance(document, offset, fPartitioning) <= 0;
- }
-
- private void smartIndentOnKeypress(IDocument document, DocumentCommand command) {
- switch (command.text.charAt(0)) {
- case '}':
- smartIndentAfterClosingBracket(document, command);
- break;
- case '{':
- smartIndentAfterOpeningBracket(document, command);
- break;
- case 'e':
- smartIndentUponE(document, command);
- break;
- case '#':
- smartIndentAfterHash(document, command);
- break;
- case '\"':
- smartInsertCloseChar(document, command, '\"');
- break;
- case ')':
- smartInsertCloseChar(document, command, ')');
- break;
- case ']':
- smartInsertCloseChar(document, command, ']');
- break;
- }
- }
-
- /**
- * A closing char (e.g. right paren ')') is being inserted. If one already exists
- * at current location in the document, skip over it and don't do an
- * insert.
- *
- * @param d - document
- * @param c - insert text
- * @param ch - closing char being inserted
- */
- private void smartInsertCloseChar(IDocument d, DocumentCommand c, char ch) {
- if (c.offset < 1 || d.getLength() == 0)
- return;
-
- try {
- if (d.getChar(c.offset) == ch) {
- int backslashCount = 0;
- int prevOffset = c.offset - 1;
- // Look backwards for backslashes. We will ignore if there are even number
- while (prevOffset > 0 && d.getChar(prevOffset) == '\\') {
- --prevOffset;
- ++backslashCount;
- }
- if ((backslashCount & 1) == 0) {
- c.text = ""; //$NON-NLS-1$
- c.offset++;
- }
- }
- } catch (BadLocationException e) {
- IDEPlugin.log(e);
- }
-
- }
-
- private void smartIndentAfterHash(IDocument doc, DocumentCommand c) {
- try {
- ITypedRegion partition= TextUtilities.getPartition(doc, fPartitioning, c.offset, false);
- if (IDocument.DEFAULT_CONTENT_TYPE.equals(partition.getType())) {
- IRegion startLine= doc.getLineInformationOfOffset(c.offset);
- String indent= doc.get(startLine.getOffset(), c.offset - startLine.getOffset());
- if (indent.trim().length() == 0) {
- c.offset -= indent.length();
- c.length += indent.length();
- }
- }
- } catch (BadLocationException e) {
- IDEPlugin.log(e);
- }
- }
-
- private void smartIndentAfterOpeningBracket(IDocument d, DocumentCommand c) {
- if (c.offset < 1 || d.getLength() == 0)
- return;
-
- int p = (c.offset == d.getLength() ? c.offset - 1 : c.offset);
-
- try {
- STPHeuristicScanner scanner= new STPHeuristicScanner(d);
- ITypedRegion partition= TextUtilities.getPartition(d, fPartitioning, p, false);
- if (STPPartitionScanner.STP_CONDITIONAL.equals(partition.getType())) {
- scanner = new STPHeuristicScanner(d, fPartitioning, STPPartitionScanner.STP_CONDITIONAL);
- }
- // current line
- int line = d.getLineOfOffset(c.offset);
- int lineOffset = d.getLineOffset(line);
-
- // make sure we don't have any leading comments etc.
- if (!d.get(lineOffset, c.offset - lineOffset).trim().isEmpty())
- return;
-
- // Line of last C code
- int pos = scanner.findNonWhitespaceBackward(p, STPHeuristicScanner.UNBOUND);
- if (pos == -1)
- return;
- int lastLine = d.getLineOfOffset(pos);
-
- // Only shift if the last C line is further up and is a braceless block candidate
- if (lastLine < line) {
- STPIndenter indenter = new STPIndenter(d, scanner, fProject);
- StringBuilder indent = indenter.computeIndentation(p, true);
- String toDelete = d.get(lineOffset, c.offset - lineOffset);
- if (indent != null && !indent.toString().equals(toDelete)) {
- c.text = indent.append(c.text).toString();
- c.length += c.offset - lineOffset;
- c.offset = lineOffset;
- }
- }
- } catch (BadLocationException e) {
- IDEPlugin.log(e);
- }
- }
-
- private boolean isLineDelimiter(IDocument document, String text) {
- String[] delimiters = document.getLegalLineDelimiters();
- if (delimiters != null)
- return TextUtilities.equals(delimiters, text) > -1;
- return false;
- }
-
- private int getBracketCount(IDocument d, int start, int end, boolean ignoreCloseBrackets) throws BadLocationException {
- int bracketcount = 0;
- while (start < end) {
- char curr = d.getChar(start);
- start++;
- switch (curr) {
- case '#' :
- if (start < end) {
- // '#'-comment: nothing to do anymore on this line
- start = end;
- }
- break;
- case '/' :
- if (start < end) {
- char next = d.getChar(start);
- if (next == '*') {
- // a comment starts, advance to the comment end
- start = getCommentEnd(d, start + 1, end);
- } else if (next == '/') {
- // '//'-comment: nothing to do anymore on this line
- start = end;
- }
- }
- break;
- case '*' :
- if (start < end) {
- char next = d.getChar(start);
- if (next == '/') {
- // we have been in a comment: forget what we read before
- bracketcount = 0;
- start++;
- }
- }
- break;
- case '{' :
- bracketcount++;
- ignoreCloseBrackets = false;
- break;
- case '}' :
- if (!ignoreCloseBrackets) {
- bracketcount--;
- }
- break;
- case '"' :
- case '\'' :
- start = getStringEnd(d, start, end, curr);
- break;
- default :
- }
- }
- return bracketcount;
- }
-
-
- // ----------- bracket counting ------------------------------------------------------
-
- private int getCommentEnd(IDocument d, int pos, int end) throws BadLocationException {
- while (pos < end) {
- char curr = d.getChar(pos);
- pos++;
- if (curr == '*') {
- if (pos < end && d.getChar(pos) == '/') {
- return pos + 1;
- }
- }
- }
- return end;
- }
-
- private String getIndentOfLine(IDocument d, int line) throws BadLocationException {
- if (line > -1) {
- int start = d.getLineOffset(line);
- int end = start + d.getLineLength(line) - 1;
- int whiteend = findEndOfWhiteSpace(d, start, end);
- return d.get(start, whiteend - start);
- }
- return ""; //$NON-NLS-1$
- }
-
- private int getStringEnd(IDocument d, int pos, int end, char ch) throws BadLocationException {
- while (pos < end) {
- char curr = d.getChar(pos);
- pos++;
- if (curr == '\\') {
- // ignore escaped characters
- pos++;
- } else if (curr == ch) {
- return pos;
- }
- }
- return end;
- }
- private void smartIndentAfterClosingBracket(IDocument d, DocumentCommand c) {
- if (c.offset == -1 || d.getLength() == 0)
- return;
-
- try {
- int p = (c.offset == d.getLength() ? c.offset - 1 : c.offset);
- int line = d.getLineOfOffset(p);
- int start = d.getLineOffset(line);
- int whiteend = findEndOfWhiteSpace(d, start, c.offset);
-
- STPHeuristicScanner scanner= new STPHeuristicScanner(d);
- ITypedRegion partition= TextUtilities.getPartition(d, fPartitioning, p, false);
- if (STPPartitionScanner.STP_CONDITIONAL.equals(partition.getType())) {
- scanner = new STPHeuristicScanner(d, fPartitioning, STPPartitionScanner.STP_CONDITIONAL);
- }
- STPIndenter indenter = new STPIndenter(d, scanner, fProject);
-
- // shift only when line does not contain any text up to the closing bracket
- if (whiteend == c.offset) {
- // evaluate the line with the opening bracket that matches out closing bracket
- int reference = indenter.findReferencePosition(c.offset, false, MatchMode.MATCH_BRACE);
- int indLine = d.getLineOfOffset(reference);
- if (indLine != -1 && indLine != line) {
- // take the indent of the found line
- StringBuilder replaceText = new StringBuilder(getIndentOfLine(d, indLine));
- // add the rest of the current line including the just added close bracket
- replaceText.append(d.get(whiteend, c.offset - whiteend));
- replaceText.append(c.text);
- // modify document command
- c.length += c.offset - start;
- c.offset = start;
- c.text = replaceText.toString();
- }
- }
- } catch (BadLocationException e) {
- IDEPlugin.log(e);
- }
- }
-
- /**
- * Installs a C partitioner with <code>document</code>.
- *
- * @param document the document
- */
- private static void installPartitioner(Document document) {
- String[] types= new String[] {
- IDocument.DEFAULT_CONTENT_TYPE,
- STPPartitionScanner.STP_COMMENT,
- STPPartitionScanner.STP_CONDITIONAL,
- };
- FastPartitioner partitioner= new FastPartitioner(new STPPartitionScanner(), types);
- partitioner.connect(document);
- document.setDocumentPartitioner(STPPartitionScanner.STP_PARTITIONING, partitioner);
- }
-
- /**
- * Installs a C partitioner with <code>document</code>.
- *
- * @param document the document
- */
- private static void removePartitioner(Document document) {
- document.setDocumentPartitioner(STPPartitionScanner.STP_PARTITIONING, null);
- }
-
- private void smartPaste(IDocument document, DocumentCommand command) {
- int newOffset= command.offset;
- int newLength= command.length;
- String newText= command.text;
-
- try {
- STPHeuristicScanner scanner= new STPHeuristicScanner(document);
- STPIndenter indenter= new STPIndenter(document, scanner, fProject);
- int offset= newOffset;
-
- // reference position to get the indent from
- int refOffset= indenter.findReferencePosition(offset);
- if (refOffset == STPHeuristicScanner.NOT_FOUND)
- return;
- int peerOffset= getPeerPosition(document, command);
- peerOffset= indenter.findReferencePosition(peerOffset);
- if (peerOffset == STPHeuristicScanner.NOT_FOUND)
- return;
- refOffset= Math.min(refOffset, peerOffset);
-
- // eat any WS before the insertion to the beginning of the line
- int firstLine= 1; // don't format the first line per default, as it has other content before it
- IRegion line= document.getLineInformationOfOffset(offset);
- String notSelected= document.get(line.getOffset(), offset - line.getOffset());
- if (notSelected.trim().length() == 0) {
- newLength += notSelected.length();
- newOffset= line.getOffset();
- firstLine= 0;
- }
-
- // Prefix: the part we need for formatting but won't paste.
- // Take up to 100 previous lines to preserve enough context.
- int firstPrefixLine= Math.max(document.getLineOfOffset(refOffset) - 100, 0);
- int prefixOffset= document.getLineInformation(firstPrefixLine).getOffset();
- String prefix= document.get(prefixOffset, newOffset - prefixOffset);
-
- // Handle the indentation computation inside a temporary document
- Document temp= new Document(prefix + newText);
- DocumentRewriteSession session= temp.startRewriteSession(DocumentRewriteSessionType.STRICTLY_SEQUENTIAL);
- scanner= new STPHeuristicScanner(temp);
- indenter= new STPIndenter(temp, scanner, fProject);
- installPartitioner(temp);
-
- // Indent the first and second line
- // compute the relative indentation difference from the second line
- // (as the first might be partially selected) and use the value to
- // indent all other lines.
- boolean isIndentDetected= false;
- StringBuilder addition= new StringBuilder();
- int insertLength= 0;
- int first= document.computeNumberOfLines(prefix) + firstLine; // don't format first line
- int lines= temp.getNumberOfLines();
- boolean changed= false;
- boolean indentInsideLineComments= true;
-
- for (int l= first; l < lines; l++) { // we don't change the number of lines while adding indents
- IRegion r= temp.getLineInformation(l);
- int lineOffset= r.getOffset();
- int lineLength= r.getLength();
-
- if (lineLength == 0) // don't modify empty lines
- continue;
-
- if (!isIndentDetected) {
- // indent the first pasted line
- String current= IndentUtil.getCurrentIndent(temp, l, indentInsideLineComments);
- StringBuilder correct= new StringBuilder(IndentUtil.computeIndent(temp, l, indenter, scanner));
-
- insertLength= subtractIndent(correct, current, addition);
- // workaround for bug 181139
- if (/*l != first && */temp.get(lineOffset, lineLength).trim().length() != 0) {
- isIndentDetected= true;
- if (insertLength == 0) {
- // no adjustment needed, bail out
- if (firstLine == 0) {
- // but we still need to adjust the first line
- command.offset= newOffset;
- command.length= newLength;
- if (changed)
- break; // still need to get the leading indent of the first line
- }
- return;
- }
- removePartitioner(temp);
- } else {
- changed= insertLength != 0;
- }
- }
-
- // relatively indent all pasted lines
- if (insertLength > 0)
- addIndent(temp, l, addition, indentInsideLineComments);
- else if (insertLength < 0)
- cutIndent(temp, l, -insertLength, indentInsideLineComments);
- }
-
- temp.stopRewriteSession(session);
- newText= temp.get(prefix.length(), temp.getLength() - prefix.length());
-
- command.offset= newOffset;
- command.length= newLength;
- command.text= newText;
- } catch (BadLocationException e) {
- IDEPlugin.log(e);
- }
- }
- /**
- * Computes the difference of two indentations and returns the difference in
- * length of current and correct. If the return value is positive, <code>addition</code>
- * is initialized with a substring of that length of <code>correct</code>.
- *
- * @param correct the correct indentation
- * @param current the current indentation (migth contain non-whitespace)
- * @param difference a string buffer - if the return value is positive, it will be cleared and set to the substring of <code>current</code> of that length
- * @return the difference in lenght of <code>correct</code> and <code>current</code>
- */
- private int subtractIndent(CharSequence correct, CharSequence current, StringBuilder difference) {
- int c1= computeVisualLength(correct);
- int c2= computeVisualLength(current);
- int diff= c1 - c2;
- if (diff <= 0)
- return diff;
-
- difference.setLength(0);
- int len= 0, i= 0;
- while (len < diff) {
- char c= correct.charAt(i++);
- difference.append(c);
- len += computeVisualLength(c);
- }
-
- return diff;
- }
-
- /**
- * Indents line <code>line</code> in <code>document</code> with <code>indent</code>.
- * Leaves leading comment signs alone.
- *
- * @param document the document
- * @param line the line
- * @param indent the indentation to insert
- * @param indentInsideLineComments option whether to indent inside line comments starting at column 0
- * @throws BadLocationException on concurrent document modification
- */
- private static void addIndent(Document document, int line, CharSequence indent, boolean indentInsideLineComments) throws BadLocationException {
- IRegion region= document.getLineInformation(line);
- int insert= region.getOffset();
- int endOffset= region.getOffset() + region.getLength();
-
- if (indentInsideLineComments) {
- // go behind line comments
- while (insert < endOffset - 2 && document.get(insert, 2).equals(LINE_COMMENT))
- insert += 2;
- }
-
- // insert indent
- document.replace(insert, 0, indent.toString());
- }
-
- /**
- * Cuts the visual equivalent of <code>toDelete</code> characters out of the
- * indentation of line <code>line</code> in <code>document</code>. Leaves
- * leading comment signs alone.
- *
- * @param document the document
- * @param line the line
- * @param toDelete the number of space equivalents to delete.
- * @param indentInsideLineComments option whether to indent inside line comments starting at column 0
- * @throws BadLocationException on concurrent document modification
- */
- private void cutIndent(Document document, int line, int toDelete, boolean indentInsideLineComments) throws BadLocationException {
- IRegion region= document.getLineInformation(line);
- int from= region.getOffset();
- int endOffset= region.getOffset() + region.getLength();
-
- if (indentInsideLineComments) {
- // go behind line comments
- while (from < endOffset - 2 && document.get(from, 2).equals(LINE_COMMENT))
- from += 2;
- }
-
- int to= from;
- while (toDelete > 0 && to < endOffset) {
- char ch= document.getChar(to);
- if (!Character.isWhitespace(ch))
- break;
- toDelete -= computeVisualLength(ch);
- if (toDelete >= 0)
- to++;
- else
- break;
- }
-
- document.replace(from, to - from, null);
- }
-
- /**
- * Returns the visual length of a given <code>CharSequence</code> taking into
- * account the visual tabulator length.
- *
- * @param seq the string to measure
- * @return the visual length of <code>seq</code>
- */
- private int computeVisualLength(CharSequence seq) {
- int size= 0;
- int tablen= getVisualTabLengthPreference();
-
- for (int i= 0; i < seq.length(); i++) {
- char ch= seq.charAt(i);
- if (ch == '\t') {
- if (tablen != 0)
- size += tablen - size % tablen;
- // else: size stays the same
- } else {
- size++;
- }
- }
- return size;
- }
-
- /**
- * Returns the visual length of a given character taking into
- * account the visual tabulator length.
- *
- * @param ch the character to measure
- * @return the visual length of <code>ch</code>
- */
- private int computeVisualLength(char ch) {
- if (ch == '\t')
- return getVisualTabLengthPreference();
- return 1;
- }
-
- /**
- * The preference setting for the visual tabulator display.
- *
- * @return the number of spaces displayed for a tabulator in the editor
- */
- private int getVisualTabLengthPreference() {
- return CodeFormatterUtil.getTabWidth();
- }
-
- private int getPeerPosition(IDocument document, DocumentCommand command) {
- if (document.getLength() == 0)
- return 0;
- /*
- * Search for scope closers in the pasted text and find their opening peers
- * in the document.
- */
- Document pasted= new Document(command.text);
- installPartitioner(pasted);
- int firstPeer= command.offset;
-
- STPHeuristicScanner pScanner= new STPHeuristicScanner(pasted);
- STPHeuristicScanner dScanner= new STPHeuristicScanner(document);
-
- // add scope relevant after context to peer search
- int afterToken= dScanner.nextToken(command.offset + command.length, STPHeuristicScanner.UNBOUND);
- try {
- switch (afterToken) {
- case STPSymbols.TokenRBRACE:
- pasted.replace(pasted.getLength(), 0, "}"); //$NON-NLS-1$
- break;
- case STPSymbols.TokenRPAREN:
- pasted.replace(pasted.getLength(), 0, ")"); //$NON-NLS-1$
- break;
- case STPSymbols.TokenRBRACKET:
- pasted.replace(pasted.getLength(), 0, "]"); //$NON-NLS-1$
- break;
- }
- } catch (BadLocationException e) {
- // cannot happen
- Assert.isTrue(false);
- }
-
- int pPos= 0; // paste text position (increasing from 0)
- int dPos= Math.max(0, command.offset - 1); // document position (decreasing from paste offset)
- while (true) {
- int token= pScanner.nextToken(pPos, STPHeuristicScanner.UNBOUND);
- pPos= pScanner.getPosition();
- switch (token) {
- case STPSymbols.TokenLBRACE:
- case STPSymbols.TokenLBRACKET:
- case STPSymbols.TokenLPAREN:
- pPos= skipScope(pScanner, pPos, token);
- if (pPos == STPHeuristicScanner.NOT_FOUND)
- return firstPeer;
- break; // closed scope -> keep searching
- case STPSymbols.TokenRBRACE:
- int peer= dScanner.findOpeningPeer(dPos, '{', '}');
- dPos= peer - 1;
- if (peer == STPHeuristicScanner.NOT_FOUND)
- return firstPeer;
- firstPeer= peer;
- break; // keep searching
- case STPSymbols.TokenRBRACKET:
- peer= dScanner.findOpeningPeer(dPos, '[', ']');
- dPos= peer - 1;
- if (peer == STPHeuristicScanner.NOT_FOUND)
- return firstPeer;
- firstPeer= peer;
- break; // keep searching
- case STPSymbols.TokenRPAREN:
- peer= dScanner.findOpeningPeer(dPos, '(', ')');
- dPos= peer - 1;
- if (peer == STPHeuristicScanner.NOT_FOUND)
- return firstPeer;
- firstPeer= peer;
- break; // keep searching
-
- case STPSymbols.TokenCASE:
- case STPSymbols.TokenDEFAULT:
- {
- STPIndenter indenter= new STPIndenter(document, dScanner, fProject);
- peer= indenter.findReferencePosition(dPos, false, MatchMode.MATCH_CASE);
- if (peer == STPHeuristicScanner.NOT_FOUND)
- return firstPeer;
- firstPeer= peer;
- }
- break; // keep searching
-
- case STPSymbols.TokenPUBLIC:
- case STPSymbols.TokenPROTECTED:
- case STPSymbols.TokenPRIVATE:
- {
- STPIndenter indenter= new STPIndenter(document, dScanner, fProject);
- peer= indenter.findReferencePosition(dPos, false, MatchMode.MATCH_ACCESS_SPECIFIER);
- if (peer == STPHeuristicScanner.NOT_FOUND)
- return firstPeer;
- firstPeer= peer;
- }
- break; // keep searching
-
- case STPSymbols.TokenEOF:
- return firstPeer;
- default:
- // keep searching
- }
- }
+ DefaultIndentLineAutoEditStrategy {
+ private static final String LINE_COMMENT= "//"; //$NON-NLS-1$
+ private boolean fCloseBrace = true;
+
+ private String fPartitioning;
+ private IProject fProject;
+
+ public STPAutoEditStrategy(String fPartitioning, IProject project) {
+ this.fPartitioning = fPartitioning;
+ this.fProject = project;
+ }
+
+ /**
+ * Returns the block balance, i.e. zero if the blocks are balanced at
+ * <code>offset</code>, a negative number if there are more closing than opening
+ * braces, and a positive number if there are more opening than closing braces.
+ *
+ * @param document
+ * @param offset
+ * @param partitioning
+ * @return the block balance
+ */
+ private static int getBlockBalance(IDocument document, int offset, String partitioning) {
+ if (offset < 1)
+ return -1;
+ if (offset >= document.getLength())
+ return 1;
+
+ int begin = offset;
+ int end = offset - 1;
+
+ STPHeuristicScanner scanner = new STPHeuristicScanner(document);
+
+ while (true) {
+ begin = scanner.findOpeningPeer(begin - 1, '{', '}');
+ end = scanner.findClosingPeer(end + 1, '{', '}');
+ if (begin == -1 && end == -1)
+ return 0;
+ if (begin == -1)
+ return -1;
+ if (end == -1)
+ return 1;
+ }
+ }
+
+ @Override
+ public void customizeDocumentCommand(IDocument document,
+ DocumentCommand command) {
+ boolean modified = false;
+ boolean isNewLine= command.length == 0 && command.text != null
+ && isLineDelimiter(document, command.text);
+ if (isNewLine) {
+ smartIndentAfterNewLine(document, command);
+ } else if (command.text.length() == 1) {
+ smartIndentOnKeypress(document, command);
+ } else if (command.text.length() > 1
+ && command.text.trim().length() != 0) {
+ smartPaste(document, command); // no smart backspace for paste
+ }
+ if (command.text.equals("\"") && !inStringOrComment(document, command)) { //$NON-NLS-1$
+ command.text = "\"\""; //$NON-NLS-1$
+ modified = true;
+ } else if (command.text.equals("(") && !inStringOrComment(document, command)) { //$NON-NLS-1$
+ command.text = "()"; //$NON-NLS-1$
+ modified = true;
+ } else if (command.text.equals("[") && !inStringOrComment(document, command)) { //$NON-NLS-1$
+ command.text = "[]"; //$NON-NLS-1$
+ modified = true;
+ }
+
+ if (modified) {
+ command.caretOffset = command.offset + 1;
+ command.shiftsCaret = false;
+ }
+
+ super.customizeDocumentCommand(document, command);
+ }
+
+ private boolean inStringOrComment(IDocument d, DocumentCommand c) {
+ int docLength = d.getLength();
+ if (c.offset == -1 || docLength == 0)
+ return false;
+ try {
+ ITypedRegion partition= TextUtilities.getPartition(d, fPartitioning, c.offset, false);
+ String partitionType = partition.getType();
+ if (c.offset > 0 &&
+ (STPPartitionScanner.STP_COMMENT.equals(partitionType)
+ || STPPartitionScanner.STP_MULTILINE_COMMENT.equals(partitionType)
+ || STPPartitionScanner.STP_STRING.equals(partitionType))) {
+ return true;
+ }
+ IRegion lineInfo = d.getLineInformationOfOffset(c.offset);
+ int offset = lineInfo.getOffset();
+ boolean inChar = false;
+ boolean inString = false;
+ boolean inComment = false;
+ for (int i = offset; i < c.offset; ++i) {
+ char ch = d.getChar(i);
+ switch (ch) {
+ case '\"':
+ if (!inChar)
+ inString = !inString;
+ break;
+ case '\'':
+ if (!inString)
+ inChar = !inChar;
+ break;
+ case '\\':
+ ++i;
+ break;
+ case '/':
+ if (!inString && !inChar) {
+ ch = d.getChar(i + 1);
+ if (ch == '/')
+ return true; // We have a line comment
+ else if (ch == '*')
+ inComment = true;
+ }
+ break;
+ case '#':
+ if (!inString && !inChar)
+ return true;
+ break;
+ case '*':
+ if (!inString && !inChar) {
+ if (inComment) {
+ ch = d.getChar(i + 1);
+ if (ch == '/')
+ inComment = false;
+ }
+ }
+ break;
+ }
+ }
+ return inString || inChar || inComment;
+
+ } catch (BadLocationException e) {
+ IDEPlugin.log(e);
+ }
+ return false;
+ }
+
+
+ private void smartIndentAfterNewLine(IDocument d, DocumentCommand c) {
+ int docLength = d.getLength();
+ if (c.offset == -1 || docLength == 0)
+ return;
+
+ int addIndent= 0;
+ STPHeuristicScanner scanner= new STPHeuristicScanner(d);
+ try {
+ ITypedRegion partition= TextUtilities.getPartition(d, fPartitioning, c.offset, false);
+ if (STPPartitionScanner.STP_CONDITIONAL.equals(partition.getType()) && c.offset > 0 && d.getChar(c.offset-1) == '\\') {
+ scanner = new STPHeuristicScanner(d, fPartitioning, STPPartitionScanner.STP_CONDITIONAL);
+ addIndent= 1;
+ }
+
+ int line = d.getLineOfOffset(c.offset);
+ IRegion reg = d.getLineInformation(line);
+ int start = reg.getOffset();
+ int lineEnd = start + reg.getLength();
+
+ StringBuilder indent= null;
+ STPIndenter indenter= new STPIndenter(d, scanner, fProject);
+ indent= indenter.computeIndentation(c.offset);
+ if (indent == null) {
+ indent= new StringBuilder();
+ }
+ if (addIndent > 0 && indent.length() == 0) {
+ indent= indenter.createReusingIndent(indent, addIndent, 0);
+ }
+
+ StringBuilder buf = new StringBuilder(c.text + indent);
+ int contentStart = findEndOfWhiteSpace(d, c.offset, lineEnd);
+ c.length = Math.max(contentStart - c.offset, 0);
+
+ // insert closing brace on new line after an unclosed opening brace
+ if (getBracketCount(d, start, c.offset, true) > 0 && fCloseBrace && !isClosedBrace(d, c.offset)) {
+ c.caretOffset = c.offset + buf.length();
+ c.shiftsCaret = false;
+
+ // copy old content of line behind insertion point to new line
+ // unless we think we are inserting an anonymous type definition
+ if (c.offset == 0 || !(computeAnonymousPosition(d, c.offset - 1, fPartitioning, lineEnd) != -1)) {
+ if (lineEnd - contentStart > 0) {
+ c.length = lineEnd - c.offset;
+ buf.append(d.get(contentStart, lineEnd - contentStart).toCharArray());
+ }
+ }
+
+ buf.append(TextUtilities.getDefaultLineDelimiter(d));
+ StringBuilder reference = null;
+ int nonWS = findEndOfWhiteSpace(d, start, lineEnd);
+ if (nonWS < c.offset && d.getChar(nonWS) == '{')
+ reference = new StringBuilder(d.get(start, nonWS - start));
+ else
+ reference = indenter.getReferenceIndentation(c.offset);
+ if (reference != null)
+ buf.append(reference);
+ buf.append('}');
+ int bound= c.offset > 200 ? c.offset - 200 : STPHeuristicScanner.UNBOUND;
+ int bracePos = scanner.findOpeningPeer(c.offset - 1, bound, '{', '}');
+ if (bracePos != STPHeuristicScanner.NOT_FOUND) {
+ if (scanner.looksLikeCompositeTypeDefinitionBackward(bracePos, bound) ||
+ scanner.previousToken(bracePos - 1, bound) == STPSymbols.TokenEQUAL) {
+ buf.append(';');
+ }
+ }
+ }
+ // insert extra line upon new line between two braces
+ else if (c.offset > start && contentStart < lineEnd && d.getChar(contentStart) == '}') {
+ int firstCharPos = scanner.findNonWhitespaceBackward(c.offset - 1, start);
+ if (firstCharPos != STPHeuristicScanner.NOT_FOUND && d.getChar(firstCharPos) == '{') {
+ c.caretOffset = c.offset + buf.length();
+ c.shiftsCaret = false;
+
+ StringBuilder reference = null;
+ int nonWS = findEndOfWhiteSpace(d, start, lineEnd);
+ if (nonWS < c.offset && d.getChar(nonWS) == '{')
+ reference = new StringBuilder(d.get(start, nonWS - start));
+ else
+ reference = indenter.getReferenceIndentation(c.offset);
+
+ buf.append(TextUtilities.getDefaultLineDelimiter(d));
+
+ if (reference != null)
+ buf.append(reference);
+ }
+ }
+ c.text = buf.toString();
+
+ } catch (BadLocationException e) {
+ IDEPlugin.log(e);
+ }
+ }
+
+ private void smartIndentUponE(IDocument doc, DocumentCommand c) {
+ if (c.offset < 4 || doc.getLength() == 0)
+ return;
+
+ try {
+ String content = doc.get(c.offset - 3, 3);
+ if (content.equals("els")) { //$NON-NLS-1$
+ STPHeuristicScanner scanner = new STPHeuristicScanner(doc);
+ int p = c.offset - 3;
+
+ // current line
+ int line = doc.getLineOfOffset(p);
+ int lineOffset = doc.getLineOffset(line);
+
+ // make sure we don't have any leading comments etc.
+ if (doc.get(lineOffset, p - lineOffset).trim().length() != 0)
+ return;
+
+ // Line of last C code
+ int pos = scanner.findNonWhitespaceBackward(p - 1, STPHeuristicScanner.UNBOUND);
+ if (pos == -1)
+ return;
+ int lastLine = doc.getLineOfOffset(pos);
+
+ // Only shift if the last C line is further up and is a braceless block candidate
+ if (lastLine < line) {
+ STPIndenter indenter = new STPIndenter(doc, scanner, fProject);
+ int ref = indenter.findReferencePosition(p, true, MatchMode.REGULAR);
+ if (ref == STPHeuristicScanner.NOT_FOUND)
+ return;
+ int refLine = doc.getLineOfOffset(ref);
+ String indent = getIndentOfLine(doc, refLine);
+
+ if (indent != null) {
+ c.text = indent + "else"; //$NON-NLS-1$
+ c.length += c.offset - lineOffset;
+ c.offset = lineOffset;
+ }
+ }
+
+ return;
+ }
+
+ if (content.equals("cas")) { //$NON-NLS-1$
+ STPHeuristicScanner scanner = new STPHeuristicScanner(doc);
+ int p = c.offset - 3;
+
+ // current line
+ int line = doc.getLineOfOffset(p);
+ int lineOffset = doc.getLineOffset(line);
+
+ // make sure we don't have any leading comments etc.
+ if (doc.get(lineOffset, p - lineOffset).trim().length() != 0)
+ return;
+
+ // Line of last C code
+ int pos = scanner.findNonWhitespaceBackward(p - 1, STPHeuristicScanner.UNBOUND);
+ if (pos == -1)
+ return;
+ int lastLine = doc.getLineOfOffset(pos);
+
+ // Only shift if the last C line is further up and is a braceless block candidate
+ if (lastLine < line) {
+ STPIndenter indenter = new STPIndenter(doc, scanner, fProject);
+ int ref = indenter.findReferencePosition(p, false, MatchMode.MATCH_CASE);
+ if (ref == STPHeuristicScanner.NOT_FOUND)
+ return;
+ int refLine = doc.getLineOfOffset(ref);
+ int nextToken = scanner.nextToken(ref, STPHeuristicScanner.UNBOUND);
+ String indent;
+ if (nextToken == STPSymbols.TokenCASE || nextToken == STPSymbols.TokenDEFAULT)
+ indent = getIndentOfLine(doc, refLine);
+ else // at the brace of the switch
+ indent = indenter.computeIndentation(p).toString();
+
+ if (indent != null) {
+ c.text = indent.toString() + "case"; //$NON-NLS-1$
+ c.length += c.offset - lineOffset;
+ c.offset = lineOffset;
+ }
+ }
+
+ return;
+ }
+ } catch (BadLocationException e) {
+ IDEPlugin.log(e);
+ }
+ }
+ /**
+ * Computes an insert position for an opening brace if <code>offset</code> maps to a position in
+ * <code>document</code> with a expression in parenthesis that will take a block after the closing parenthesis.
+ *
+ * @param document the document being modified
+ * @param offset the offset of the caret position, relative to the line start.
+ * @param partitioning the document partitioning
+ * @param max the max position
+ * @return an insert position relative to the line start if <code>line</code> contains a parenthesized expression that can be followed by a block, -1 otherwise
+ */
+ private static int computeAnonymousPosition(IDocument document, int offset, String partitioning, int max) {
+ // find the opening parenthesis for every closing parenthesis on the current line after offset
+ // return the position behind the closing parenthesis if it looks like a method declaration
+ // or an expression for an if, while, for, catch statement
+
+ STPHeuristicScanner scanner = new STPHeuristicScanner(document);
+ int pos = offset;
+ int length = max;
+ int scanTo = scanner.scanForward(pos, length, '}');
+ if (scanTo == -1)
+ scanTo = length;
+
+ int closingParen = findClosingParenToLeft(scanner, pos) - 1;
+
+ while (true) {
+ int startScan = closingParen + 1;
+ closingParen = scanner.scanForward(startScan, scanTo, ')');
+ if (closingParen == -1)
+ break;
+
+ int openingParen = scanner.findOpeningPeer(closingParen - 1, '(', ')');
+
+ // no way an expression at the beginning of the document can mean anything
+ if (openingParen < 1)
+ break;
+
+ // only select insert positions for parenthesis currently embracing the caret
+ if (openingParen > pos)
+ continue;
+ }
+
+ return -1;
+ }
+
+ /**
+ * Finds a closing parenthesis to the left of <code>position</code> in document, where that parenthesis is only
+ * separated by whitespace from <code>position</code>. If no such parenthesis can be found, <code>position</code> is returned.
+ *
+ * @param scanner the C heuristic scanner set up on the document
+ * @param position the first character position in <code>document</code> to be considered
+ * @return the position of a closing parenthesis left to <code>position</code> separated only by whitespace, or <code>position</code> if no parenthesis can be found
+ */
+ private static int findClosingParenToLeft(STPHeuristicScanner scanner, int position) {
+ if (position < 1)
+ return position;
+
+ if (scanner.previousToken(position - 1, STPHeuristicScanner.UNBOUND) == STPSymbols.TokenRPAREN)
+ return scanner.getPosition() + 1;
+ return position;
+ }
+
+ private boolean isClosedBrace(IDocument document, int offset) {
+ return getBlockBalance(document, offset, fPartitioning) <= 0;
+ }
+
+ private void smartIndentOnKeypress(IDocument document, DocumentCommand command) {
+ switch (command.text.charAt(0)) {
+ case '}':
+ smartIndentAfterClosingBracket(document, command);
+ break;
+ case '{':
+ smartIndentAfterOpeningBracket(document, command);
+ break;
+ case 'e':
+ smartIndentUponE(document, command);
+ break;
+ case '#':
+ smartIndentAfterHash(document, command);
+ break;
+ case '\"':
+ smartInsertCloseChar(document, command, '\"');
+ break;
+ case ')':
+ smartInsertCloseChar(document, command, ')');
+ break;
+ case ']':
+ smartInsertCloseChar(document, command, ']');
+ break;
+ }
+ }
+
+ /**
+ * A closing char (e.g. right paren ')') is being inserted. If one already exists
+ * at current location in the document, skip over it and don't do an
+ * insert.
+ *
+ * @param d - document
+ * @param c - insert text
+ * @param ch - closing char being inserted
+ */
+ private void smartInsertCloseChar(IDocument d, DocumentCommand c, char ch) {
+ if (c.offset < 1 || d.getLength() == 0)
+ return;
+
+ try {
+ if (d.getChar(c.offset) == ch) {
+ int backslashCount = 0;
+ int prevOffset = c.offset - 1;
+ // Look backwards for backslashes. We will ignore if there are even number
+ while (prevOffset > 0 && d.getChar(prevOffset) == '\\') {
+ --prevOffset;
+ ++backslashCount;
+ }
+ if ((backslashCount & 1) == 0) {
+ c.text = ""; //$NON-NLS-1$
+ c.offset++;
+ }
+ }
+ } catch (BadLocationException e) {
+ IDEPlugin.log(e);
+ }
+
+ }
+
+ private void smartIndentAfterHash(IDocument doc, DocumentCommand c) {
+ try {
+ ITypedRegion partition= TextUtilities.getPartition(doc, fPartitioning, c.offset, false);
+ if (IDocument.DEFAULT_CONTENT_TYPE.equals(partition.getType())) {
+ IRegion startLine= doc.getLineInformationOfOffset(c.offset);
+ String indent= doc.get(startLine.getOffset(), c.offset - startLine.getOffset());
+ if (indent.trim().length() == 0) {
+ c.offset -= indent.length();
+ c.length += indent.length();
+ }
+ }
+ } catch (BadLocationException e) {
+ IDEPlugin.log(e);
+ }
+ }
+
+ private void smartIndentAfterOpeningBracket(IDocument d, DocumentCommand c) {
+ if (c.offset < 1 || d.getLength() == 0)
+ return;
+
+ int p = (c.offset == d.getLength() ? c.offset - 1 : c.offset);
+
+ try {
+ STPHeuristicScanner scanner= new STPHeuristicScanner(d);
+ ITypedRegion partition= TextUtilities.getPartition(d, fPartitioning, p, false);
+ if (STPPartitionScanner.STP_CONDITIONAL.equals(partition.getType())) {
+ scanner = new STPHeuristicScanner(d, fPartitioning, STPPartitionScanner.STP_CONDITIONAL);
+ }
+ // current line
+ int line = d.getLineOfOffset(c.offset);
+ int lineOffset = d.getLineOffset(line);
+
+ // make sure we don't have any leading comments etc.
+ if (!d.get(lineOffset, c.offset - lineOffset).trim().isEmpty())
+ return;
+
+ // Line of last C code
+ int pos = scanner.findNonWhitespaceBackward(p, STPHeuristicScanner.UNBOUND);
+ if (pos == -1)
+ return;
+ int lastLine = d.getLineOfOffset(pos);
+
+ // Only shift if the last C line is further up and is a braceless block candidate
+ if (lastLine < line) {
+ STPIndenter indenter = new STPIndenter(d, scanner, fProject);
+ StringBuilder indent = indenter.computeIndentation(p, true);
+ String toDelete = d.get(lineOffset, c.offset - lineOffset);
+ if (indent != null && !indent.toString().equals(toDelete)) {
+ c.text = indent.append(c.text).toString();
+ c.length += c.offset - lineOffset;
+ c.offset = lineOffset;
+ }
+ }
+ } catch (BadLocationException e) {
+ IDEPlugin.log(e);
+ }
+ }
+
+ private boolean isLineDelimiter(IDocument document, String text) {
+ String[] delimiters = document.getLegalLineDelimiters();
+ if (delimiters != null)
+ return TextUtilities.equals(delimiters, text) > -1;
+ return false;
+ }
+
+ private int getBracketCount(IDocument d, int start, int end, boolean ignoreCloseBrackets) throws BadLocationException {
+ int bracketcount = 0;
+ while (start < end) {
+ char curr = d.getChar(start);
+ start++;
+ switch (curr) {
+ case '#' :
+ if (start < end) {
+ // '#'-comment: nothing to do anymore on this line
+ start = end;
+ }
+ break;
+ case '/' :
+ if (start < end) {
+ char next = d.getChar(start);
+ if (next == '*') {
+ // a comment starts, advance to the comment end
+ start = getCommentEnd(d, start + 1, end);
+ } else if (next == '/') {
+ // '//'-comment: nothing to do anymore on this line
+ start = end;
+ }
+ }
+ break;
+ case '*' :
+ if (start < end) {
+ char next = d.getChar(start);
+ if (next == '/') {
+ // we have been in a comment: forget what we read before
+ bracketcount = 0;
+ start++;
+ }
+ }
+ break;
+ case '{' :
+ bracketcount++;
+ ignoreCloseBrackets = false;
+ break;
+ case '}' :
+ if (!ignoreCloseBrackets) {
+ bracketcount--;
+ }
+ break;
+ case '"' :
+ case '\'' :
+ start = getStringEnd(d, start, end, curr);
+ break;
+ default :
+ }
+ }
+ return bracketcount;
+ }
+
+
+ // ----------- bracket counting ------------------------------------------------------
+
+ private int getCommentEnd(IDocument d, int pos, int end) throws BadLocationException {
+ while (pos < end) {
+ char curr = d.getChar(pos);
+ pos++;
+ if (curr == '*') {
+ if (pos < end && d.getChar(pos) == '/') {
+ return pos + 1;
+ }
+ }
+ }
+ return end;
+ }
+
+ private String getIndentOfLine(IDocument d, int line) throws BadLocationException {
+ if (line > -1) {
+ int start = d.getLineOffset(line);
+ int end = start + d.getLineLength(line) - 1;
+ int whiteend = findEndOfWhiteSpace(d, start, end);
+ return d.get(start, whiteend - start);
+ }
+ return ""; //$NON-NLS-1$
+ }
+
+ private int getStringEnd(IDocument d, int pos, int end, char ch) throws BadLocationException {
+ while (pos < end) {
+ char curr = d.getChar(pos);
+ pos++;
+ if (curr == '\\') {
+ // ignore escaped characters
+ pos++;
+ } else if (curr == ch) {
+ return pos;
+ }
+ }
+ return end;
+ }
+ private void smartIndentAfterClosingBracket(IDocument d, DocumentCommand c) {
+ if (c.offset == -1 || d.getLength() == 0)
+ return;
+
+ try {
+ int p = (c.offset == d.getLength() ? c.offset - 1 : c.offset);
+ int line = d.getLineOfOffset(p);
+ int start = d.getLineOffset(line);
+ int whiteend = findEndOfWhiteSpace(d, start, c.offset);
+
+ STPHeuristicScanner scanner= new STPHeuristicScanner(d);
+ ITypedRegion partition= TextUtilities.getPartition(d, fPartitioning, p, false);
+ if (STPPartitionScanner.STP_CONDITIONAL.equals(partition.getType())) {
+ scanner = new STPHeuristicScanner(d, fPartitioning, STPPartitionScanner.STP_CONDITIONAL);
+ }
+ STPIndenter indenter = new STPIndenter(d, scanner, fProject);
+
+ // shift only when line does not contain any text up to the closing bracket
+ if (whiteend == c.offset) {
+ // evaluate the line with the opening bracket that matches out closing bracket
+ int reference = indenter.findReferencePosition(c.offset, false, MatchMode.MATCH_BRACE);
+ int indLine = d.getLineOfOffset(reference);
+ if (indLine != -1 && indLine != line) {
+ // take the indent of the found line
+ StringBuilder replaceText = new StringBuilder(getIndentOfLine(d, indLine));
+ // add the rest of the current line including the just added close bracket
+ replaceText.append(d.get(whiteend, c.offset - whiteend));
+ replaceText.append(c.text);
+ // modify document command
+ c.length += c.offset - start;
+ c.offset = start;
+ c.text = replaceText.toString();
+ }
+ }
+ } catch (BadLocationException e) {
+ IDEPlugin.log(e);
+ }
+ }
+
+ /**
+ * Installs a C partitioner with <code>document</code>.
+ *
+ * @param document the document
+ */
+ private static void installPartitioner(Document document) {
+ String[] types= new String[] {
+ IDocument.DEFAULT_CONTENT_TYPE,
+ STPPartitionScanner.STP_COMMENT,
+ STPPartitionScanner.STP_CONDITIONAL,
+ };
+ FastPartitioner partitioner= new FastPartitioner(new STPPartitionScanner(), types);
+ partitioner.connect(document);
+ document.setDocumentPartitioner(STPPartitionScanner.STP_PARTITIONING, partitioner);
+ }
+
+ /**
+ * Installs a C partitioner with <code>document</code>.
+ *
+ * @param document the document
+ */
+ private static void removePartitioner(Document document) {
+ document.setDocumentPartitioner(STPPartitionScanner.STP_PARTITIONING, null);
+ }
+
+ private void smartPaste(IDocument document, DocumentCommand command) {
+ int newOffset= command.offset;
+ int newLength= command.length;
+ String newText= command.text;
+
+ try {
+ STPHeuristicScanner scanner= new STPHeuristicScanner(document);
+ STPIndenter indenter= new STPIndenter(document, scanner, fProject);
+ int offset= newOffset;
+
+ // reference position to get the indent from
+ int refOffset= indenter.findReferencePosition(offset);
+ if (refOffset == STPHeuristicScanner.NOT_FOUND)
+ return;
+ int peerOffset= getPeerPosition(document, command);
+ peerOffset= indenter.findReferencePosition(peerOffset);
+ if (peerOffset == STPHeuristicScanner.NOT_FOUND)
+ return;
+ refOffset= Math.min(refOffset, peerOffset);
+
+ // eat any WS before the insertion to the beginning of the line
+ int firstLine= 1; // don't format the first line per default, as it has other content before it
+ IRegion line= document.getLineInformationOfOffset(offset);
+ String notSelected= document.get(line.getOffset(), offset - line.getOffset());
+ if (notSelected.trim().length() == 0) {
+ newLength += notSelected.length();
+ newOffset= line.getOffset();
+ firstLine= 0;
+ }
+
+ // Prefix: the part we need for formatting but won't paste.
+ // Take up to 100 previous lines to preserve enough context.
+ int firstPrefixLine= Math.max(document.getLineOfOffset(refOffset) - 100, 0);
+ int prefixOffset= document.getLineInformation(firstPrefixLine).getOffset();
+ String prefix= document.get(prefixOffset, newOffset - prefixOffset);
+
+ // Handle the indentation computation inside a temporary document
+ Document temp= new Document(prefix + newText);
+ DocumentRewriteSession session= temp.startRewriteSession(DocumentRewriteSessionType.STRICTLY_SEQUENTIAL);
+ scanner= new STPHeuristicScanner(temp);
+ indenter= new STPIndenter(temp, scanner, fProject);
+ installPartitioner(temp);
+
+ // Indent the first and second line
+ // compute the relative indentation difference from the second line
+ // (as the first might be partially selected) and use the value to
+ // indent all other lines.
+ boolean isIndentDetected= false;
+ StringBuilder addition= new StringBuilder();
+ int insertLength= 0;
+ int first= document.computeNumberOfLines(prefix) + firstLine; // don't format first line
+ int lines= temp.getNumberOfLines();
+ boolean changed= false;
+ boolean indentInsideLineComments= true;
+
+ for (int l= first; l < lines; l++) { // we don't change the number of lines while adding indents
+ IRegion r= temp.getLineInformation(l);
+ int lineOffset= r.getOffset();
+ int lineLength= r.getLength();
+
+ if (lineLength == 0) // don't modify empty lines
+ continue;
+
+ if (!isIndentDetected) {
+ // indent the first pasted line
+ String current= IndentUtil.getCurrentIndent(temp, l, indentInsideLineComments);
+ StringBuilder correct= new StringBuilder(IndentUtil.computeIndent(temp, l, indenter, scanner));
+
+ insertLength= subtractIndent(correct, current, addition);
+ // workaround for bug 181139
+ if (/*l != first && */temp.get(lineOffset, lineLength).trim().length() != 0) {
+ isIndentDetected= true;
+ if (insertLength == 0) {
+ // no adjustment needed, bail out
+ if (firstLine == 0) {
+ // but we still need to adjust the first line
+ command.offset= newOffset;
+ command.length= newLength;
+ if (changed)
+ break; // still need to get the leading indent of the first line
+ }
+ return;
+ }
+ removePartitioner(temp);
+ } else {
+ changed= insertLength != 0;
+ }
+ }
+
+ // relatively indent all pasted lines
+ if (insertLength > 0)
+ addIndent(temp, l, addition, indentInsideLineComments);
+ else if (insertLength < 0)
+ cutIndent(temp, l, -insertLength, indentInsideLineComments);
+ }
+
+ temp.stopRewriteSession(session);
+ newText= temp.get(prefix.length(), temp.getLength() - prefix.length());
+
+ command.offset= newOffset;
+ command.length= newLength;
+ command.text= newText;
+ } catch (BadLocationException e) {
+ IDEPlugin.log(e);
+ }
+ }
+ /**
+ * Computes the difference of two indentations and returns the difference in
+ * length of current and correct. If the return value is positive, <code>addition</code>
+ * is initialized with a substring of that length of <code>correct</code>.
+ *
+ * @param correct the correct indentation
+ * @param current the current indentation (migth contain non-whitespace)
+ * @param difference a string buffer - if the return value is positive, it will be cleared and set to the substring of <code>current</code> of that length
+ * @return the difference in lenght of <code>correct</code> and <code>current</code>
+ */
+ private int subtractIndent(CharSequence correct, CharSequence current, StringBuilder difference) {
+ int c1= computeVisualLength(correct);
+ int c2= computeVisualLength(current);
+ int diff= c1 - c2;
+ if (diff <= 0)
+ return diff;
+
+ difference.setLength(0);
+ int len= 0, i= 0;
+ while (len < diff) {
+ char c= correct.charAt(i++);
+ difference.append(c);
+ len += computeVisualLength(c);
+ }
+
+ return diff;
+ }
+
+ /**
+ * Indents line <code>line</code> in <code>document</code> with <code>indent</code>.
+ * Leaves leading comment signs alone.
+ *
+ * @param document the document
+ * @param line the line
+ * @param indent the indentation to insert
+ * @param indentInsideLineComments option whether to indent inside line comments starting at column 0
+ * @throws BadLocationException on concurrent document modification
+ */
+ private static void addIndent(Document document, int line, CharSequence indent, boolean indentInsideLineComments) throws BadLocationException {
+ IRegion region= document.getLineInformation(line);
+ int insert= region.getOffset();
+ int endOffset= region.getOffset() + region.getLength();
+
+ if (indentInsideLineComments) {
+ // go behind line comments
+ while (insert < endOffset - 2 && document.get(insert, 2).equals(LINE_COMMENT))
+ insert += 2;
+ }
+
+ // insert indent
+ document.replace(insert, 0, indent.toString());
+ }
+
+ /**
+ * Cuts the visual equivalent of <code>toDelete</code> characters out of the
+ * indentation of line <code>line</code> in <code>document</code>. Leaves
+ * leading comment signs alone.
+ *
+ * @param document the document
+ * @param line the line
+ * @param toDelete the number of space equivalents to delete.
+ * @param indentInsideLineComments option whether to indent inside line comments starting at column 0
+ * @throws BadLocationException on concurrent document modification
+ */
+ private void cutIndent(Document document, int line, int toDelete, boolean indentInsideLineComments) throws BadLocationException {
+ IRegion region= document.getLineInformation(line);
+ int from= region.getOffset();
+ int endOffset= region.getOffset() + region.getLength();
+
+ if (indentInsideLineComments) {
+ // go behind line comments
+ while (from < endOffset - 2 && document.get(from, 2).equals(LINE_COMMENT))
+ from += 2;
+ }
+
+ int to= from;
+ while (toDelete > 0 && to < endOffset) {
+ char ch= document.getChar(to);
+ if (!Character.isWhitespace(ch))
+ break;
+ toDelete -= computeVisualLength(ch);
+ if (toDelete >= 0)
+ to++;
+ else
+ break;
+ }
+
+ document.replace(from, to - from, null);
+ }
+
+ /**
+ * Returns the visual length of a given <code>CharSequence</code> taking into
+ * account the visual tabulator length.
+ *
+ * @param seq the string to measure
+ * @return the visual length of <code>seq</code>
+ */
+ private int computeVisualLength(CharSequence seq) {
+ int size= 0;
+ int tablen= getVisualTabLengthPreference();
+
+ for (int i= 0; i < seq.length(); i++) {
+ char ch= seq.charAt(i);
+ if (ch == '\t') {
+ if (tablen != 0)
+ size += tablen - size % tablen;
+ // else: size stays the same
+ } else {
+ size++;
+ }
+ }
+ return size;
+ }
+
+ /**
+ * Returns the visual length of a given character taking into
+ * account the visual tabulator length.
+ *
+ * @param ch the character to measure
+ * @return the visual length of <code>ch</code>
+ */
+ private int computeVisualLength(char ch) {
+ if (ch == '\t')
+ return getVisualTabLengthPreference();
+ return 1;
+ }
+
+ /**
+ * The preference setting for the visual tabulator display.
+ *
+ * @return the number of spaces displayed for a tabulator in the editor
+ */
+ private int getVisualTabLengthPreference() {
+ return CodeFormatterUtil.getTabWidth();
+ }
+
+ private int getPeerPosition(IDocument document, DocumentCommand command) {
+ if (document.getLength() == 0)
+ return 0;
+ /*
+ * Search for scope closers in the pasted text and find their opening peers
+ * in the document.
+ */
+ Document pasted= new Document(command.text);
+ installPartitioner(pasted);
+ int firstPeer= command.offset;
+
+ STPHeuristicScanner pScanner= new STPHeuristicScanner(pasted);
+ STPHeuristicScanner dScanner= new STPHeuristicScanner(document);
+
+ // add scope relevant after context to peer search
+ int afterToken= dScanner.nextToken(command.offset + command.length, STPHeuristicScanner.UNBOUND);
+ try {
+ switch (afterToken) {
+ case STPSymbols.TokenRBRACE:
+ pasted.replace(pasted.getLength(), 0, "}"); //$NON-NLS-1$
+ break;
+ case STPSymbols.TokenRPAREN:
+ pasted.replace(pasted.getLength(), 0, ")"); //$NON-NLS-1$
+ break;
+ case STPSymbols.TokenRBRACKET:
+ pasted.replace(pasted.getLength(), 0, "]"); //$NON-NLS-1$
+ break;
+ }
+ } catch (BadLocationException e) {
+ // cannot happen
+ Assert.isTrue(false);
+ }
+
+ int pPos= 0; // paste text position (increasing from 0)
+ int dPos= Math.max(0, command.offset - 1); // document position (decreasing from paste offset)
+ while (true) {
+ int token= pScanner.nextToken(pPos, STPHeuristicScanner.UNBOUND);
+ pPos= pScanner.getPosition();
+ switch (token) {
+ case STPSymbols.TokenLBRACE:
+ case STPSymbols.TokenLBRACKET:
+ case STPSymbols.TokenLPAREN:
+ pPos= skipScope(pScanner, pPos, token);
+ if (pPos == STPHeuristicScanner.NOT_FOUND)
+ return firstPeer;
+ break; // closed scope -> keep searching
+ case STPSymbols.TokenRBRACE:
+ int peer= dScanner.findOpeningPeer(dPos, '{', '}');
+ dPos= peer - 1;
+ if (peer == STPHeuristicScanner.NOT_FOUND)
+ return firstPeer;
+ firstPeer= peer;
+ break; // keep searching
+ case STPSymbols.TokenRBRACKET:
+ peer= dScanner.findOpeningPeer(dPos, '[', ']');
+ dPos= peer - 1;
+ if (peer == STPHeuristicScanner.NOT_FOUND)
+ return firstPeer;
+ firstPeer= peer;
+ break; // keep searching
+ case STPSymbols.TokenRPAREN:
+ peer= dScanner.findOpeningPeer(dPos, '(', ')');
+ dPos= peer - 1;
+ if (peer == STPHeuristicScanner.NOT_FOUND)
+ return firstPeer;
+ firstPeer= peer;
+ break; // keep searching
+
+ case STPSymbols.TokenCASE:
+ case STPSymbols.TokenDEFAULT:
+ {
+ STPIndenter indenter= new STPIndenter(document, dScanner, fProject);
+ peer= indenter.findReferencePosition(dPos, false, MatchMode.MATCH_CASE);
+ if (peer == STPHeuristicScanner.NOT_FOUND)
+ return firstPeer;
+ firstPeer= peer;
+ }
+ break; // keep searching
+
+ case STPSymbols.TokenPUBLIC:
+ case STPSymbols.TokenPROTECTED:
+ case STPSymbols.TokenPRIVATE:
+ {
+ STPIndenter indenter= new STPIndenter(document, dScanner, fProject);
+ peer= indenter.findReferencePosition(dPos, false, MatchMode.MATCH_ACCESS_SPECIFIER);
+ if (peer == STPHeuristicScanner.NOT_FOUND)
+ return firstPeer;
+ firstPeer= peer;
+ }
+ break; // keep searching
+
+ case STPSymbols.TokenEOF:
+ return firstPeer;
+ default:
+ // keep searching
+ }
+ }
}
/**
* Skips the scope opened by <code>token</code> in <code>document</code>,
@@ -1047,39 +1047,39 @@ public class STPAutoEditStrategy extends
* @return the position after the scope
*/
private static int skipScope(STPHeuristicScanner scanner, int pos, int token) {
- int openToken= token;
- int closeToken;
- switch (token) {
- case STPSymbols.TokenLPAREN:
- closeToken= STPSymbols.TokenRPAREN;
- break;
- case STPSymbols.TokenLBRACKET:
- closeToken= STPSymbols.TokenRBRACKET;
- break;
- case STPSymbols.TokenLBRACE:
- closeToken= STPSymbols.TokenRBRACE;
- break;
- default:
- Assert.isTrue(false);
- return -1; // dummy
- }
-
- int depth= 1;
- int p= pos;
-
- while (true) {
- int tok= scanner.nextToken(p, STPHeuristicScanner.UNBOUND);
- p= scanner.getPosition();
-
- if (tok == openToken) {
- depth++;
- } else if (tok == closeToken) {
- depth--;
- if (depth == 0)
- return p + 1;
- } else if (tok == STPSymbols.TokenEOF) {
- return STPHeuristicScanner.NOT_FOUND;
- }
- }
+ int openToken= token;
+ int closeToken;
+ switch (token) {
+ case STPSymbols.TokenLPAREN:
+ closeToken= STPSymbols.TokenRPAREN;
+ break;
+ case STPSymbols.TokenLBRACKET:
+ closeToken= STPSymbols.TokenRBRACKET;
+ break;
+ case STPSymbols.TokenLBRACE:
+ closeToken= STPSymbols.TokenRBRACE;
+ break;
+ default:
+ Assert.isTrue(false);
+ return -1; // dummy
+ }
+
+ int depth= 1;
+ int p= pos;
+
+ while (true) {
+ int tok= scanner.nextToken(p, STPHeuristicScanner.UNBOUND);
+ p= scanner.getPosition();
+
+ if (tok == openToken) {
+ depth++;
+ } else if (tok == closeToken) {
+ depth--;
+ if (depth == 0)
+ return p + 1;
+ } else if (tok == STPSymbols.TokenEOF) {
+ return STPHeuristicScanner.NOT_FOUND;
+ }
+ }
}
} \ No newline at end of file
diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/STPColorConstants.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/STPColorConstants.java
index 97ca5e873d..e5287a63fd 100644
--- a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/STPColorConstants.java
+++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/STPColorConstants.java
@@ -1,23 +1,23 @@
/* Copyright (c) 2008 Phil Muldoon <pkmuldoon@picobot.org>.
- *
+ *
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
- * Phil Muldoon <pkmuldoon@picobot.org> - initial API and implementation.
+ * Phil Muldoon <pkmuldoon@picobot.org> - initial API and implementation.
*******************************************************************************/
package org.eclipse.linuxtools.internal.systemtap.ui.ide.editors.stp;
import org.eclipse.swt.graphics.RGB;
public interface STPColorConstants {
- RGB KEYWORD = new RGB(127, 0, 85);
- RGB COMMENT = new RGB(63, 127, 95);
- RGB STP_STRING = new RGB(0, 0, 255);
- RGB DEFAULT = new RGB(0, 0, 0);
- RGB EMBEDDED = new RGB (0, 64, 64);
+ RGB KEYWORD = new RGB(127, 0, 85);
+ RGB COMMENT = new RGB(63, 127, 95);
+ RGB STP_STRING = new RGB(0, 0, 255);
+ RGB DEFAULT = new RGB(0, 0, 0);
+ RGB EMBEDDED = new RGB (0, 64, 64);
RGB EMBEDDEDC = new RGB (0, 64, 64);
RGB TYPE= new RGB(0, 0, 128);
diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/STPCompletionProcessor.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/STPCompletionProcessor.java
index 3d9791b27a..feb2a11635 100644
--- a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/STPCompletionProcessor.java
+++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/STPCompletionProcessor.java
@@ -32,460 +32,460 @@ import org.eclipse.linuxtools.internal.systemtap.ui.ide.structures.TapsetLibrary
public class STPCompletionProcessor implements IContentAssistProcessor, ITextHover {
- private final IContextInformation[] NO_CONTEXTS = new IContextInformation[0];
- private final char[] PROPOSAL_ACTIVATION_CHARS = new char[] { '.' };
- private ICompletionProposal[] NO_COMPLETIONS = new ICompletionProposal[0];
-
- private static final String GLOBAL_KEYWORD = "global "; //$NON-NLS-1$
- private static final String PROBE_KEYWORD = "probe "; //$NON-NLS-1$
- private static final String FUNCTION_KEYWORD = "function "; //$NON-NLS-1$
-
- private static final String[][] GLOBAL_KEYWORDS = {
- { GLOBAL_KEYWORD, Messages.STPCompletionProcessor_global },
- { PROBE_KEYWORD, Messages.STPCompletionProcessor_probe },
- { FUNCTION_KEYWORD, Messages.STPCompletionProcessor_function } };
-
- private STPMetadataSingleton stpMetadataSingleton;
-
- private static class Token implements IRegion {
- String tokenString;
- int offset;
-
- public Token(String string, int n) {
- this.tokenString = string;
- this.offset = n;
- }
-
- @Override
- public int getLength() {
- return this.tokenString.length();
- }
-
- @Override
- public int getOffset() {
- return this.offset;
- }
- }
-
- public STPCompletionProcessor() {
- this.stpMetadataSingleton = STPMetadataSingleton.getInstance();
- }
-
- /* (non-Javadoc)
- * @see org.eclipse.jface.text.contentassist.IContentAssistProcessor#computeCompletionProposals(org.eclipse.jface.text.ITextViewer, int)
- */
- @Override
- public ICompletionProposal[] computeCompletionProposals(ITextViewer viewer,
- int offset) {
- return computeCompletionProposals(viewer.getDocument(), offset);
- }
-
- public ICompletionProposal[] computeCompletionProposals(IDocument document, int offset) {
-
- ITypedRegion partition = null;
- boolean useGlobal = false;
-
- try {
- partition =
- ((IDocumentExtension3) document).getPartition(STPProbeScanner.STP_PROBE_PARTITIONING, offset, false);
- if (partition.getOffset() == offset) {
- if (partition.getType() != IDocument.DEFAULT_CONTENT_TYPE && partition.getType() != STPProbeScanner.STP_PROBE) {
- if (offset > 0) {
- ITypedRegion prevPartition =
- ((IDocumentExtension3) document).getPartition(STPProbeScanner.STP_PROBE_PARTITIONING, offset - 1, false);
- useGlobal = prevPartition.getType() == IDocument.DEFAULT_CONTENT_TYPE;
- } else {
- useGlobal = true;
- }
- }
- }
- } catch (BadLocationException e1) {
- return NO_COMPLETIONS;
- } catch (BadPartitioningException e) {
- return NO_COMPLETIONS;
- }
-
- String prefix = ""; //$NON-NLS-1$
- String prePrefix = ""; //$NON-NLS-1$
-
- // Get completion hint from document
- try {
- prefix = getPrefix(document, offset);
- Token previousToken = getPrecedingToken(document, offset - prefix.length() - 1);
-
- while (previousToken.tokenString.equals("=") || //$NON-NLS-1$
- previousToken.tokenString.equals(",") ) { //$NON-NLS-1$
- previousToken = getPrecedingToken(document, previousToken.offset - 1);
- previousToken = getPrecedingToken(document, previousToken.offset - 1);
- }
-
- prePrefix = previousToken.tokenString;
-
- } catch (BadLocationException e) {
- return NO_COMPLETIONS;
- }
-
- if (prePrefix.startsWith("probe")) { //$NON-NLS-1$
- return getProbeCompletionList(prefix, offset);
- }
-
- // If inside a probe return probe variable completions and functions
- // which can be called.
- if (partition.getType() == STPProbeScanner.STP_PROBE) {
- ICompletionProposal[] variableCompletions = getProbeVariableCompletions(document, offset, prefix);
- ICompletionProposal[] functionCompletions = getFunctionCompletions(offset, prefix);
-
- ArrayList<ICompletionProposal> completions = new ArrayList<>(
- variableCompletions.length + functionCompletions.length);
- completions.addAll(Arrays.asList(variableCompletions));
- completions.addAll(Arrays.asList(functionCompletions));
-
- return completions.toArray(new ICompletionProposal[0]);
- } else if (partition.getType() == IDocument.DEFAULT_CONTENT_TYPE || useGlobal) {
- // In the global scope return global keyword completion.
- return getGlobalKeywordCompletion(prefix, offset);
- }
-
- return NO_COMPLETIONS;
- }
-
- private ICompletionProposal[] getFunctionCompletions(int offset,
- String prefix) {
- String[] completionData = stpMetadataSingleton.getFunctionCompletions(prefix);
- ICompletionProposal[] result = new ICompletionProposal[completionData.length];
- int prefixLength = prefix.length();
- for (int i = 0; i < completionData.length; i++) {
- result[i] = new CompletionProposal(
- completionData[i].substring(prefixLength) + "()", //$NON-NLS-1$
- offset,
- 0,
- completionData[i].length() - prefixLength + 1,
- null,
- completionData[i] + " - function", //$NON-NLS-1$
- null,
- TapsetLibrary.getAndCacheDocumentation("function::" + completionData[i])); //$NON-NLS-1$
- }
-
- return result;
- }
-
- private ICompletionProposal[] getProbeVariableCompletions(IDocument document, int offset, String prefix) {
- try {
- String probe;
- probe = getProbe(document, offset);
- String[] completionData = stpMetadataSingleton
- .getProbeVariableCompletions(probe, prefix);
- ICompletionProposal[] result = new ICompletionProposal[completionData.length];
-
- int prefixLength = prefix.length();
- for (int i = 0; i < completionData.length; i++) {
- int endIndex = completionData[i].indexOf(':');
- String variableName = completionData[i].substring(0, endIndex);
- result[i] = new CompletionProposal(completionData[i].substring(
- prefixLength, endIndex),
- offset,
- 0,
- endIndex - prefixLength,
- null,
- completionData[i] + " - variable", //$NON-NLS-1$
- null,
- TapsetLibrary.getAndCacheDocumentation("probe::" + probe + "::" + variableName)); //$NON-NLS-1$ //$NON-NLS-2$
- }
- return result;
- } catch (BadLocationException e) {
- return NO_COMPLETIONS;
- } catch (BadPartitioningException e) {
- return NO_COMPLETIONS;
- }
- }
-
- /**
- * Returns the full name of the probe surrounding the given
- * offset. This function assumes that the given offset is inside
- * of a {@link STPPartitionScanner#STP_PROBE} section.
- * @param document
- * @param offset
- * @return the probe name
- * @throws BadLocationException
- * @throws BadPartitioningException
- */
- private String getProbe(IDocument document, int offset) throws BadLocationException, BadPartitioningException {
- String probePoint = null;
-
- ITypedRegion partition
- = ((IDocumentExtension3)document).getPartition(STPProbeScanner.STP_PROBE_PARTITIONING,
- offset, false);
- String probe = document.get(partition.getOffset(), partition.getLength());
-
- // make sure that we are inside a probe
- if (probe.startsWith(PROBE_KEYWORD)) {
- probePoint = probe.substring(PROBE_KEYWORD.length(), probe.indexOf('{'));
- probePoint = probePoint.trim();
- }
-
- return probePoint;
- }
-
- private ICompletionProposal[] getProbeCompletionList(String prefix, int offset) {
- prefix = canonicalizePrefix(prefix);
- String[] completionData = stpMetadataSingleton.getProbeCompletions(prefix);
-
- ICompletionProposal[] result = new ICompletionProposal[completionData.length];
- for (int i = 0; i < completionData.length; i++) {
- result[i] = new CompletionProposal(
- completionData[i].substring(prefix.length()),
- offset,
- 0,
- completionData[i].length() - prefix.length(),
- null,
- completionData[i],
- null,
- TapsetLibrary.getAndCacheDocumentation("probe::" + completionData[i])); //$NON-NLS-1$
- }
- return result;
-
- }
-
- /**
- * Returns a standardized version of the given prefix so that completion matching
- * can be performed.
- * For example for process("/some/long/path") this returns process(string);
- * @param prefix
- * @return
- */
- private String canonicalizePrefix(String prefix) {
-
- if (prefix.isEmpty()) {
- return ""; //$NON-NLS-1$
- }
- prefix = prefix.replaceAll("(?s)\\(\\s*\".*\"\\s*\\)", "(string)"); //$NON-NLS-1$ //$NON-NLS-2$
- prefix = prefix.replaceAll("(?s)\\(\\s*\\d*\\s*\\)", "(number)"); //$NON-NLS-1$ //$NON-NLS-2$
- return prefix;
- }
-
- private ICompletionProposal[] getGlobalKeywordCompletion(String prefix, int offset) {
-
- ArrayList<ICompletionProposal> completions = new ArrayList<>();
- int prefixLength = prefix.length();
- for (String[] keyword : GLOBAL_KEYWORDS) {
- if (keyword[0].startsWith(prefix)) {
- CompletionProposal proposal = new CompletionProposal(
- keyword[0].substring(prefixLength),
- offset,
- 0,
- keyword[0].length() - prefixLength,
- null,
- keyword[0],
- new ContextInformation("contextDisplayString", "informationDisplayString"), //$NON-NLS-1$ //$NON-NLS-2$
- keyword[1]);
- completions.add(proposal);
- }
- }
- return completions.toArray(new ICompletionProposal[0]);
- }
-
- /**
- * Returns the token preceding the current completion position.
- * @param doc The document for the which the completion is requested.
- * @param prefix The prefix for which the user has requested completion.
- * @param offset Current offset in the document
- * @return The preceding token.
- * @throws BadLocationException
- */
- private Token getPrecedingToken(IDocument doc, int offset) throws BadLocationException {
- // Skip trailing space
- int n = offset;
- while (n >= 0 && Character.isSpaceChar(doc.getChar(n))) {
- n--;
- }
-
- char c = doc.getChar(n);
- if (isTokenDelimiter(c)) {
- return new Token(Character.toString(c), n);
- }
-
- int end = n;
- while (n >= 0 && !isTokenDelimiter((doc.getChar(n)))) {
- n--;
- }
-
- return new Token(doc.get(n+1, end-n), n+1);
- }
-
- private Token getCurrentToken(IDocument doc, int offset) throws BadLocationException {
- char c = doc.getChar(offset);
-
- if (isDelimiter(c)) {
- return new Token(Character.toString(c), offset);
- }
-
- int start = offset;
- while (start >= 0 && !isDelimiter((doc.getChar(start)))) {
- start--;
- }
-
- int end = offset;
- while (end < doc.getLength() && !isDelimiter((doc.getChar(end)))) {
- end++;
- }
-
- start++;
- return new Token(doc.get(start, end-start), start);
- }
-
- /**
- *
- * Return the word the user wants to submit for completion proposals.
- *
- * @param doc - document to insert completion.
- * @param offset - offset of where completion hint was first generated.
- * @return - word to generate completion proposals.
- *
- * @throws BadLocationException
- */
- private String getPrefix(IDocument doc, int offset)
- throws BadLocationException {
-
- for (int n = offset - 1; n >= 0; n--) {
- char c = doc.getChar(n);
- if (isTokenDelimiter(c)) {
- String word = doc.get(n + 1, offset - n - 1);
- return word;
- }
- }
- return ""; //$NON-NLS-1$
- }
-
- private boolean isTokenDelimiter(char c) {
- if (Character.isWhitespace(c)) {
- return true;
- }
-
- switch (c) {
- case '\n':
- case '\0':
- case ',':
- case '{':
- case '}':
- case ']':
- case '[':
- return true;
- }
- return false;
- }
-
- private boolean isDelimiter (char c) {
-
- if (isTokenDelimiter(c)) {
- return true;
- }
-
- switch (c) {
- case '(':
- case ')':
- return true;
- }
- return false;
- }
-
- public void waitForInitialization() {
- this.stpMetadataSingleton.waitForInitialization();
- }
-
- /* (non-Javadoc)
- * @see org.eclipse.jface.text.contentassist.IContentAssistProcessor#computeContextInformation(org.eclipse.jface.text.ITextViewer, int)
- */
- @Override
- public IContextInformation[] computeContextInformation(ITextViewer viewer,
- int offset) {
- return NO_CONTEXTS;
- }
-
- /* (non-Javadoc)
- * @see org.eclipse.jface.text.contentassist.IContentAssistProcessor#getCompletionProposalAutoActivationCharacters()
- */
- @Override
- public char[] getCompletionProposalAutoActivationCharacters() {
- return PROPOSAL_ACTIVATION_CHARS;
- }
-
- /* (non-Javadoc)
- * @see org.eclipse.jface.text.contentassist.IContentAssistProcessor#getContextInformationAutoActivationCharacters()
- */
- @Override
- public char[] getContextInformationAutoActivationCharacters() {
- return PROPOSAL_ACTIVATION_CHARS;
- }
-
- /* (non-Javadoc)
- * @see org.eclipse.jface.text.contentassist.IContentAssistProcessor#getContextInformationValidator()
- */
- @Override
- public IContextInformationValidator getContextInformationValidator() {
- return null;
- }
-
- /* (non-Javadoc)
- * @see org.eclipse.jface.text.contentassist.IContentAssistProcessor#getErrorMessage()
- */
- @Override
- public String getErrorMessage() {
- // TODO: When does this trigger?
- return "Error."; //$NON-NLS-1$
- }
-
- @Override
- public String getHoverInfo(ITextViewer textViewer, IRegion hoverRegion) {
- String documentation = null;
- try {
- String keyword = textViewer.getDocument().get(hoverRegion.getOffset(), hoverRegion.getLength());
-
- documentation = TapsetLibrary.getDocumentation("function::" + keyword); //$NON-NLS-1$
- if (!documentation.startsWith("No manual entry for")) { //$NON-NLS-1$
- return documentation;
- }
-
- documentation = TapsetLibrary.getDocumentation("probe::" + keyword); //$NON-NLS-1$
- if (!documentation.startsWith("No manual entry for")) { //$NON-NLS-1$
- return documentation;
- }
-
- documentation = TapsetLibrary.getDocumentation("tapset::" + keyword); //$NON-NLS-1$
- if (!documentation.startsWith("No manual entry for")) { //$NON-NLS-1$
- return documentation;
- }
-
- if (keyword.indexOf('.') > 0) {
- keyword = keyword.split("\\.")[0]; //$NON-NLS-1$
- documentation = TapsetLibrary.getDocumentation("tapset::" + keyword); //$NON-NLS-1$
- }
-
- IDocument document = textViewer.getDocument();
- ITypedRegion partition =
- ((IDocumentExtension3)document).getPartition(STPProbeScanner.STP_PROBE_PARTITIONING,
- hoverRegion.getOffset(), false);
- if (partition.getType() == STPProbeScanner.STP_PROBE) {
- String probe = getProbe(textViewer.getDocument(), hoverRegion.getOffset());
- documentation = TapsetLibrary.getDocumentation("probe::" + probe + "::"+ keyword); //$NON-NLS-1$ //$NON-NLS-2$
- }
-
- } catch (BadLocationException e) {
- // Bad hover location; just ignore it.
- } catch (BadPartitioningException e) {
- // Bad hover scenario, just ignore it.
- }
-
- return documentation;
- }
-
- @Override
- public IRegion getHoverRegion(ITextViewer textViewer, int offset) {
- try {
- return getCurrentToken(textViewer.getDocument(), offset);
- } catch (BadLocationException e) {
- // Bad hover location; just ignore it.
- }
-
- return null;
- }
+ private final IContextInformation[] NO_CONTEXTS = new IContextInformation[0];
+ private final char[] PROPOSAL_ACTIVATION_CHARS = new char[] { '.' };
+ private ICompletionProposal[] NO_COMPLETIONS = new ICompletionProposal[0];
+
+ private static final String GLOBAL_KEYWORD = "global "; //$NON-NLS-1$
+ private static final String PROBE_KEYWORD = "probe "; //$NON-NLS-1$
+ private static final String FUNCTION_KEYWORD = "function "; //$NON-NLS-1$
+
+ private static final String[][] GLOBAL_KEYWORDS = {
+ { GLOBAL_KEYWORD, Messages.STPCompletionProcessor_global },
+ { PROBE_KEYWORD, Messages.STPCompletionProcessor_probe },
+ { FUNCTION_KEYWORD, Messages.STPCompletionProcessor_function } };
+
+ private STPMetadataSingleton stpMetadataSingleton;
+
+ private static class Token implements IRegion {
+ String tokenString;
+ int offset;
+
+ public Token(String string, int n) {
+ this.tokenString = string;
+ this.offset = n;
+ }
+
+ @Override
+ public int getLength() {
+ return this.tokenString.length();
+ }
+
+ @Override
+ public int getOffset() {
+ return this.offset;
+ }
+ }
+
+ public STPCompletionProcessor() {
+ this.stpMetadataSingleton = STPMetadataSingleton.getInstance();
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.text.contentassist.IContentAssistProcessor#computeCompletionProposals(org.eclipse.jface.text.ITextViewer, int)
+ */
+ @Override
+ public ICompletionProposal[] computeCompletionProposals(ITextViewer viewer,
+ int offset) {
+ return computeCompletionProposals(viewer.getDocument(), offset);
+ }
+
+ public ICompletionProposal[] computeCompletionProposals(IDocument document, int offset) {
+
+ ITypedRegion partition = null;
+ boolean useGlobal = false;
+
+ try {
+ partition =
+ ((IDocumentExtension3) document).getPartition(STPProbeScanner.STP_PROBE_PARTITIONING, offset, false);
+ if (partition.getOffset() == offset) {
+ if (partition.getType() != IDocument.DEFAULT_CONTENT_TYPE && partition.getType() != STPProbeScanner.STP_PROBE) {
+ if (offset > 0) {
+ ITypedRegion prevPartition =
+ ((IDocumentExtension3) document).getPartition(STPProbeScanner.STP_PROBE_PARTITIONING, offset - 1, false);
+ useGlobal = prevPartition.getType() == IDocument.DEFAULT_CONTENT_TYPE;
+ } else {
+ useGlobal = true;
+ }
+ }
+ }
+ } catch (BadLocationException e1) {
+ return NO_COMPLETIONS;
+ } catch (BadPartitioningException e) {
+ return NO_COMPLETIONS;
+ }
+
+ String prefix = ""; //$NON-NLS-1$
+ String prePrefix = ""; //$NON-NLS-1$
+
+ // Get completion hint from document
+ try {
+ prefix = getPrefix(document, offset);
+ Token previousToken = getPrecedingToken(document, offset - prefix.length() - 1);
+
+ while (previousToken.tokenString.equals("=") || //$NON-NLS-1$
+ previousToken.tokenString.equals(",") ) { //$NON-NLS-1$
+ previousToken = getPrecedingToken(document, previousToken.offset - 1);
+ previousToken = getPrecedingToken(document, previousToken.offset - 1);
+ }
+
+ prePrefix = previousToken.tokenString;
+
+ } catch (BadLocationException e) {
+ return NO_COMPLETIONS;
+ }
+
+ if (prePrefix.startsWith("probe")) { //$NON-NLS-1$
+ return getProbeCompletionList(prefix, offset);
+ }
+
+ // If inside a probe return probe variable completions and functions
+ // which can be called.
+ if (partition.getType() == STPProbeScanner.STP_PROBE) {
+ ICompletionProposal[] variableCompletions = getProbeVariableCompletions(document, offset, prefix);
+ ICompletionProposal[] functionCompletions = getFunctionCompletions(offset, prefix);
+
+ ArrayList<ICompletionProposal> completions = new ArrayList<>(
+ variableCompletions.length + functionCompletions.length);
+ completions.addAll(Arrays.asList(variableCompletions));
+ completions.addAll(Arrays.asList(functionCompletions));
+
+ return completions.toArray(new ICompletionProposal[0]);
+ } else if (partition.getType() == IDocument.DEFAULT_CONTENT_TYPE || useGlobal) {
+ // In the global scope return global keyword completion.
+ return getGlobalKeywordCompletion(prefix, offset);
+ }
+
+ return NO_COMPLETIONS;
+ }
+
+ private ICompletionProposal[] getFunctionCompletions(int offset,
+ String prefix) {
+ String[] completionData = stpMetadataSingleton.getFunctionCompletions(prefix);
+ ICompletionProposal[] result = new ICompletionProposal[completionData.length];
+ int prefixLength = prefix.length();
+ for (int i = 0; i < completionData.length; i++) {
+ result[i] = new CompletionProposal(
+ completionData[i].substring(prefixLength) + "()", //$NON-NLS-1$
+ offset,
+ 0,
+ completionData[i].length() - prefixLength + 1,
+ null,
+ completionData[i] + " - function", //$NON-NLS-1$
+ null,
+ TapsetLibrary.getAndCacheDocumentation("function::" + completionData[i])); //$NON-NLS-1$
+ }
+
+ return result;
+ }
+
+ private ICompletionProposal[] getProbeVariableCompletions(IDocument document, int offset, String prefix) {
+ try {
+ String probe;
+ probe = getProbe(document, offset);
+ String[] completionData = stpMetadataSingleton
+ .getProbeVariableCompletions(probe, prefix);
+ ICompletionProposal[] result = new ICompletionProposal[completionData.length];
+
+ int prefixLength = prefix.length();
+ for (int i = 0; i < completionData.length; i++) {
+ int endIndex = completionData[i].indexOf(':');
+ String variableName = completionData[i].substring(0, endIndex);
+ result[i] = new CompletionProposal(completionData[i].substring(
+ prefixLength, endIndex),
+ offset,
+ 0,
+ endIndex - prefixLength,
+ null,
+ completionData[i] + " - variable", //$NON-NLS-1$
+ null,
+ TapsetLibrary.getAndCacheDocumentation("probe::" + probe + "::" + variableName)); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ return result;
+ } catch (BadLocationException e) {
+ return NO_COMPLETIONS;
+ } catch (BadPartitioningException e) {
+ return NO_COMPLETIONS;
+ }
+ }
+
+ /**
+ * Returns the full name of the probe surrounding the given
+ * offset. This function assumes that the given offset is inside
+ * of a {@link STPPartitionScanner#STP_PROBE} section.
+ * @param document
+ * @param offset
+ * @return the probe name
+ * @throws BadLocationException
+ * @throws BadPartitioningException
+ */
+ private String getProbe(IDocument document, int offset) throws BadLocationException, BadPartitioningException {
+ String probePoint = null;
+
+ ITypedRegion partition
+ = ((IDocumentExtension3)document).getPartition(STPProbeScanner.STP_PROBE_PARTITIONING,
+ offset, false);
+ String probe = document.get(partition.getOffset(), partition.getLength());
+
+ // make sure that we are inside a probe
+ if (probe.startsWith(PROBE_KEYWORD)) {
+ probePoint = probe.substring(PROBE_KEYWORD.length(), probe.indexOf('{'));
+ probePoint = probePoint.trim();
+ }
+
+ return probePoint;
+ }
+
+ private ICompletionProposal[] getProbeCompletionList(String prefix, int offset) {
+ prefix = canonicalizePrefix(prefix);
+ String[] completionData = stpMetadataSingleton.getProbeCompletions(prefix);
+
+ ICompletionProposal[] result = new ICompletionProposal[completionData.length];
+ for (int i = 0; i < completionData.length; i++) {
+ result[i] = new CompletionProposal(
+ completionData[i].substring(prefix.length()),
+ offset,
+ 0,
+ completionData[i].length() - prefix.length(),
+ null,
+ completionData[i],
+ null,
+ TapsetLibrary.getAndCacheDocumentation("probe::" + completionData[i])); //$NON-NLS-1$
+ }
+ return result;
+
+ }
+
+ /**
+ * Returns a standardized version of the given prefix so that completion matching
+ * can be performed.
+ * For example for process("/some/long/path") this returns process(string);
+ * @param prefix
+ * @return
+ */
+ private String canonicalizePrefix(String prefix) {
+
+ if (prefix.isEmpty()) {
+ return ""; //$NON-NLS-1$
+ }
+ prefix = prefix.replaceAll("(?s)\\(\\s*\".*\"\\s*\\)", "(string)"); //$NON-NLS-1$ //$NON-NLS-2$
+ prefix = prefix.replaceAll("(?s)\\(\\s*\\d*\\s*\\)", "(number)"); //$NON-NLS-1$ //$NON-NLS-2$
+ return prefix;
+ }
+
+ private ICompletionProposal[] getGlobalKeywordCompletion(String prefix, int offset) {
+
+ ArrayList<ICompletionProposal> completions = new ArrayList<>();
+ int prefixLength = prefix.length();
+ for (String[] keyword : GLOBAL_KEYWORDS) {
+ if (keyword[0].startsWith(prefix)) {
+ CompletionProposal proposal = new CompletionProposal(
+ keyword[0].substring(prefixLength),
+ offset,
+ 0,
+ keyword[0].length() - prefixLength,
+ null,
+ keyword[0],
+ new ContextInformation("contextDisplayString", "informationDisplayString"), //$NON-NLS-1$ //$NON-NLS-2$
+ keyword[1]);
+ completions.add(proposal);
+ }
+ }
+ return completions.toArray(new ICompletionProposal[0]);
+ }
+
+ /**
+ * Returns the token preceding the current completion position.
+ * @param doc The document for the which the completion is requested.
+ * @param prefix The prefix for which the user has requested completion.
+ * @param offset Current offset in the document
+ * @return The preceding token.
+ * @throws BadLocationException
+ */
+ private Token getPrecedingToken(IDocument doc, int offset) throws BadLocationException {
+ // Skip trailing space
+ int n = offset;
+ while (n >= 0 && Character.isSpaceChar(doc.getChar(n))) {
+ n--;
+ }
+
+ char c = doc.getChar(n);
+ if (isTokenDelimiter(c)) {
+ return new Token(Character.toString(c), n);
+ }
+
+ int end = n;
+ while (n >= 0 && !isTokenDelimiter((doc.getChar(n)))) {
+ n--;
+ }
+
+ return new Token(doc.get(n+1, end-n), n+1);
+ }
+
+ private Token getCurrentToken(IDocument doc, int offset) throws BadLocationException {
+ char c = doc.getChar(offset);
+
+ if (isDelimiter(c)) {
+ return new Token(Character.toString(c), offset);
+ }
+
+ int start = offset;
+ while (start >= 0 && !isDelimiter((doc.getChar(start)))) {
+ start--;
+ }
+
+ int end = offset;
+ while (end < doc.getLength() && !isDelimiter((doc.getChar(end)))) {
+ end++;
+ }
+
+ start++;
+ return new Token(doc.get(start, end-start), start);
+ }
+
+ /**
+ *
+ * Return the word the user wants to submit for completion proposals.
+ *
+ * @param doc - document to insert completion.
+ * @param offset - offset of where completion hint was first generated.
+ * @return - word to generate completion proposals.
+ *
+ * @throws BadLocationException
+ */
+ private String getPrefix(IDocument doc, int offset)
+ throws BadLocationException {
+
+ for (int n = offset - 1; n >= 0; n--) {
+ char c = doc.getChar(n);
+ if (isTokenDelimiter(c)) {
+ String word = doc.get(n + 1, offset - n - 1);
+ return word;
+ }
+ }
+ return ""; //$NON-NLS-1$
+ }
+
+ private boolean isTokenDelimiter(char c) {
+ if (Character.isWhitespace(c)) {
+ return true;
+ }
+
+ switch (c) {
+ case '\n':
+ case '\0':
+ case ',':
+ case '{':
+ case '}':
+ case ']':
+ case '[':
+ return true;
+ }
+ return false;
+ }
+
+ private boolean isDelimiter (char c) {
+
+ if (isTokenDelimiter(c)) {
+ return true;
+ }
+
+ switch (c) {
+ case '(':
+ case ')':
+ return true;
+ }
+ return false;
+ }
+
+ public void waitForInitialization() {
+ this.stpMetadataSingleton.waitForInitialization();
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.text.contentassist.IContentAssistProcessor#computeContextInformation(org.eclipse.jface.text.ITextViewer, int)
+ */
+ @Override
+ public IContextInformation[] computeContextInformation(ITextViewer viewer,
+ int offset) {
+ return NO_CONTEXTS;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.text.contentassist.IContentAssistProcessor#getCompletionProposalAutoActivationCharacters()
+ */
+ @Override
+ public char[] getCompletionProposalAutoActivationCharacters() {
+ return PROPOSAL_ACTIVATION_CHARS;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.text.contentassist.IContentAssistProcessor#getContextInformationAutoActivationCharacters()
+ */
+ @Override
+ public char[] getContextInformationAutoActivationCharacters() {
+ return PROPOSAL_ACTIVATION_CHARS;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.text.contentassist.IContentAssistProcessor#getContextInformationValidator()
+ */
+ @Override
+ public IContextInformationValidator getContextInformationValidator() {
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.text.contentassist.IContentAssistProcessor#getErrorMessage()
+ */
+ @Override
+ public String getErrorMessage() {
+ // TODO: When does this trigger?
+ return "Error."; //$NON-NLS-1$
+ }
+
+ @Override
+ public String getHoverInfo(ITextViewer textViewer, IRegion hoverRegion) {
+ String documentation = null;
+ try {
+ String keyword = textViewer.getDocument().get(hoverRegion.getOffset(), hoverRegion.getLength());
+
+ documentation = TapsetLibrary.getDocumentation("function::" + keyword); //$NON-NLS-1$
+ if (!documentation.startsWith("No manual entry for")) { //$NON-NLS-1$
+ return documentation;
+ }
+
+ documentation = TapsetLibrary.getDocumentation("probe::" + keyword); //$NON-NLS-1$
+ if (!documentation.startsWith("No manual entry for")) { //$NON-NLS-1$
+ return documentation;
+ }
+
+ documentation = TapsetLibrary.getDocumentation("tapset::" + keyword); //$NON-NLS-1$
+ if (!documentation.startsWith("No manual entry for")) { //$NON-NLS-1$
+ return documentation;
+ }
+
+ if (keyword.indexOf('.') > 0) {
+ keyword = keyword.split("\\.")[0]; //$NON-NLS-1$
+ documentation = TapsetLibrary.getDocumentation("tapset::" + keyword); //$NON-NLS-1$
+ }
+
+ IDocument document = textViewer.getDocument();
+ ITypedRegion partition =
+ ((IDocumentExtension3)document).getPartition(STPProbeScanner.STP_PROBE_PARTITIONING,
+ hoverRegion.getOffset(), false);
+ if (partition.getType() == STPProbeScanner.STP_PROBE) {
+ String probe = getProbe(textViewer.getDocument(), hoverRegion.getOffset());
+ documentation = TapsetLibrary.getDocumentation("probe::" + probe + "::"+ keyword); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+ } catch (BadLocationException e) {
+ // Bad hover location; just ignore it.
+ } catch (BadPartitioningException e) {
+ // Bad hover scenario, just ignore it.
+ }
+
+ return documentation;
+ }
+
+ @Override
+ public IRegion getHoverRegion(ITextViewer textViewer, int offset) {
+ try {
+ return getCurrentToken(textViewer.getDocument(), offset);
+ } catch (BadLocationException e) {
+ // Bad hover location; just ignore it.
+ }
+
+ return null;
+ }
} \ No newline at end of file
diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/STPConfiguration.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/STPConfiguration.java
index 7cd71d53f0..498aa99bbb 100644
--- a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/STPConfiguration.java
+++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/STPConfiguration.java
@@ -32,70 +32,70 @@ import org.eclipse.linuxtools.systemtap.ui.editor.DoubleClickStrategy;
public class STPConfiguration extends SourceViewerConfiguration {
- private STPElementScanner scanner;
- private ColorManager colorManager;
- private STPEditor editor;
- private DoubleClickStrategy doubleClickStrategy;
- private STPCompletionProcessor processor;
-
- public STPConfiguration(ColorManager colorManager, STPEditor editor) {
- this.colorManager = colorManager;
- this.editor = editor;
- this.processor = new STPCompletionProcessor();
- }
-
- /* (non-Javadoc)
- * @see org.eclipse.jface.text.source.SourceViewerConfiguration#getConfiguredContentTypes(org.eclipse.jface.text.source.ISourceViewer)
- */
- @Override
- public String[] getConfiguredContentTypes(ISourceViewer sourceViewer) {
- return new String[] {
- IDocument.DEFAULT_CONTENT_TYPE,
- STPPartitionScanner.STP_COMMENT,
- STPPartitionScanner.STP_CONDITIONAL};
- }
-
- /* (non-Javadoc)
- * @see org.eclipse.jface.text.source.SourceViewerConfiguration#getContentAssistant(org.eclipse.jface.text.source.ISourceViewer)
- */
- @Override
- public IContentAssistant getContentAssistant(ISourceViewer sourceViewer) {
- ContentAssistant assistant = new ContentAssistant();
-
- assistant.enableAutoActivation(true);
- assistant.setAutoActivationDelay(500);
- assistant.setProposalPopupOrientation(IContentAssistant.PROPOSAL_OVERLAY);
- assistant
- .setContextInformationPopupOrientation(IContentAssistant.CONTEXT_INFO_ABOVE);
-
- assistant.setContentAssistProcessor(processor,IDocument.DEFAULT_CONTENT_TYPE);
- assistant.setContentAssistProcessor(processor,STPPartitionScanner.STP_CONDITIONAL);
-
- assistant.setInformationControlCreator(getInformationControlCreator(sourceViewer));
-
- return assistant;
- }
-
- /**
- * Return the default Element scanner.
- *
- * @return default element scanner.
- */
- private STPElementScanner getSTPScanner() {
- if (scanner == null) {
- scanner = new STPElementScanner(colorManager);
- scanner.setDefaultReturnToken(new Token(new TextAttribute(
- colorManager.getColor(STPColorConstants.DEFAULT))));
- }
- return scanner;
- }
+ private STPElementScanner scanner;
+ private ColorManager colorManager;
+ private STPEditor editor;
+ private DoubleClickStrategy doubleClickStrategy;
+ private STPCompletionProcessor processor;
+
+ public STPConfiguration(ColorManager colorManager, STPEditor editor) {
+ this.colorManager = colorManager;
+ this.editor = editor;
+ this.processor = new STPCompletionProcessor();
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.text.source.SourceViewerConfiguration#getConfiguredContentTypes(org.eclipse.jface.text.source.ISourceViewer)
+ */
+ @Override
+ public String[] getConfiguredContentTypes(ISourceViewer sourceViewer) {
+ return new String[] {
+ IDocument.DEFAULT_CONTENT_TYPE,
+ STPPartitionScanner.STP_COMMENT,
+ STPPartitionScanner.STP_CONDITIONAL};
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.text.source.SourceViewerConfiguration#getContentAssistant(org.eclipse.jface.text.source.ISourceViewer)
+ */
+ @Override
+ public IContentAssistant getContentAssistant(ISourceViewer sourceViewer) {
+ ContentAssistant assistant = new ContentAssistant();
+
+ assistant.enableAutoActivation(true);
+ assistant.setAutoActivationDelay(500);
+ assistant.setProposalPopupOrientation(IContentAssistant.PROPOSAL_OVERLAY);
+ assistant
+ .setContextInformationPopupOrientation(IContentAssistant.CONTEXT_INFO_ABOVE);
+
+ assistant.setContentAssistProcessor(processor,IDocument.DEFAULT_CONTENT_TYPE);
+ assistant.setContentAssistProcessor(processor,STPPartitionScanner.STP_CONDITIONAL);
+
+ assistant.setInformationControlCreator(getInformationControlCreator(sourceViewer));
+
+ return assistant;
+ }
+
+ /**
+ * Return the default Element scanner.
+ *
+ * @return default element scanner.
+ */
+ private STPElementScanner getSTPScanner() {
+ if (scanner == null) {
+ scanner = new STPElementScanner(colorManager);
+ scanner.setDefaultReturnToken(new Token(new TextAttribute(
+ colorManager.getColor(STPColorConstants.DEFAULT))));
+ }
+ return scanner;
+ }
/* (non-Javadoc)
* @see org.eclipse.jface.text.source.SourceViewerConfiguration#getReconciler(org.eclipse.jface.text.source.ISourceViewer)
*
* Return the reconciler built on the custom Systemtap reconciling strategy that enables code folding for this editor.
*/
- @Override
+ @Override
public IReconciler getReconciler(ISourceViewer sourceViewer)
{
STPReconcilingStrategy strategy = new STPReconcilingStrategy();
@@ -104,58 +104,58 @@ public class STPConfiguration extends SourceViewerConfiguration {
return reconciler;
}
- /**
- * Instantiates and returns a double click strategy object if one does not exist, and returns the
- * current one if it does.
- */
- @Override
- public ITextDoubleClickStrategy getDoubleClickStrategy(ISourceViewer sourceViewer,String contentType) {
- if (doubleClickStrategy == null) {
- doubleClickStrategy = new DoubleClickStrategy();
- }
- return doubleClickStrategy;
- }
-
-
- /* (non-Javadoc)
- * @see org.eclipse.jface.text.source.SourceViewerConfiguration#getPresentationReconciler(org.eclipse.jface.text.source.ISourceViewer)
- */
- @Override
- public IPresentationReconciler getPresentationReconciler(
- ISourceViewer sourceViewer) {
-
- PresentationReconciler reconciler = new PresentationReconciler();
-
- DefaultDamagerRepairer dr = new DefaultDamagerRepairer(getSTPScanner());
- reconciler.setDamager(dr, IDocument.DEFAULT_CONTENT_TYPE);
- reconciler.setRepairer(dr, IDocument.DEFAULT_CONTENT_TYPE);
-
- dr = new DefaultDamagerRepairer(getSTPScanner());
- reconciler.setDamager(dr, STPPartitionScanner.STP_COMMENT);
- reconciler.setRepairer(dr, STPPartitionScanner.STP_COMMENT);
-
- dr = new DefaultDamagerRepairer(getSTPScanner());
- reconciler.setDamager(dr, STPPartitionScanner.STP_CONDITIONAL);
- reconciler.setRepairer(dr, STPPartitionScanner.STP_CONDITIONAL);
-
- return reconciler;
- }
-
- @Override
- public IAutoEditStrategy[] getAutoEditStrategies(
- ISourceViewer sourceViewer, String contentType) {
- return new IAutoEditStrategy[] {new STPAutoEditStrategy(STPPartitionScanner.STP_PARTITIONING, null)};
- }
-
- @Override
- public ITextHover getTextHover(ISourceViewer sourceViewer, String contentType) {
- return processor;
- }
-
- @Override
- public String[] getDefaultPrefixes(ISourceViewer sourceViewer,
- String contentType) {
- return new String[] { "//", "" }; //$NON-NLS-1$//$NON-NLS-2$
- }
+ /**
+ * Instantiates and returns a double click strategy object if one does not exist, and returns the
+ * current one if it does.
+ */
+ @Override
+ public ITextDoubleClickStrategy getDoubleClickStrategy(ISourceViewer sourceViewer,String contentType) {
+ if (doubleClickStrategy == null) {
+ doubleClickStrategy = new DoubleClickStrategy();
+ }
+ return doubleClickStrategy;
+ }
+
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.text.source.SourceViewerConfiguration#getPresentationReconciler(org.eclipse.jface.text.source.ISourceViewer)
+ */
+ @Override
+ public IPresentationReconciler getPresentationReconciler(
+ ISourceViewer sourceViewer) {
+
+ PresentationReconciler reconciler = new PresentationReconciler();
+
+ DefaultDamagerRepairer dr = new DefaultDamagerRepairer(getSTPScanner());
+ reconciler.setDamager(dr, IDocument.DEFAULT_CONTENT_TYPE);
+ reconciler.setRepairer(dr, IDocument.DEFAULT_CONTENT_TYPE);
+
+ dr = new DefaultDamagerRepairer(getSTPScanner());
+ reconciler.setDamager(dr, STPPartitionScanner.STP_COMMENT);
+ reconciler.setRepairer(dr, STPPartitionScanner.STP_COMMENT);
+
+ dr = new DefaultDamagerRepairer(getSTPScanner());
+ reconciler.setDamager(dr, STPPartitionScanner.STP_CONDITIONAL);
+ reconciler.setRepairer(dr, STPPartitionScanner.STP_CONDITIONAL);
+
+ return reconciler;
+ }
+
+ @Override
+ public IAutoEditStrategy[] getAutoEditStrategies(
+ ISourceViewer sourceViewer, String contentType) {
+ return new IAutoEditStrategy[] {new STPAutoEditStrategy(STPPartitionScanner.STP_PARTITIONING, null)};
+ }
+
+ @Override
+ public ITextHover getTextHover(ISourceViewer sourceViewer, String contentType) {
+ return processor;
+ }
+
+ @Override
+ public String[] getDefaultPrefixes(ISourceViewer sourceViewer,
+ String contentType) {
+ return new String[] { "//", "" }; //$NON-NLS-1$//$NON-NLS-2$
+ }
} \ No newline at end of file
diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/STPDefaultCodeFormatterConstants.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/STPDefaultCodeFormatterConstants.java
index c6b14e41bf..f4255baa81 100644
--- a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/STPDefaultCodeFormatterConstants.java
+++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/STPDefaultCodeFormatterConstants.java
@@ -25,409 +25,409 @@ import org.eclipse.linuxtools.internal.systemtap.ui.ide.IDEPlugin;
*/
public class STPDefaultCodeFormatterConstants {
- /**
- * <pre>
- * FORMATTER / Value to set an option to false.
- * </pre>
- */
- public static final String FALSE = "false"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Value to set an option to false.
+ * </pre>
+ */
+ public static final String FALSE = "false"; //$NON-NLS-1$
- /**
- * <pre>
- * FORMATTER / Option for alignment of arguments in method invocation
- * - option id: "org.eclipse.cdt.core.formatter.alignment_for_arguments_in_method_invocation"
- * - possible values: values returned by <code>createAlignmentValue(boolean, int, int)</code> call
- * - default: createAlignmentValue(false, WRAP_COMPACT, INDENT_DEFAULT)
- * </pre>
- * @see #createAlignmentValue(boolean, int, int)
- */
- public static final String FORMATTER_ALIGNMENT_FOR_ARGUMENTS_IN_METHOD_INVOCATION = IDEPlugin.PLUGIN_ID + ".formatter.alignment_for_arguments_in_method_invocation"; //$NON-NLS-1$
- /**
- * <pre>
- * FORMATTER / Option for alignment of expressions in initializer list
- * - option id: "org.eclipse.cdt.core.formatter.alignment_for_expressions_in_array_initializer"
- * - possible values: values returned by <code>createAlignmentValue(boolean, int, int)</code> call
- * - default: createAlignmentValue(false, WRAP_COMPACT, INDENT_DEFAULT)
- * </pre>
- * @see #createAlignmentValue(boolean, int, int)
- */
- public static final String FORMATTER_ALIGNMENT_FOR_EXPRESSIONS_IN_INITIALIZER_LIST = IDEPlugin.PLUGIN_ID + ".formatter.alignment_for_expressions_in_array_initializer"; //$NON-NLS-1$
- /**
- * <pre>
- * FORMATTER / Option for alignment of parameters in method declaration
- * - option id: "org.eclipse.cdt.core.formatter.alignment_for_parameters_in_method_declaration"
- * - possible values: values returned by <code>createAlignmentValue(boolean, int, int)</code> call
- * - default: createAlignmentValue(false, WRAP_COMPACT, INDENT_DEFAULT)
- * </pre>
- * @see #createAlignmentValue(boolean, int, int)
- */
- public static final String FORMATTER_ALIGNMENT_FOR_PARAMETERS_IN_METHOD_DECLARATION = IDEPlugin.PLUGIN_ID + ".formatter.alignment_for_parameters_in_method_declaration"; //$NON-NLS-1$
- /**
- * <pre>
- * FORMATTER / Option to position the braces of initializer list
- * - option id: "org.eclipse.cdt.core.formatter.brace_position_for_array_initializer"
- * - possible values: { END_OF_LINE, NEXT_LINE, NEXT_LINE_SHIFTED, NEXT_LINE_ON_WRAP }
- * - default: END_OF_LINE
- * </pre>
- * @see #END_OF_LINE
- * @see #NEXT_LINE
- * @see #NEXT_LINE_SHIFTED
- * @see #NEXT_LINE_ON_WRAP
- */
- public static final String FORMATTER_BRACE_POSITION_FOR_INITIALIZER_LIST = IDEPlugin.PLUGIN_ID + ".formatter.brace_position_for_array_initializer"; //$NON-NLS-1$
- /**
- * <pre>
- * FORMATTER / Option to position the braces of a block
- * - option id: "org.eclipse.cdt.core.formatter.brace_position_for_block"
- * - possible values: { END_OF_LINE, NEXT_LINE, NEXT_LINE_SHIFTED, NEXT_LINE_ON_WRAP }
- * - default: END_OF_LINE
- * </pre>
- * @see #END_OF_LINE
- * @see #NEXT_LINE
- * @see #NEXT_LINE_SHIFTED
- * @see #NEXT_LINE_ON_WRAP
- */
- public static final String FORMATTER_BRACE_POSITION_FOR_BLOCK = IDEPlugin.PLUGIN_ID + ".formatter.brace_position_for_block"; //$NON-NLS-1$
- /**
- * <pre>
- * FORMATTER / Option to position the braces of a method declaration
- * - option id: "org.eclipse.cdt.core.formatter.brace_position_for_method_declaration"
- * - possible values: { END_OF_LINE, NEXT_LINE, NEXT_LINE_SHIFTED, NEXT_LINE_ON_WRAP }
- * - default: END_OF_LINE
- * </pre>
- * @see #END_OF_LINE
- * @see #NEXT_LINE
- * @see #NEXT_LINE_SHIFTED
- * @see #NEXT_LINE_ON_WRAP
- */
- public static final String FORMATTER_BRACE_POSITION_FOR_METHOD_DECLARATION = IDEPlugin.PLUGIN_ID + ".formatter.brace_position_for_method_declaration"; //$NON-NLS-1$
- /**
- * <pre>
- * FORMATTER / Option to position the braces of a switch statement
- * - option id: "org.eclipse.cdt.core.formatter.brace_position_for_switch"
- * - possible values: { END_OF_LINE, NEXT_LINE, NEXT_LINE_SHIFTED, NEXT_LINE_ON_WRAP }
- * - default: END_OF_LINE
- * </pre>
- * @see #END_OF_LINE
- * @see #NEXT_LINE
- * @see #NEXT_LINE_SHIFTED
- * @see #NEXT_LINE_ON_WRAP
- */
- public static final String FORMATTER_BRACE_POSITION_FOR_SWITCH = IDEPlugin.PLUGIN_ID + ".formatter.brace_position_for_switch"; //$NON-NLS-1$
- /**
- * <pre>
- * FORMATTER / Option to position the braces of a type declaration
- * - option id: "org.eclipse.cdt.core.formatter.brace_position_for_type_declaration"
- * - possible values: { END_OF_LINE, NEXT_LINE, NEXT_LINE_SHIFTED, NEXT_LINE_ON_WRAP }
- * - default: END_OF_LINE
- * </pre>
- * @see #END_OF_LINE
- * @see #NEXT_LINE
- * @see #NEXT_LINE_SHIFTED
- * @see #NEXT_LINE_ON_WRAP
- */
- public static final String FORMATTER_BRACE_POSITION_FOR_TYPE_DECLARATION = IDEPlugin.PLUGIN_ID + ".formatter.brace_position_for_type_declaration"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option for alignment of arguments in method invocation
+ * - option id: "org.eclipse.cdt.core.formatter.alignment_for_arguments_in_method_invocation"
+ * - possible values: values returned by <code>createAlignmentValue(boolean, int, int)</code> call
+ * - default: createAlignmentValue(false, WRAP_COMPACT, INDENT_DEFAULT)
+ * </pre>
+ * @see #createAlignmentValue(boolean, int, int)
+ */
+ public static final String FORMATTER_ALIGNMENT_FOR_ARGUMENTS_IN_METHOD_INVOCATION = IDEPlugin.PLUGIN_ID + ".formatter.alignment_for_arguments_in_method_invocation"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option for alignment of expressions in initializer list
+ * - option id: "org.eclipse.cdt.core.formatter.alignment_for_expressions_in_array_initializer"
+ * - possible values: values returned by <code>createAlignmentValue(boolean, int, int)</code> call
+ * - default: createAlignmentValue(false, WRAP_COMPACT, INDENT_DEFAULT)
+ * </pre>
+ * @see #createAlignmentValue(boolean, int, int)
+ */
+ public static final String FORMATTER_ALIGNMENT_FOR_EXPRESSIONS_IN_INITIALIZER_LIST = IDEPlugin.PLUGIN_ID + ".formatter.alignment_for_expressions_in_array_initializer"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option for alignment of parameters in method declaration
+ * - option id: "org.eclipse.cdt.core.formatter.alignment_for_parameters_in_method_declaration"
+ * - possible values: values returned by <code>createAlignmentValue(boolean, int, int)</code> call
+ * - default: createAlignmentValue(false, WRAP_COMPACT, INDENT_DEFAULT)
+ * </pre>
+ * @see #createAlignmentValue(boolean, int, int)
+ */
+ public static final String FORMATTER_ALIGNMENT_FOR_PARAMETERS_IN_METHOD_DECLARATION = IDEPlugin.PLUGIN_ID + ".formatter.alignment_for_parameters_in_method_declaration"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option to position the braces of initializer list
+ * - option id: "org.eclipse.cdt.core.formatter.brace_position_for_array_initializer"
+ * - possible values: { END_OF_LINE, NEXT_LINE, NEXT_LINE_SHIFTED, NEXT_LINE_ON_WRAP }
+ * - default: END_OF_LINE
+ * </pre>
+ * @see #END_OF_LINE
+ * @see #NEXT_LINE
+ * @see #NEXT_LINE_SHIFTED
+ * @see #NEXT_LINE_ON_WRAP
+ */
+ public static final String FORMATTER_BRACE_POSITION_FOR_INITIALIZER_LIST = IDEPlugin.PLUGIN_ID + ".formatter.brace_position_for_array_initializer"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option to position the braces of a block
+ * - option id: "org.eclipse.cdt.core.formatter.brace_position_for_block"
+ * - possible values: { END_OF_LINE, NEXT_LINE, NEXT_LINE_SHIFTED, NEXT_LINE_ON_WRAP }
+ * - default: END_OF_LINE
+ * </pre>
+ * @see #END_OF_LINE
+ * @see #NEXT_LINE
+ * @see #NEXT_LINE_SHIFTED
+ * @see #NEXT_LINE_ON_WRAP
+ */
+ public static final String FORMATTER_BRACE_POSITION_FOR_BLOCK = IDEPlugin.PLUGIN_ID + ".formatter.brace_position_for_block"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option to position the braces of a method declaration
+ * - option id: "org.eclipse.cdt.core.formatter.brace_position_for_method_declaration"
+ * - possible values: { END_OF_LINE, NEXT_LINE, NEXT_LINE_SHIFTED, NEXT_LINE_ON_WRAP }
+ * - default: END_OF_LINE
+ * </pre>
+ * @see #END_OF_LINE
+ * @see #NEXT_LINE
+ * @see #NEXT_LINE_SHIFTED
+ * @see #NEXT_LINE_ON_WRAP
+ */
+ public static final String FORMATTER_BRACE_POSITION_FOR_METHOD_DECLARATION = IDEPlugin.PLUGIN_ID + ".formatter.brace_position_for_method_declaration"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option to position the braces of a switch statement
+ * - option id: "org.eclipse.cdt.core.formatter.brace_position_for_switch"
+ * - possible values: { END_OF_LINE, NEXT_LINE, NEXT_LINE_SHIFTED, NEXT_LINE_ON_WRAP }
+ * - default: END_OF_LINE
+ * </pre>
+ * @see #END_OF_LINE
+ * @see #NEXT_LINE
+ * @see #NEXT_LINE_SHIFTED
+ * @see #NEXT_LINE_ON_WRAP
+ */
+ public static final String FORMATTER_BRACE_POSITION_FOR_SWITCH = IDEPlugin.PLUGIN_ID + ".formatter.brace_position_for_switch"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option to position the braces of a type declaration
+ * - option id: "org.eclipse.cdt.core.formatter.brace_position_for_type_declaration"
+ * - possible values: { END_OF_LINE, NEXT_LINE, NEXT_LINE_SHIFTED, NEXT_LINE_ON_WRAP }
+ * - default: END_OF_LINE
+ * </pre>
+ * @see #END_OF_LINE
+ * @see #NEXT_LINE
+ * @see #NEXT_LINE_SHIFTED
+ * @see #NEXT_LINE_ON_WRAP
+ */
+ public static final String FORMATTER_BRACE_POSITION_FOR_TYPE_DECLARATION = IDEPlugin.PLUGIN_ID + ".formatter.brace_position_for_type_declaration"; //$NON-NLS-1$
- /**
- * <pre>
- * FORMATTER / Option to set the continuation indentation
- * - option id: "org.eclipse.cdt.core.formatter.continuation_indentation"
- * - possible values: "&lt;n&gt;", where n is zero or a positive integer
- * - default: "2"
- * </pre>
- */
- public static final String FORMATTER_CONTINUATION_INDENTATION = IDEPlugin.PLUGIN_ID + ".formatter.continuation_indentation"; //$NON-NLS-1$
- /**
- * <pre>
- * FORMATTER / Option to indent 'public:', 'protected:', 'private:' access specifiers relative to class declaration.
- * - option id: "org.eclipse.cdt.core.formatter.indent_access_specifier_compare_to_type_header"
- * - possible values: { TRUE, FALSE }
- * - default: FALSE
- * </pre>
- * @see #TRUE
- * @see #FALSE
- */
- public static final String FORMATTER_INDENT_ACCESS_SPECIFIER_COMPARE_TO_TYPE_HEADER = IDEPlugin.PLUGIN_ID + ".formatter.indent_access_specifier_compare_to_type_header"; //$NON-NLS-1$
- /**
- * <pre>
- * FORMATTER / Number of extra spaces in front of 'public:', 'protected:', 'private:' access specifiers.
- * Enables fractional indent of access specifiers. Does not affect indentation of body declarations.
- * - option id: "org.eclipse.cdt.core.formatter.indent_access_specifier_extra_spaces"
- * - possible values: "&lt;n&gt;", where n is zero or a positive integer
- * - default: "0"
- * </pre>
- * @since 5.2
- */
- public static final String FORMATTER_INDENT_ACCESS_SPECIFIER_EXTRA_SPACES = IDEPlugin.PLUGIN_ID + ".formatter.indent_access_specifier_extra_spaces"; //$NON-NLS-1$
- /**
- * <pre>
- * FORMATTER / Option to indent body declarations relative to access specifiers (visibility labels)
- * - option id: "org.eclipse.cdt.core.formatter.indent_body_declarations_compare_to_access_specifier"
- * - possible values: { TRUE, FALSE }
- * - default: TRUE
- * </pre>
- * @see #TRUE
- * @see #FALSE
- */
- public static final String FORMATTER_INDENT_BODY_DECLARATIONS_COMPARE_TO_ACCESS_SPECIFIER = IDEPlugin.PLUGIN_ID + ".formatter.indent_body_declarations_compare_to_access_specifier"; //$NON-NLS-1$
- /**
- * <pre>
- * FORMATTER / Option to indent body declarations compare to its enclosing namespace header
- * - option id: "org.eclipse.cdt.core.formatter.indent_body_declarations_compare_to_namespace_header"
- * - possible values: { TRUE, FALSE }
- * - default: TRUE
- * </pre>
- * @see #TRUE
- * @see #FALSE
- */
- public static final String FORMATTER_INDENT_BODY_DECLARATIONS_COMPARE_TO_NAMESPACE_HEADER = IDEPlugin.PLUGIN_ID + ".formatter.indent_body_declarations_compare_to_namespace_header"; //$NON-NLS-1$
- /**
- * <pre>
- * FORMATTER / Option to indent empty lines
- * - option id: "org.eclipse.cdt.core.formatter.indent_empty_lines"
- * - possible values: { TRUE, FALSE }
- * - default: FALSE
- * </pre>
- * @see #TRUE
- * @see #FALSE
- */
- public static final String FORMATTER_INDENT_EMPTY_LINES = IDEPlugin.PLUGIN_ID + ".formatter.indent_empty_lines"; //$NON-NLS-1$
- /**
- * <pre>
- * FORMATTER / Option to indent inside line comments at column 0
- * - option id: "org.eclipse.cdt.core.formatter.indent_inside_line_comments"
- * - possible values: { TRUE, FALSE }
- * - default: FALSE
- * </pre>
- * @see #TRUE
- * @see #FALSE
- */
- public static final String FORMATTER_INDENT_INSIDE_LINE_COMMENTS = IDEPlugin.PLUGIN_ID + ".formatter.indent_inside_line_comments"; //$NON-NLS-1$
- /**
- * <pre>
- * FORMATTER / Option to indent statements inside a block
- * - option id: "org.eclipse.cdt.core.formatter.indent_statements_compare_to_block"
- * - possible values: { TRUE, FALSE }
- * - default: TRUE
- * </pre>
- * @see #TRUE
- * @see #FALSE
- */
- public static final String FORMATTER_INDENT_STATEMENTS_COMPARE_TO_BLOCK = IDEPlugin.PLUGIN_ID + ".formatter.indent_statements_compare_to_block"; //$NON-NLS-1$
- /**
- * <pre>
- * FORMATTER / Option to indent statements inside the body of a method or a constructor
- * - option id: "org.eclipse.cdt.core.formatter.indent_statements_compare_to_body"
- * - possible values: { TRUE, FALSE }
- * - default: TRUE
- * </pre>
- * @see #TRUE
- * @see #FALSE
- */
- public static final String FORMATTER_INDENT_STATEMENTS_COMPARE_TO_BODY = IDEPlugin.PLUGIN_ID + ".formatter.indent_statements_compare_to_body"; //$NON-NLS-1$
- /**
- * <pre>
- * FORMATTER / Option to indent switch statements compare to cases
- * - option id: "org.eclipse.cdt.core.formatter.indent_switchstatements_compare_to_cases"
- * - possible values: { TRUE, FALSE }
- * - default: TRUE
- * </pre>
- * @see #TRUE
- * @see #FALSE
- */
- public static final String FORMATTER_INDENT_SWITCHSTATEMENTS_COMPARE_TO_CASES = IDEPlugin.PLUGIN_ID + ".formatter.indent_switchstatements_compare_to_cases"; //$NON-NLS-1$
- /**
- * <pre>
- * FORMATTER / Option to indent switch statements compare to switch
- * - option id: "org.eclipse.cdt.core.formatter.indent_switchstatements_compare_to_switch"
- * - possible values: { TRUE, FALSE }
- * - default: TRUE
- * </pre>
- * @see #TRUE
- * @see #FALSE
- */
- public static final String FORMATTER_INDENT_SWITCHSTATEMENTS_COMPARE_TO_SWITCH = IDEPlugin.PLUGIN_ID + ".formatter.indent_switchstatements_compare_to_switch"; //$NON-NLS-1$
- /**
- * <pre>
- * FORMATTER / Option to specify the tabulation size
- * - option id: "org.eclipse.cdt.core.formatter.tabulation.char"
- * - possible values: { TAB, SPACE, MIXED }
- * - default: TAB
- * </pre>
- * More values may be added in the future.
- *
- * @see IDEPlugin#TAB
- * @see IDEPlugin#SPACE
- * @see #MIXED
- */
- public static final String FORMATTER_TAB_CHAR = IDEPlugin.PLUGIN_ID + ".formatter.tabulation.char"; //$NON-NLS-1$
- /**
- * <pre>
- * FORMATTER / Option to specify the equivalent number of spaces that represents one tabulation
- * - option id: "org.eclipse.cdt.core.formatter.tabulation.size"
- * - possible values: "&lt;n&gt;", where n is zero or a positive integer
- * - default: "4"
- * </pre>
- */
- public static final String FORMATTER_TAB_SIZE = IDEPlugin.PLUGIN_ID + ".formatter.tabulation.size"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option to set the continuation indentation
+ * - option id: "org.eclipse.cdt.core.formatter.continuation_indentation"
+ * - possible values: "&lt;n&gt;", where n is zero or a positive integer
+ * - default: "2"
+ * </pre>
+ */
+ public static final String FORMATTER_CONTINUATION_INDENTATION = IDEPlugin.PLUGIN_ID + ".formatter.continuation_indentation"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option to indent 'public:', 'protected:', 'private:' access specifiers relative to class declaration.
+ * - option id: "org.eclipse.cdt.core.formatter.indent_access_specifier_compare_to_type_header"
+ * - possible values: { TRUE, FALSE }
+ * - default: FALSE
+ * </pre>
+ * @see #TRUE
+ * @see #FALSE
+ */
+ public static final String FORMATTER_INDENT_ACCESS_SPECIFIER_COMPARE_TO_TYPE_HEADER = IDEPlugin.PLUGIN_ID + ".formatter.indent_access_specifier_compare_to_type_header"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Number of extra spaces in front of 'public:', 'protected:', 'private:' access specifiers.
+ * Enables fractional indent of access specifiers. Does not affect indentation of body declarations.
+ * - option id: "org.eclipse.cdt.core.formatter.indent_access_specifier_extra_spaces"
+ * - possible values: "&lt;n&gt;", where n is zero or a positive integer
+ * - default: "0"
+ * </pre>
+ * @since 5.2
+ */
+ public static final String FORMATTER_INDENT_ACCESS_SPECIFIER_EXTRA_SPACES = IDEPlugin.PLUGIN_ID + ".formatter.indent_access_specifier_extra_spaces"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option to indent body declarations relative to access specifiers (visibility labels)
+ * - option id: "org.eclipse.cdt.core.formatter.indent_body_declarations_compare_to_access_specifier"
+ * - possible values: { TRUE, FALSE }
+ * - default: TRUE
+ * </pre>
+ * @see #TRUE
+ * @see #FALSE
+ */
+ public static final String FORMATTER_INDENT_BODY_DECLARATIONS_COMPARE_TO_ACCESS_SPECIFIER = IDEPlugin.PLUGIN_ID + ".formatter.indent_body_declarations_compare_to_access_specifier"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option to indent body declarations compare to its enclosing namespace header
+ * - option id: "org.eclipse.cdt.core.formatter.indent_body_declarations_compare_to_namespace_header"
+ * - possible values: { TRUE, FALSE }
+ * - default: TRUE
+ * </pre>
+ * @see #TRUE
+ * @see #FALSE
+ */
+ public static final String FORMATTER_INDENT_BODY_DECLARATIONS_COMPARE_TO_NAMESPACE_HEADER = IDEPlugin.PLUGIN_ID + ".formatter.indent_body_declarations_compare_to_namespace_header"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option to indent empty lines
+ * - option id: "org.eclipse.cdt.core.formatter.indent_empty_lines"
+ * - possible values: { TRUE, FALSE }
+ * - default: FALSE
+ * </pre>
+ * @see #TRUE
+ * @see #FALSE
+ */
+ public static final String FORMATTER_INDENT_EMPTY_LINES = IDEPlugin.PLUGIN_ID + ".formatter.indent_empty_lines"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option to indent inside line comments at column 0
+ * - option id: "org.eclipse.cdt.core.formatter.indent_inside_line_comments"
+ * - possible values: { TRUE, FALSE }
+ * - default: FALSE
+ * </pre>
+ * @see #TRUE
+ * @see #FALSE
+ */
+ public static final String FORMATTER_INDENT_INSIDE_LINE_COMMENTS = IDEPlugin.PLUGIN_ID + ".formatter.indent_inside_line_comments"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option to indent statements inside a block
+ * - option id: "org.eclipse.cdt.core.formatter.indent_statements_compare_to_block"
+ * - possible values: { TRUE, FALSE }
+ * - default: TRUE
+ * </pre>
+ * @see #TRUE
+ * @see #FALSE
+ */
+ public static final String FORMATTER_INDENT_STATEMENTS_COMPARE_TO_BLOCK = IDEPlugin.PLUGIN_ID + ".formatter.indent_statements_compare_to_block"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option to indent statements inside the body of a method or a constructor
+ * - option id: "org.eclipse.cdt.core.formatter.indent_statements_compare_to_body"
+ * - possible values: { TRUE, FALSE }
+ * - default: TRUE
+ * </pre>
+ * @see #TRUE
+ * @see #FALSE
+ */
+ public static final String FORMATTER_INDENT_STATEMENTS_COMPARE_TO_BODY = IDEPlugin.PLUGIN_ID + ".formatter.indent_statements_compare_to_body"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option to indent switch statements compare to cases
+ * - option id: "org.eclipse.cdt.core.formatter.indent_switchstatements_compare_to_cases"
+ * - possible values: { TRUE, FALSE }
+ * - default: TRUE
+ * </pre>
+ * @see #TRUE
+ * @see #FALSE
+ */
+ public static final String FORMATTER_INDENT_SWITCHSTATEMENTS_COMPARE_TO_CASES = IDEPlugin.PLUGIN_ID + ".formatter.indent_switchstatements_compare_to_cases"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option to indent switch statements compare to switch
+ * - option id: "org.eclipse.cdt.core.formatter.indent_switchstatements_compare_to_switch"
+ * - possible values: { TRUE, FALSE }
+ * - default: TRUE
+ * </pre>
+ * @see #TRUE
+ * @see #FALSE
+ */
+ public static final String FORMATTER_INDENT_SWITCHSTATEMENTS_COMPARE_TO_SWITCH = IDEPlugin.PLUGIN_ID + ".formatter.indent_switchstatements_compare_to_switch"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option to specify the tabulation size
+ * - option id: "org.eclipse.cdt.core.formatter.tabulation.char"
+ * - possible values: { TAB, SPACE, MIXED }
+ * - default: TAB
+ * </pre>
+ * More values may be added in the future.
+ *
+ * @see IDEPlugin#TAB
+ * @see IDEPlugin#SPACE
+ * @see #MIXED
+ */
+ public static final String FORMATTER_TAB_CHAR = IDEPlugin.PLUGIN_ID + ".formatter.tabulation.char"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option to specify the equivalent number of spaces that represents one tabulation
+ * - option id: "org.eclipse.cdt.core.formatter.tabulation.size"
+ * - possible values: "&lt;n&gt;", where n is zero or a positive integer
+ * - default: "4"
+ * </pre>
+ */
+ public static final String FORMATTER_TAB_SIZE = IDEPlugin.PLUGIN_ID + ".formatter.tabulation.size"; //$NON-NLS-1$
- /**
- * <pre>
- * FORMATTER / The wrapping is done by indenting by one compare to the current indentation.
- * </pre>
- */
- public static final int INDENT_BY_ONE= 2;
+ /**
+ * <pre>
+ * FORMATTER / The wrapping is done by indenting by one compare to the current indentation.
+ * </pre>
+ */
+ public static final int INDENT_BY_ONE= 2;
- /**
- * <pre>
- * FORMATTER / The wrapping is done by using the current indentation.
- * </pre>
- */
- public static final int INDENT_DEFAULT= 0;
- /**
- * <pre>
- * FORMATTER / The wrapping is done by indenting on column under the splitting location.
- * </pre>
- */
- public static final int INDENT_ON_COLUMN = 1;
+ /**
+ * <pre>
+ * FORMATTER / The wrapping is done by using the current indentation.
+ * </pre>
+ */
+ public static final int INDENT_DEFAULT= 0;
+ /**
+ * <pre>
+ * FORMATTER / The wrapping is done by indenting on column under the splitting location.
+ * </pre>
+ */
+ public static final int INDENT_ON_COLUMN = 1;
- /**
- * <pre>
- * FORMATTER / Possible value for the option FORMATTER_TAB_CHAR
- * </pre>
- * @see IDEPlugin#TAB
- * @see IDEPlugin#SPACE
- * @see #FORMATTER_TAB_CHAR
- */
- public static final String MIXED = "mixed"; //$NON-NLS-1$
- /**
- * <pre>
- * FORMATTER / Value to set a brace location at the start of the next line with
- * an extra indentation.
- * </pre>
- * @see #FORMATTER_BRACE_POSITION_FOR_INITIALIZER_LIST
- * @see #FORMATTER_BRACE_POSITION_FOR_BLOCK
- * @see #FORMATTER_BRACE_POSITION_FOR_METHOD_DECLARATION
- * @see #FORMATTER_BRACE_POSITION_FOR_SWITCH
- * @see #FORMATTER_BRACE_POSITION_FOR_TYPE_DECLARATION
- */
- public static final String NEXT_LINE_SHIFTED = "next_line_shifted"; //$NON-NLS-1$
- /**
- * <pre>
- * FORMATTER / Value to set an option to true.
- * </pre>
- */
- public static final String TRUE = "true"; //$NON-NLS-1$
- /**
- * <pre>
- * FORMATTER / The wrapping is done using as few lines as possible.
- * </pre>
- */
- public static final int WRAP_COMPACT= 1;
- /**
- * <pre>
- * FORMATTER / The wrapping is done putting the first element on a new
- * line and then wrapping next elements using as few lines as possible.
- * </pre>
- */
- public static final int WRAP_COMPACT_FIRST_BREAK= 2;
- /**
- * <pre>
- * FORMATTER / The wrapping is done by putting each element on its own line
- * except the first element.
- * </pre>
- */
- public static final int WRAP_NEXT_PER_LINE= 5;
- /**
- * <pre>
- * FORMATTER / The wrapping is done by putting each element on its own line.
- * All elements are indented by one except the first element.
- * </pre>
- */
- public static final int WRAP_NEXT_SHIFTED= 4;
+ /**
+ * <pre>
+ * FORMATTER / Possible value for the option FORMATTER_TAB_CHAR
+ * </pre>
+ * @see IDEPlugin#TAB
+ * @see IDEPlugin#SPACE
+ * @see #FORMATTER_TAB_CHAR
+ */
+ public static final String MIXED = "mixed"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Value to set a brace location at the start of the next line with
+ * an extra indentation.
+ * </pre>
+ * @see #FORMATTER_BRACE_POSITION_FOR_INITIALIZER_LIST
+ * @see #FORMATTER_BRACE_POSITION_FOR_BLOCK
+ * @see #FORMATTER_BRACE_POSITION_FOR_METHOD_DECLARATION
+ * @see #FORMATTER_BRACE_POSITION_FOR_SWITCH
+ * @see #FORMATTER_BRACE_POSITION_FOR_TYPE_DECLARATION
+ */
+ public static final String NEXT_LINE_SHIFTED = "next_line_shifted"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Value to set an option to true.
+ * </pre>
+ */
+ public static final String TRUE = "true"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / The wrapping is done using as few lines as possible.
+ * </pre>
+ */
+ public static final int WRAP_COMPACT= 1;
+ /**
+ * <pre>
+ * FORMATTER / The wrapping is done putting the first element on a new
+ * line and then wrapping next elements using as few lines as possible.
+ * </pre>
+ */
+ public static final int WRAP_COMPACT_FIRST_BREAK= 2;
+ /**
+ * <pre>
+ * FORMATTER / The wrapping is done by putting each element on its own line
+ * except the first element.
+ * </pre>
+ */
+ public static final int WRAP_NEXT_PER_LINE= 5;
+ /**
+ * <pre>
+ * FORMATTER / The wrapping is done by putting each element on its own line.
+ * All elements are indented by one except the first element.
+ * </pre>
+ */
+ public static final int WRAP_NEXT_SHIFTED= 4;
- /**
- * <pre>
- * FORMATTER / Value to disable alignment.
- * </pre>
- */
- public static final int WRAP_NO_SPLIT= 0;
- /**
- * <pre>
- * FORMATTER / The wrapping is done by putting each element on its own line.
- * </pre>
- */
- public static final int WRAP_ONE_PER_LINE= 3;
+ /**
+ * <pre>
+ * FORMATTER / Value to disable alignment.
+ * </pre>
+ */
+ public static final int WRAP_NO_SPLIT= 0;
+ /**
+ * <pre>
+ * FORMATTER / The wrapping is done by putting each element on its own line.
+ * </pre>
+ */
+ public static final int WRAP_ONE_PER_LINE= 3;
- /*
- * Private constants.
- */
- private static final IllegalArgumentException WRONG_ARGUMENT = new IllegalArgumentException();
+ /*
+ * Private constants.
+ */
+ private static final IllegalArgumentException WRONG_ARGUMENT = new IllegalArgumentException();
- /**
- * <p>Return the indentation style of the given alignment value.
- * The given alignment value should be created using the <code>createAlignmentValue(boolean, int, int)</code>
- * API.
- * </p>
- *
- * @param value the given alignment value
- * @return the indentation style of the given alignment value
- * @see #createAlignmentValue(boolean, int, int)
- * @exception IllegalArgumentException if the given alignment value is null, or if it
- * doesn't have a valid format.
- */
- public static int getIndentStyle(String value) {
- if (value == null) {
- throw WRONG_ARGUMENT;
- }
- try {
- int existingValue = Integer.parseInt(value);
- if ((existingValue & STPAlignment.M_INDENT_BY_ONE) != 0) {
- return INDENT_BY_ONE;
- } else if ((existingValue & STPAlignment.M_INDENT_ON_COLUMN) != 0) {
- return INDENT_ON_COLUMN;
- } else {
- return INDENT_DEFAULT;
- }
- } catch (NumberFormatException e) {
- throw WRONG_ARGUMENT;
- }
- }
+ /**
+ * <p>Return the indentation style of the given alignment value.
+ * The given alignment value should be created using the <code>createAlignmentValue(boolean, int, int)</code>
+ * API.
+ * </p>
+ *
+ * @param value the given alignment value
+ * @return the indentation style of the given alignment value
+ * @see #createAlignmentValue(boolean, int, int)
+ * @exception IllegalArgumentException if the given alignment value is null, or if it
+ * doesn't have a valid format.
+ */
+ public static int getIndentStyle(String value) {
+ if (value == null) {
+ throw WRONG_ARGUMENT;
+ }
+ try {
+ int existingValue = Integer.parseInt(value);
+ if ((existingValue & STPAlignment.M_INDENT_BY_ONE) != 0) {
+ return INDENT_BY_ONE;
+ } else if ((existingValue & STPAlignment.M_INDENT_ON_COLUMN) != 0) {
+ return INDENT_ON_COLUMN;
+ } else {
+ return INDENT_DEFAULT;
+ }
+ } catch (NumberFormatException e) {
+ throw WRONG_ARGUMENT;
+ }
+ }
- /**
- * <p>Return the wrapping style of the given alignment value.
- * The given alignment value should be created using the <code>createAlignmentValue(boolean, int, int)</code>
- * API.
- * </p>
- *
- * @param value the given alignment value
- * @return the wrapping style of the given alignment value
- * @see #createAlignmentValue(boolean, int, int)
- * @exception IllegalArgumentException if the given alignment value is null, or if it
- * doesn't have a valid format.
- */
- public static int getWrappingStyle(String value) {
- if (value == null) {
- throw WRONG_ARGUMENT;
- }
- try {
- int existingValue = Integer.parseInt(value) & STPAlignment.SPLIT_MASK;
- switch (existingValue) {
- case STPAlignment.M_COMPACT_SPLIT:
- return WRAP_COMPACT;
- case STPAlignment.M_COMPACT_FIRST_BREAK_SPLIT:
- return WRAP_COMPACT_FIRST_BREAK;
- case STPAlignment.M_NEXT_PER_LINE_SPLIT:
- return WRAP_NEXT_PER_LINE;
- case STPAlignment.M_NEXT_SHIFTED_SPLIT:
- return WRAP_NEXT_SHIFTED;
- case STPAlignment.M_ONE_PER_LINE_SPLIT:
- return WRAP_ONE_PER_LINE;
- default:
- return WRAP_NO_SPLIT;
- }
- } catch (NumberFormatException e) {
- throw WRONG_ARGUMENT;
- }
- }
+ /**
+ * <p>Return the wrapping style of the given alignment value.
+ * The given alignment value should be created using the <code>createAlignmentValue(boolean, int, int)</code>
+ * API.
+ * </p>
+ *
+ * @param value the given alignment value
+ * @return the wrapping style of the given alignment value
+ * @see #createAlignmentValue(boolean, int, int)
+ * @exception IllegalArgumentException if the given alignment value is null, or if it
+ * doesn't have a valid format.
+ */
+ public static int getWrappingStyle(String value) {
+ if (value == null) {
+ throw WRONG_ARGUMENT;
+ }
+ try {
+ int existingValue = Integer.parseInt(value) & STPAlignment.SPLIT_MASK;
+ switch (existingValue) {
+ case STPAlignment.M_COMPACT_SPLIT:
+ return WRAP_COMPACT;
+ case STPAlignment.M_COMPACT_FIRST_BREAK_SPLIT:
+ return WRAP_COMPACT_FIRST_BREAK;
+ case STPAlignment.M_NEXT_PER_LINE_SPLIT:
+ return WRAP_NEXT_PER_LINE;
+ case STPAlignment.M_NEXT_SHIFTED_SPLIT:
+ return WRAP_NEXT_SHIFTED;
+ case STPAlignment.M_ONE_PER_LINE_SPLIT:
+ return WRAP_ONE_PER_LINE;
+ default:
+ return WRAP_NO_SPLIT;
+ }
+ } catch (NumberFormatException e) {
+ throw WRONG_ARGUMENT;
+ }
+ }
}
diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/STPDocumentProvider.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/STPDocumentProvider.java
index 1e7feb9970..1a1269398f 100644
--- a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/STPDocumentProvider.java
+++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/STPDocumentProvider.java
@@ -24,31 +24,31 @@ import org.eclipse.ui.editors.text.TextFileDocumentProvider;
public class STPDocumentProvider extends TextFileDocumentProvider {
- @Override
- public void connect(Object element) throws CoreException {
- super.connect(element);
- setupDocument(this.getDocument(element));
- }
+ @Override
+ public void connect(Object element) throws CoreException {
+ super.connect(element);
+ setupDocument(this.getDocument(element));
+ }
- protected void setupDocument(IDocument document) {
- if (document != null) {
- IDocumentPartitioner partitioner = new FastPartitioner(
- new STPPartitionScanner(), STPPartitionScanner.STP_PARTITION_TYPES);
- partitioner.connect(document);
- IDocumentPartitioner partitioner2 = new FastPartitioner(
- new STPProbeScanner(), STPProbeScanner.STP_PROBE_PARTITION_TYPES);
- partitioner2.connect(document);
- ((IDocumentExtension3)document).setDocumentPartitioner(STPPartitionScanner.STP_PARTITIONING, partitioner);
- ((IDocumentExtension3)document).setDocumentPartitioner(STPProbeScanner.STP_PROBE_PARTITIONING, partitioner2);
- }
- }
+ protected void setupDocument(IDocument document) {
+ if (document != null) {
+ IDocumentPartitioner partitioner = new FastPartitioner(
+ new STPPartitionScanner(), STPPartitionScanner.STP_PARTITION_TYPES);
+ partitioner.connect(document);
+ IDocumentPartitioner partitioner2 = new FastPartitioner(
+ new STPProbeScanner(), STPProbeScanner.STP_PROBE_PARTITION_TYPES);
+ partitioner2.connect(document);
+ ((IDocumentExtension3)document).setDocumentPartitioner(STPPartitionScanner.STP_PARTITIONING, partitioner);
+ ((IDocumentExtension3)document).setDocumentPartitioner(STPProbeScanner.STP_PROBE_PARTITIONING, partitioner2);
+ }
+ }
- /**
- * Instantiates and returns a new AnnotationModel object.
- */
- @Override
- protected IAnnotationModel createAnnotationModel(IFile file) {
- return new AnnotationModel();
- }
+ /**
+ * Instantiates and returns a new AnnotationModel object.
+ */
+ @Override
+ protected IAnnotationModel createAnnotationModel(IFile file) {
+ return new AnnotationModel();
+ }
}
diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/STPEditor.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/STPEditor.java
index bdd1744612..045cfd537b 100644
--- a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/STPEditor.java
+++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/STPEditor.java
@@ -1,13 +1,13 @@
/*******************************************************************************
* Copyright (c) 2008 Phil Muldoon <pkmuldoon@picobot.org>.
- *
+ *
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
- * Phil Muldoon <pkmuldoon@picobot.org> - initial API.
+ * Phil Muldoon <pkmuldoon@picobot.org> - initial API.
*******************************************************************************/
package org.eclipse.linuxtools.internal.systemtap.ui.ide.editors.stp;
@@ -36,89 +36,89 @@ import org.eclipse.ui.texteditor.ITextEditorActionConstants;
public class STPEditor extends SimpleEditor {
- private ColorManager colorManager;
-
+ private ColorManager colorManager;
+
private ProjectionSupport stpProjectionSupport;
- private Annotation[] stpOldAnnotations;
- private ProjectionAnnotationModel stpAnnotationModel;
-
- public static final String ID="org.eclipse.linuxtools.internal.systemtap.ui.ide.editors.stp.STPEditor"; //$NON-NLS-1$
-
- public STPEditor() {
- super();
- colorManager = new ColorManager();
- setSourceViewerConfiguration(new STPConfiguration(colorManager,this));
- }
-
- @Override
- protected void internalInit() {
- configureInsertMode(SMART_INSERT, false);
- setDocumentProvider(new STPDocumentProvider());
- }
-
- @Override
- protected void doSetInput(IEditorInput input) throws CoreException {
- if(input instanceof FileStoreEditorInput) {
- input= new PathEditorInput(new Path(((FileStoreEditorInput) input).getURI().getPath()));
- }
- super.doSetInput(input);
- }
-
- @Override
- public void createPartControl(Composite parent)
- {
- super.createPartControl(parent);
- ProjectionViewer viewer =(ProjectionViewer)getSourceViewer();
- stpProjectionSupport = new ProjectionSupport(viewer,getAnnotationAccess(),getSharedColors());
- stpProjectionSupport.install();
- viewer.doOperation(ProjectionViewer.TOGGLE);
- stpAnnotationModel = viewer.getProjectionAnnotationModel();
- }
-
- @Override
- protected ISourceViewer createSourceViewer(Composite parent, IVerticalRuler ruler, int styles) {
-
- ISourceViewer viewer = new ProjectionViewer(parent, ruler,
- getOverviewRuler(), isOverviewRulerVisible(), styles);
- getSourceViewerDecorationSupport(viewer);
- return viewer;
- }
-
-
- public void updateFoldingStructure(ArrayList<Position> updatedPositions)
- {
- ProjectionAnnotation annotation;
- Annotation[] updatedAnnotations = new Annotation[updatedPositions.size()];
- HashMap<ProjectionAnnotation, Position> newAnnotations = new HashMap<>();
- for(int i =0;i<updatedPositions.size();i++)
- {
- annotation = new ProjectionAnnotation();
- newAnnotations.put(annotation,updatedPositions.get(i));
- updatedAnnotations[i]=annotation;
- }
- stpAnnotationModel.modifyAnnotations(stpOldAnnotations,newAnnotations,null);
- stpOldAnnotations = updatedAnnotations;
- }
-
- public ISourceViewer getMySourceViewer() {
- return this.getSourceViewer();
- }
-
- @Override
- public void dispose() {
- colorManager.dispose();
- super.dispose();
- }
-
- @Override
- protected void editorContextMenuAboutToShow(IMenuManager menu) {
-
- super.editorContextMenuAboutToShow(menu);
- addAction(menu, ITextEditorActionConstants.GROUP_EDIT,
- ITextEditorActionConstants.SHIFT_RIGHT);
- addAction(menu, ITextEditorActionConstants.GROUP_EDIT,
- ITextEditorActionConstants.SHIFT_LEFT);
-
- }
-
+ private Annotation[] stpOldAnnotations;
+ private ProjectionAnnotationModel stpAnnotationModel;
+
+ public static final String ID="org.eclipse.linuxtools.internal.systemtap.ui.ide.editors.stp.STPEditor"; //$NON-NLS-1$
+
+ public STPEditor() {
+ super();
+ colorManager = new ColorManager();
+ setSourceViewerConfiguration(new STPConfiguration(colorManager,this));
+ }
+
+ @Override
+ protected void internalInit() {
+ configureInsertMode(SMART_INSERT, false);
+ setDocumentProvider(new STPDocumentProvider());
+ }
+
+ @Override
+ protected void doSetInput(IEditorInput input) throws CoreException {
+ if(input instanceof FileStoreEditorInput) {
+ input= new PathEditorInput(new Path(((FileStoreEditorInput) input).getURI().getPath()));
+ }
+ super.doSetInput(input);
+ }
+
+ @Override
+ public void createPartControl(Composite parent)
+ {
+ super.createPartControl(parent);
+ ProjectionViewer viewer =(ProjectionViewer)getSourceViewer();
+ stpProjectionSupport = new ProjectionSupport(viewer,getAnnotationAccess(),getSharedColors());
+ stpProjectionSupport.install();
+ viewer.doOperation(ProjectionViewer.TOGGLE);
+ stpAnnotationModel = viewer.getProjectionAnnotationModel();
+ }
+
+ @Override
+ protected ISourceViewer createSourceViewer(Composite parent, IVerticalRuler ruler, int styles) {
+
+ ISourceViewer viewer = new ProjectionViewer(parent, ruler,
+ getOverviewRuler(), isOverviewRulerVisible(), styles);
+ getSourceViewerDecorationSupport(viewer);
+ return viewer;
+ }
+
+
+ public void updateFoldingStructure(ArrayList<Position> updatedPositions)
+ {
+ ProjectionAnnotation annotation;
+ Annotation[] updatedAnnotations = new Annotation[updatedPositions.size()];
+ HashMap<ProjectionAnnotation, Position> newAnnotations = new HashMap<>();
+ for(int i =0;i<updatedPositions.size();i++)
+ {
+ annotation = new ProjectionAnnotation();
+ newAnnotations.put(annotation,updatedPositions.get(i));
+ updatedAnnotations[i]=annotation;
+ }
+ stpAnnotationModel.modifyAnnotations(stpOldAnnotations,newAnnotations,null);
+ stpOldAnnotations = updatedAnnotations;
+ }
+
+ public ISourceViewer getMySourceViewer() {
+ return this.getSourceViewer();
+ }
+
+ @Override
+ public void dispose() {
+ colorManager.dispose();
+ super.dispose();
+ }
+
+ @Override
+ protected void editorContextMenuAboutToShow(IMenuManager menu) {
+
+ super.editorContextMenuAboutToShow(menu);
+ addAction(menu, ITextEditorActionConstants.GROUP_EDIT,
+ ITextEditorActionConstants.SHIFT_RIGHT);
+ addAction(menu, ITextEditorActionConstants.GROUP_EDIT,
+ ITextEditorActionConstants.SHIFT_LEFT);
+
+ }
+
} \ No newline at end of file
diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/STPElementScanner.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/STPElementScanner.java
index 183678ecde..51ade8b5a9 100644
--- a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/STPElementScanner.java
+++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/STPElementScanner.java
@@ -1,13 +1,13 @@
/*******************************************************************************
* Copyright (c) 2008 Phil Muldoon <pkmuldoon@picobot.org>.
- *
+ *
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
- * Phil Muldoon <pkmuldoon@picobot.org> - initial API and implementation.
+ * Phil Muldoon <pkmuldoon@picobot.org> - initial API and implementation.
*******************************************************************************/
package org.eclipse.linuxtools.internal.systemtap.ui.ide.editors.stp;
@@ -29,80 +29,80 @@ import org.eclipse.swt.SWT;
public class STPElementScanner extends BufferedRuleBasedScanner {
- private String[] keywordList = { "probe", "for", "else", //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$
- "foreach", "exit", "printf", "in", //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$//$NON-NLS-4$
- "return", "break", "global", "next", //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$//$NON-NLS-4$
- "while", "if", "delete", "#include", //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$//$NON-NLS-4$
- "function", "do", "print", "error", //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$//$NON-NLS-4$
- "log", "printd", "printdln", "println", //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$//$NON-NLS-4$
- "sprint", "sprintf", "system", "warn" }; //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$//$NON-NLS-4$
-
- /**
- *
- * Build Element scanner for Syntax Highlighting for Systemtap Editor
- *
- * @param manager ColorManager to source highlighting.
- *
- */
- public STPElementScanner(ColorManager manager) {
- IToken defaultToken = new Token(new TextAttribute(manager
- .getColor(STPColorConstants.DEFAULT)));
-
- IToken keywordToken = new Token(new TextAttribute(manager
- .getColor(STPColorConstants.KEYWORD),null,SWT.BOLD));
-
- IToken commentToken = new Token(new TextAttribute(manager
- .getColor(STPColorConstants.COMMENT)));
-
- IToken stringToken = new Token(new TextAttribute(manager
- .getColor(STPColorConstants.STP_STRING)));
-
-
- // Build keyword scanner
- WordRule keywordsRule = new WordRule(new IWordDetector() {
-
- @Override
- public boolean isWordStart(char c) {
- // probe kernel.function("schedule") is a valid name in
- // Systemtap, but we do not want to highlight the function
- // here as a keyword. Same with foo.return and so on.
- if (c == '.') {
- return true;
- }
-
- return Character.isJavaIdentifierStart(c);
- }
-
- @Override
- public boolean isWordPart(char c) {
- // Set isWordStart for . rule.
- if (c == '.') {
- return true;
- }
-
- return Character.isJavaIdentifierPart(c);
- }
-
- }, defaultToken, true);
-
- for (int i=0; i<keywordList.length; i++)
- keywordsRule.addWord(keywordList[i], keywordToken);
-
- setRules(new IRule[] { new MultiLineRule("/*", "*/", commentToken), //$NON-NLS-1$//$NON-NLS-2$
- new EndOfLineRule("/*", commentToken), //$NON-NLS-1$
- new EndOfLineRule("#", commentToken), //$NON-NLS-1$
- new EndOfLineRule("//", commentToken), //$NON-NLS-1$
- new EndOfLineRule("#if", defaultToken), //$NON-NLS-1$
- new EndOfLineRule("#else", defaultToken), //$NON-NLS-1$
- new EndOfLineRule("#endif", defaultToken), //$NON-NLS-1$
- new EndOfLineRule("#define", defaultToken), //$NON-NLS-1$
- new SingleLineRule("\"", "\"", stringToken, '\\'), //$NON-NLS-1$ //$NON-NLS-2$
- new SingleLineRule("'", "'", stringToken, '\\'), //$NON-NLS-1$//$NON-NLS-2$
- keywordsRule, new WhitespaceRule(new IWhitespaceDetector() {
- @Override
- public boolean isWhitespace(char c) {
- return Character.isWhitespace(c);
- }
- }), });
- }
+ private String[] keywordList = { "probe", "for", "else", //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$
+ "foreach", "exit", "printf", "in", //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$//$NON-NLS-4$
+ "return", "break", "global", "next", //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$//$NON-NLS-4$
+ "while", "if", "delete", "#include", //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$//$NON-NLS-4$
+ "function", "do", "print", "error", //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$//$NON-NLS-4$
+ "log", "printd", "printdln", "println", //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$//$NON-NLS-4$
+ "sprint", "sprintf", "system", "warn" }; //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$//$NON-NLS-4$
+
+ /**
+ *
+ * Build Element scanner for Syntax Highlighting for Systemtap Editor
+ *
+ * @param manager ColorManager to source highlighting.
+ *
+ */
+ public STPElementScanner(ColorManager manager) {
+ IToken defaultToken = new Token(new TextAttribute(manager
+ .getColor(STPColorConstants.DEFAULT)));
+
+ IToken keywordToken = new Token(new TextAttribute(manager
+ .getColor(STPColorConstants.KEYWORD),null,SWT.BOLD));
+
+ IToken commentToken = new Token(new TextAttribute(manager
+ .getColor(STPColorConstants.COMMENT)));
+
+ IToken stringToken = new Token(new TextAttribute(manager
+ .getColor(STPColorConstants.STP_STRING)));
+
+
+ // Build keyword scanner
+ WordRule keywordsRule = new WordRule(new IWordDetector() {
+
+ @Override
+ public boolean isWordStart(char c) {
+ // probe kernel.function("schedule") is a valid name in
+ // Systemtap, but we do not want to highlight the function
+ // here as a keyword. Same with foo.return and so on.
+ if (c == '.') {
+ return true;
+ }
+
+ return Character.isJavaIdentifierStart(c);
+ }
+
+ @Override
+ public boolean isWordPart(char c) {
+ // Set isWordStart for . rule.
+ if (c == '.') {
+ return true;
+ }
+
+ return Character.isJavaIdentifierPart(c);
+ }
+
+ }, defaultToken, true);
+
+ for (int i=0; i<keywordList.length; i++)
+ keywordsRule.addWord(keywordList[i], keywordToken);
+
+ setRules(new IRule[] { new MultiLineRule("/*", "*/", commentToken), //$NON-NLS-1$//$NON-NLS-2$
+ new EndOfLineRule("/*", commentToken), //$NON-NLS-1$
+ new EndOfLineRule("#", commentToken), //$NON-NLS-1$
+ new EndOfLineRule("//", commentToken), //$NON-NLS-1$
+ new EndOfLineRule("#if", defaultToken), //$NON-NLS-1$
+ new EndOfLineRule("#else", defaultToken), //$NON-NLS-1$
+ new EndOfLineRule("#endif", defaultToken), //$NON-NLS-1$
+ new EndOfLineRule("#define", defaultToken), //$NON-NLS-1$
+ new SingleLineRule("\"", "\"", stringToken, '\\'), //$NON-NLS-1$ //$NON-NLS-2$
+ new SingleLineRule("'", "'", stringToken, '\\'), //$NON-NLS-1$//$NON-NLS-2$
+ keywordsRule, new WhitespaceRule(new IWhitespaceDetector() {
+ @Override
+ public boolean isWhitespace(char c) {
+ return Character.isWhitespace(c);
+ }
+ }), });
+ }
}
diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/STPHeuristicScanner.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/STPHeuristicScanner.java
index 7237abb757..37d1161e8a 100644
--- a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/STPHeuristicScanner.java
+++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/STPHeuristicScanner.java
@@ -30,1039 +30,1039 @@ import org.eclipse.jface.text.TypedRegion;
* <p>An instance holds some internal position in the document and is therefore not thread-safe.</p>
*/
public final class STPHeuristicScanner implements STPSymbols {
- /**
- * Returned by all methods when the requested position could not be found, or if a
- * {@link BadLocationException} was thrown while scanning.
- */
- public static final int NOT_FOUND= -1;
-
- /**
- * Special bound parameter that means either -1 (backward scanning) or
- * <code>fDocument.getLength()</code> (forward scanning).
- */
- public static final int UNBOUND= -2;
-
-
- /* character constants */
- private static final char LBRACE= '{';
- private static final char RBRACE= '}';
- private static final char LPAREN= '(';
- private static final char RPAREN= ')';
- private static final char SEMICOLON= ';';
- private static final char COLON= ':';
- private static final char COMMA= ',';
- private static final char LBRACKET= '[';
- private static final char RBRACKET= ']';
- private static final char QUESTIONMARK= '?';
- private static final char EQUAL= '=';
- private static final char LANGLE= '<';
- private static final char RANGLE= '>';
- private static final char DOT= '.';
- private static final char MINUS= '-';
- private static final char PLUS= '+';
- private static final char TILDE= '~';
-
- /**
- * Specifies the stop condition, upon which the <code>scanXXX</code> methods will decide whether
- * to keep scanning or not. This interface may implemented by clients.
- */
- private static abstract class StopCondition {
- /**
- * Instructs the scanner to return the current position.
- *
- * @param ch the char at the current position
- * @param position the current position
- * @param forward the iteration direction
- * @return <code>true</code> if the stop condition is met.
- */
- public abstract boolean stop(char ch, int position, boolean forward);
-
- /**
- * Asks the condition to return the next position to query. The default
- * is to return the next/previous position.
- *
- * @return the next position to scan
- */
- public int nextPosition(int position, boolean forward) {
- return forward ? position + 1 : position - 1;
- }
- }
-
- /**
- * Stops upon a non-whitespace (as defined by {@link Character#isWhitespace(char)}) character.
- */
- private static class NonWhitespace extends StopCondition {
- /*
- * @see org.eclipse.cdt.internal.ui.text.CHeuristicScanner.StopCondition#stop(char)
- */
- @Override
- public boolean stop(char ch, int position, boolean forward) {
- return !Character.isWhitespace(ch);
- }
- }
-
- /**
- * Stops upon a non-whitespace character in the default partition.
- *
- * @see NonWhitespace
- */
- private final class NonWhitespaceDefaultPartition extends NonWhitespace {
- /*
- * @see org.eclipse.cdt.internal.ui.text.CHeuristicScanner.StopCondition#stop(char)
- */
- @Override
- public boolean stop(char ch, int position, boolean forward) {
- return super.stop(ch, position, true) && isDefaultPartition(position);
- }
-
- /*
- * @see org.eclipse.cdt.internal.ui.text.CHeuristicScanner.StopCondition#nextPosition(int, boolean)
- */
- @Override
- public int nextPosition(int position, boolean forward) {
- ITypedRegion partition= getPartition(position);
- if (fPartition.equals(partition.getType()))
- return super.nextPosition(position, forward);
-
- if (forward) {
- int end= partition.getOffset() + partition.getLength();
- if (position < end)
- return end;
- } else {
- int offset= partition.getOffset();
- if (position > offset)
- return offset - 1;
- }
- return super.nextPosition(position, forward);
- }
- }
-
- /**
- * Stops upon a non-java identifier (as defined by {@link Character#isJavaIdentifierPart(char)}) character.
- */
- private static class NonJavaIdentifierPart extends StopCondition {
- /*
- * @see org.eclipse.cdt.internal.ui.text.CHeuristicScanner.StopCondition#stop(char)
- */
- @Override
- public boolean stop(char ch, int position, boolean forward) {
- return !Character.isJavaIdentifierPart(ch);
- }
- }
-
- /**
- * Stops upon a non-java identifier character in the default partition.
- *
- * @see NonJavaIdentifierPart
- */
- private final class NonJavaIdentifierPartDefaultPartition extends NonJavaIdentifierPart {
- /*
- * @see org.eclipse.cdt.internal.ui.text.CHeuristicScanner.StopCondition#stop(char)
- */
- @Override
- public boolean stop(char ch, int position, boolean forward) {
- return super.stop(ch, position, true) || !isDefaultPartition(position);
- }
-
- /*
- * @see org.eclipse.cdt.internal.ui.text.CHeuristicScanner.StopCondition#nextPosition(int, boolean)
- */
- @Override
- public int nextPosition(int position, boolean forward) {
- ITypedRegion partition= getPartition(position);
- if (fPartition.equals(partition.getType()))
- return super.nextPosition(position, forward);
-
- if (forward) {
- int end= partition.getOffset() + partition.getLength();
- if (position < end)
- return end;
- } else {
- int offset= partition.getOffset();
- if (position > offset)
- return offset - 1;
- }
- return super.nextPosition(position, forward);
- }
- }
-
- /**
- * Stops upon a character in the default partition that matches the given character list.
- */
- private final class CharacterMatch extends StopCondition {
- private final char[] fChars;
-
- /**
- * Creates a new instance.
- * @param ch the single character to match
- */
- public CharacterMatch(char ch) {
- this(new char[] {ch});
- }
-
- /**
- * Creates a new instance.
- * @param chars the chars to match.
- */
- public CharacterMatch(char[] chars) {
- Assert.isNotNull(chars);
- Assert.isTrue(chars.length > 0);
- fChars= chars;
- Arrays.sort(chars);
- }
-
- /*
- * @see org.eclipse.cdt.internal.ui.text.CHeuristicScanner.StopCondition#stop(char, int)
- */
- @Override
- public boolean stop(char ch, int position, boolean forward) {
- return Arrays.binarySearch(fChars, ch) >= 0 && isDefaultPartition(position);
- }
-
- /*
- * @see org.eclipse.cdt.internal.ui.text.CHeuristicScanner.StopCondition#nextPosition(int, boolean)
- */
- @Override
- public int nextPosition(int position, boolean forward) {
- ITypedRegion partition= getPartition(position);
- if (fPartition.equals(partition.getType()))
- return super.nextPosition(position, forward);
-
- if (forward) {
- int end= partition.getOffset() + partition.getLength();
- if (position < end)
- return end;
- } else {
- int offset= partition.getOffset();
- if (position > offset)
- return offset - 1;
- }
- return super.nextPosition(position, forward);
- }
- }
-
- /** The document being scanned. */
- private final IDocument fDocument;
- /** The partitioning being used for scanning. */
- private final String fPartitioning;
- /** The partition to scan in. */
- private final String fPartition;
-
- /* internal scan state */
-
- /** the most recently read character. */
- private char fChar;
- /** the most recently read position. */
- private int fPos;
- /**
- * The most recently used partition.
- */
- private ITypedRegion fCachedPartition= new TypedRegion(-1, 0, "__no_partition_at_all"); //$NON-NLS-1$
-
- /* preset stop conditions */
- private final StopCondition fNonWSDefaultPart= new NonWhitespaceDefaultPartition();
- private static final StopCondition fNonWS= new NonWhitespace();
- private final StopCondition fNonIdent= new NonJavaIdentifierPartDefaultPartition();
-
- /**
- * Creates a new instance.
- *
- * @param document the document to scan
- * @param partitioning the partitioning to use for scanning
- * @param partition the partition to scan in
- */
- public STPHeuristicScanner(IDocument document, String partitioning, String partition) {
- Assert.isLegal(document != null);
- Assert.isLegal(partitioning != null);
- Assert.isLegal(partition != null);
- fDocument= document;
- fPartitioning= partitioning;
- fPartition= partition;
- }
-
- /**
- * Calls <code>this(document, STPPartitionScanner.STP_PARTITIONING, IDocument.DEFAULT_CONTENT_TYPE)</code>.
- *
- * @param document the document to scan.
- */
- public STPHeuristicScanner(IDocument document) {
- this(document, STPPartitionScanner.STP_PARTITIONING, IDocument.DEFAULT_CONTENT_TYPE);
- }
-
- /**
- * Returns the most recent internal scan position.
- *
- * @return the most recent internal scan position.
- */
- public int getPosition() {
- return fPos;
- }
-
- /**
- * Returns the next token in forward direction, starting at <code>start</code>, and not extending
- * further than <code>bound</code>. The return value is one of the constants defined in {@link STPSymbols}.
- * After a call, {@link #getPosition()} will return the position just after the scanned token
- * (i.e. the next position that will be scanned).
- *
- * @param start the first character position in the document to consider
- * @param bound the first position not to consider any more
- * @return a constant from {@link STPSymbols} describing the next token
- */
- public int nextToken(int start, int bound) {
- int pos= scanForward(start, bound, fNonWS);
- if (pos == NOT_FOUND)
- return TokenEOF;
- try {
- // check for string or char literal
- char ch = fDocument.getChar(pos);
- if (ch == '"' || ch == '\'') {
- fChar= ch;
- fPos= fNonWSDefaultPart.nextPosition(pos, true);
- return TokenOTHER;
- }
- } catch (BadLocationException exc) {
- }
- pos= scanForward(pos, bound, fNonWSDefaultPart);
- if (pos == NOT_FOUND)
- return TokenEOF;
-
- fPos++;
-
- switch (fChar) {
- case LBRACE:
- return TokenLBRACE;
- case RBRACE:
- return TokenRBRACE;
- case LBRACKET:
- return TokenLBRACKET;
- case RBRACKET:
- return TokenRBRACKET;
- case LPAREN:
- return TokenLPAREN;
- case RPAREN:
- return TokenRPAREN;
- case SEMICOLON:
- return TokenSEMICOLON;
- case COLON:
- switch (peekNextChar()) {
- case COLON:
- ++fPos;
- return TokenDOUBLECOLON;
- }
- return TokenCOLON;
- case COMMA:
- return TokenCOMMA;
- case QUESTIONMARK:
- return TokenQUESTIONMARK;
- case EQUAL:
- return TokenEQUAL;
- case LANGLE:
- switch (peekNextChar()) {
- case LANGLE:
- ++fPos;
- if (peekNextChar() == LANGLE) {
- ++fPos;
- return TokenAGGREGATE;
- }
- return TokenSHIFTLEFT;
- case EQUAL:
- ++fPos;
- return TokenOTHER;
- }
- return TokenLESSTHAN;
- case RANGLE:
- switch (peekNextChar()) {
- case RANGLE:
- ++fPos;
- return TokenSHIFTRIGHT;
- case EQUAL:
- ++fPos;
- return TokenOTHER;
- }
- return TokenGREATERTHAN;
- case DOT:
- return TokenDOT;
- case MINUS:
- switch (peekNextChar()) {
- case RANGLE:
- ++fPos;
- return TokenARROW;
- }
- return TokenMINUS;
- case PLUS:
- return TokenPLUS;
- case TILDE:
- return TokenTILDE;
- }
-
- // else
- if (Character.isJavaIdentifierPart(fChar)) {
- // assume an identifier or keyword
- int from= pos, to;
- pos= scanForward(pos + 1, bound, fNonIdent);
- if (pos == NOT_FOUND)
- to= bound == UNBOUND ? fDocument.getLength() : bound;
- else
- to= pos;
-
- String identOrKeyword;
- try {
- identOrKeyword= fDocument.get(from, to - from);
- } catch (BadLocationException e) {
- return TokenEOF;
- }
-
- return getToken(identOrKeyword);
-
-
- }
- // operators, number literals etc
- return TokenOTHER;
- }
-
- /**
- * Returns the next token in backward direction, starting at <code>start</code>, and not extending
- * further than <code>bound</code>. The return value is one of the constants defined in {@link STPSymbols}.
- * After a call, {@link #getPosition()} will return the position just before the scanned token
- * starts (i.e. the next position that will be scanned).
- *
- * @param start the first character position in the document to consider
- * @param bound the first position not to consider any more
- * @return a constant from {@link STPSymbols} describing the previous token
- */
- public int previousToken(int start, int bound) {
- int pos= scanBackward(start, bound, fNonWSDefaultPart);
- if (pos == NOT_FOUND)
- return TokenEOF;
-
- fPos--;
-
- switch (fChar) {
- case LBRACE:
- return TokenLBRACE;
- case RBRACE:
- return TokenRBRACE;
- case LBRACKET:
- return TokenLBRACKET;
- case RBRACKET:
- return TokenRBRACKET;
- case LPAREN:
- return TokenLPAREN;
- case RPAREN:
- return TokenRPAREN;
- case SEMICOLON:
- return TokenSEMICOLON;
- case COLON:
- switch (peekPreviousChar()) {
- case COLON:
- --fPos;
- return TokenDOUBLECOLON;
- }
- return TokenCOLON;
- case COMMA:
- return TokenCOMMA;
- case QUESTIONMARK:
- return TokenQUESTIONMARK;
- case EQUAL:
- switch (peekPreviousChar()) {
- case RANGLE:
- case LANGLE:
- --fPos;
- return TokenOTHER;
- }
- return TokenEQUAL;
- case LANGLE:
- switch (peekPreviousChar()) {
- case LANGLE:
- --fPos;
- return TokenSHIFTLEFT;
- }
- return TokenLESSTHAN;
- case RANGLE:
- switch (peekPreviousChar()) {
- case RANGLE:
- --fPos;
- return TokenSHIFTRIGHT;
- case MINUS:
- --fPos;
- return TokenARROW;
- }
- return TokenGREATERTHAN;
- case DOT:
- return TokenDOT;
- case MINUS:
- return TokenMINUS;
- case PLUS:
- return TokenPLUS;
- case TILDE:
- return TokenTILDE;
- }
-
- // else
- if (Character.isJavaIdentifierPart(fChar)) {
- // assume an ident or keyword
- int from, to= pos + 1;
- pos= scanBackward(pos - 1, bound, fNonIdent);
- if (pos == NOT_FOUND)
- from= bound == UNBOUND ? 0 : bound + 1;
- else
- from= pos + 1;
-
- String identOrKeyword;
- try {
- identOrKeyword= fDocument.get(from, to - from);
- } catch (BadLocationException e) {
- return TokenEOF;
- }
-
- return getToken(identOrKeyword);
- }
- // operators, number literals etc
- return TokenOTHER;
- }
-
- /**
- * @return the next char without shifting the position
- */
- private char peekNextChar() {
- if (fPos + 1 < fDocument.getLength()) {
- try {
- return fDocument.getChar(fPos + 1);
- } catch (BadLocationException exc) {
- }
- }
- return (char)-1;
- }
-
- /**
- * @return the previous char without shifting the position
- */
- private char peekPreviousChar() {
- if (fPos >= 0) {
- try {
- return fDocument.getChar(fPos);
- } catch (BadLocationException e) {
- }
- }
- return (char)-1;
- }
-
- /**
- * Returns one of the keyword constants or <code>TokenIDENT</code> for a scanned identifier.
- *
- * @param s a scanned identifier
- * @return one of the constants defined in {@link STPSymbols}
- */
- private int getToken(String s) {
- Assert.isNotNull(s);
-
- switch (s.length()) {
- case 2:
- if ("if".equals(s)) //$NON-NLS-1$
- return TokenIF;
- if ("do".equals(s)) //$NON-NLS-1$
- return TokenDO;
- break;
- case 3:
- if ("for".equals(s)) //$NON-NLS-1$
- return TokenFOR;
- if ("try".equals(s)) //$NON-NLS-1$
- return TokenTRY;
- if ("new".equals(s)) //$NON-NLS-1$
- return TokenNEW;
- break;
- case 4:
- if ("case".equals(s)) //$NON-NLS-1$
- return TokenCASE;
- if ("else".equals(s)) //$NON-NLS-1$
- return TokenELSE;
- if ("enum".equals(s)) //$NON-NLS-1$
- return TokenENUM;
- if ("goto".equals(s)) //$NON-NLS-1$
- return TokenGOTO;
- break;
- case 5:
- if ("break".equals(s)) //$NON-NLS-1$
- return TokenBREAK;
- if ("catch".equals(s)) //$NON-NLS-1$
- return TokenCATCH;
- if ("class".equals(s)) //$NON-NLS-1$
- return TokenCLASS;
- if ("const".equals(s)) //$NON-NLS-1$
- return TokenCONST;
- if ("while".equals(s)) //$NON-NLS-1$
- return TokenWHILE;
- if ("union".equals(s)) //$NON-NLS-1$
- return TokenUNION;
- if ("using".equals(s)) //$NON-NLS-1$
- return TokenUSING;
- if ("throw".equals(s)) //$NON-NLS-1$
- return TokenTHROW;
- break;
- case 6:
- if ("delete".equals(s)) //$NON-NLS-1$
- return TokenDELETE;
- if ("public".equals(s)) //$NON-NLS-1$
- return TokenPUBLIC;
- if ("return".equals(s)) //$NON-NLS-1$
- return TokenRETURN;
- if ("static".equals(s)) //$NON-NLS-1$
- return TokenSTATIC;
- if ("struct".equals(s)) //$NON-NLS-1$
- return TokenSTRUCT;
- if ("switch".equals(s)) //$NON-NLS-1$
- return TokenSWITCH;
- if ("extern".equals(s)) //$NON-NLS-1$
- return TokenEXTERN;
- break;
- case 7:
- if ("default".equals(s)) //$NON-NLS-1$
- return TokenDEFAULT;
- if ("foreach".equals(s)) //$NON-NLS-1$
- return TokenFOREACH;
- if ("private".equals(s)) //$NON-NLS-1$
- return TokenPRIVATE;
- if ("typedef".equals(s)) //$NON-NLS-1$
- return TokenTYPEDEF;
- if ("virtual".equals(s)) //$NON-NLS-1$
- return TokenVIRTUAL;
- break;
- case 8:
- if ("operator".equals(s)) //$NON-NLS-1$
- return TokenOPERATOR;
- if ("template".equals(s)) //$NON-NLS-1$
- return TokenTEMPLATE;
- if ("typename".equals(s)) //$NON-NLS-1$
- return TokenTYPENAME;
- break;
- case 9:
- if ("namespace".equals(s)) //$NON-NLS-1$
- return TokenNAMESPACE;
- if ("protected".equals(s)) //$NON-NLS-1$
- return TokenPROTECTED;
- }
- return TokenIDENT;
- }
-
- /**
- * Returns the position of the closing peer character (forward search). Any scopes introduced
- * by opening peers are skipped. All peers accounted for must reside in the default partition.
- *
- * <p>Note that <code>start</code> must not point to the opening peer, but to the first
- * character being searched.</p>
- *
- * @param start the start position
- * @param openingPeer the opening peer character (e.g. '{')
- * @param closingPeer the closing peer character (e.g. '}')
- * @return the matching peer character position, or <code>NOT_FOUND</code>
- */
- public int findClosingPeer(int start, final char openingPeer, final char closingPeer) {
- return findClosingPeer(start, UNBOUND, openingPeer, closingPeer);
- }
-
- /**
- * Returns the position of the closing peer character (forward search). Any scopes introduced by opening peers
- * are skipped. All peers accounted for must reside in the default partition.
- *
- * <p>Note that <code>start</code> must not point to the opening peer, but to the first
- * character being searched.</p>
- *
- * @param start the start position
- * @param bound the bound
- * @param openingPeer the opening peer character (e.g. '{')
- * @param closingPeer the closing peer character (e.g. '}')
- * @return the matching peer character position, or <code>NOT_FOUND</code>
- */
- private int findClosingPeer(int start, int bound, final char openingPeer, final char closingPeer) {
- Assert.isLegal(start >= 0);
-
- try {
- int depth= 1;
- start -= 1;
- while (true) {
- start= scanForward(start + 1, bound, new CharacterMatch(new char[] {openingPeer, closingPeer}));
- if (start == NOT_FOUND)
- return NOT_FOUND;
-
- if (fDocument.getChar(start) == openingPeer)
- depth++;
- else
- depth--;
-
- if (depth == 0)
- return start;
- }
-
- } catch (BadLocationException e) {
- return NOT_FOUND;
- }
- }
-
- /**
- * Returns the position of the opening peer character (backward search). Any scopes introduced by closing peers
- * are skipped. All peers accounted for must reside in the default partition.
- *
- * <p>Note that <code>start</code> must not point to the closing peer, but to the first
- * character being searched.</p>
- *
- * @param start the start position
- * @param openingPeer the opening peer character (e.g. '{')
- * @param closingPeer the closing peer character (e.g. '}')
- * @return the matching peer character position, or <code>NOT_FOUND</code>
- */
- public int findOpeningPeer(int start, char openingPeer, char closingPeer) {
- return findOpeningPeer(start, STPHeuristicScanner.UNBOUND, openingPeer, closingPeer);
- }
-
- /**
- * Returns the position of the opening peer character (backward search). Any scopes introduced by closing peers
- * are skipped. All peers accounted for must reside in the default partition.
- *
- * <p>Note that <code>start</code> must not point to the closing peer, but to the first
- * character being searched.</p>
- *
- * @param start the start position
- * @param bound the bound
- * @param openingPeer the opening peer character (e.g. '{')
- * @param closingPeer the closing peer character (e.g. '}')
- * @return the matching peer character position, or <code>NOT_FOUND</code>
- */
- public int findOpeningPeer(int start, int bound, char openingPeer, char closingPeer) {
- Assert.isLegal(start < fDocument.getLength());
-
- try {
- final CharacterMatch match= new CharacterMatch(new char[] {openingPeer, closingPeer});
- int depth= 1;
- start += 1;
- while (true) {
- start= scanBackward(start - 1, bound, match);
- if (start == NOT_FOUND)
- return NOT_FOUND;
-
- if (fDocument.getChar(start) == closingPeer)
- depth++;
- else
- depth--;
-
- if (depth == 0)
- return start;
- }
-
- } catch (BadLocationException e) {
- return NOT_FOUND;
- }
- }
-
- /**
- * Finds the smallest position in <code>fDocument</code> such that the position is &gt;= <code>position</code>
- * and &lt; <code>bound</code> and <code>Character.isWhitespace(fDocument.getChar(pos))</code> evaluates to <code>false</code>.
- *
- * @param position the first character position in <code>fDocument</code> to be considered
- * @param bound the first position in <code>fDocument</code> to not consider any more, with <code>bound</code> &gt; <code>position</code>, or <code>UNBOUND</code>
- * @return the smallest position of a non-whitespace character in [<code>position</code>, <code>bound</code>), or <code>NOT_FOUND</code> if none can be found
- */
- public int findNonWhitespaceForwardInAnyPartition(int position, int bound) {
- return scanForward(position, bound, fNonWS);
- }
-
- /**
- * Finds the highest position in <code>fDocument</code> such that the position is &lt;= <code>position</code>
- * and &gt; <code>bound</code> and <code>Character.isWhitespace(fDocument.getChar(pos))</code> evaluates to <code>false</code>
- * and the position is in the default partition.
- *
- * @param position the first character position in <code>fDocument</code> to be considered
- * @param bound the first position in <code>fDocument</code> to not consider any more, with <code>bound</code> &lt; <code>position</code>, or <code>UNBOUND</code>
- * @return the highest position of a non-whitespace character in (<code>bound</code>, <code>position</code>] that resides in a C partition, or <code>NOT_FOUND</code> if none can be found
- */
- public int findNonWhitespaceBackward(int position, int bound) {
- return scanBackward(position, bound, fNonWSDefaultPart);
- }
-
- /**
- * Finds the lowest position <code>p</code> in <code>fDocument</code> such that <code>start</code> &lt;= p &lt;
- * <code>bound</code> and <code>condition.stop(fDocument.getChar(p), p)</code> evaluates to <code>true</code>.
- *
- * @param start the first character position in <code>fDocument</code> to be considered
- * @param bound the first position in <code>fDocument</code> to not consider any more, with <code>bound</code> &gt; <code>start</code>, or <code>UNBOUND</code>
- * @param condition the <code>StopCondition</code> to check
- * @return the lowest position in [<code>start</code>, <code>bound</code>) for which <code>condition</code> holds, or <code>NOT_FOUND</code> if none can be found
- */
- private int scanForward(int start, int bound, StopCondition condition) {
- Assert.isLegal(start >= 0);
-
- if (bound == UNBOUND)
- bound= fDocument.getLength();
-
- Assert.isLegal(bound <= fDocument.getLength());
-
- try {
- fPos= start;
- while (fPos < bound) {
-
- fChar= fDocument.getChar(fPos);
- if (condition.stop(fChar, fPos, true))
- return fPos;
-
- fPos= condition.nextPosition(fPos, true);
- }
- } catch (BadLocationException e) {
- }
- return NOT_FOUND;
- }
-
-
- /**
- * Finds the lowest position in <code>fDocument</code> such that the position is &gt;= <code>position</code>
- * and &lt; <code>bound</code> and <code>fDocument.getChar(position) == ch</code> evaluates to <code>true</code>
- * and the position is in the default partition.
- *
- * @param position the first character position in <code>fDocument</code> to be considered
- * @param bound the first position in <code>fDocument</code> to not consider any more, with <code>bound</code> &gt; <code>position</code>, or <code>UNBOUND</code>
- * @param ch the <code>char</code> to search for
- * @return the lowest position of <code>ch</code> in (<code>bound</code>, <code>position</code>] that resides in a C partition, or <code>NOT_FOUND</code> if none can be found
- */
- public int scanForward(int position, int bound, char ch) {
- return scanForward(position, bound, new CharacterMatch(ch));
- }
-
- /**
- * Finds the highest position <code>p</code> in <code>fDocument</code> such that <code>bound</code> &lt; <code>p</code> &lt;= <code>start</code>
- * and <code>condition.stop(fDocument.getChar(p), p)</code> evaluates to <code>true</code>.
- *
- * @param start the first character position in <code>fDocument</code> to be considered
- * @param bound the first position in <code>fDocument</code> to not consider any more, with <code>bound</code> &lt; <code>start</code>, or <code>UNBOUND</code>
- * @param condition the <code>StopCondition</code> to check
- * @return the highest position in (<code>bound</code>, <code>start</code> for which <code>condition</code> holds, or <code>NOT_FOUND</code> if none can be found
- */
- private int scanBackward(int start, int bound, StopCondition condition) {
- if (bound == UNBOUND)
- bound= -1;
-
- Assert.isLegal(bound >= -1);
- Assert.isLegal(start < fDocument.getLength() );
-
- try {
- fPos= start;
- while (fPos > bound) {
-
- fChar= fDocument.getChar(fPos);
- if (condition.stop(fChar, fPos, false))
- return fPos;
-
- fPos= condition.nextPosition(fPos, false);
- }
- } catch (BadLocationException e) {
- }
- return NOT_FOUND;
- }
-
- /**
- * Checks whether <code>position</code> resides in a default (C) partition of <code>fDocument</code>.
- *
- * @param position the position to be checked
- * @return <code>true</code> if <code>position</code> is in the default partition of <code>fDocument</code>, <code>false</code> otherwise
- */
- private boolean isDefaultPartition(int position) {
- String type = getPartition(position).getType();
- return fPartition.equals(type);
- }
-
- /**
- * Returns the partition at <code>position</code>.
- *
- * @param position the position to get the partition for
- * @return the partition at <code>position</code> or a dummy zero-length
- * partition if accessing the document fails
- */
- private ITypedRegion getPartition(int position) {
- if (!contains(fCachedPartition, position)) {
- Assert.isTrue(position >= 0);
- Assert.isTrue(position <= fDocument.getLength());
-
- try {
- fCachedPartition= TextUtilities.getPartition(fDocument, fPartitioning, position, false);
- } catch (BadLocationException e) {
- fCachedPartition= new TypedRegion(position, 0, "__no_partition_at_all"); //$NON-NLS-1$
- }
- }
-
- return fCachedPartition;
- }
-
- /**
- * Returns <code>true</code> if <code>region</code> contains <code>position</code>.
- *
- * @param region a region
- * @param position an offset
- * @return <code>true</code> if <code>region</code> contains <code>position</code>
- */
- private boolean contains(IRegion region, int position) {
- int offset= region.getOffset();
- return offset <= position && position < offset + region.getLength();
- }
-
- /**
- * Checks if the line seems to be an open condition not followed by a block (i.e. an if, while,
- * or for statement with just one following statement, see example below).
- *
- * <pre>
- * if (condition)
- * doStuff();
- * </pre>
- *
- * <p>Algorithm: if the last non-WS, non-Comment code on the line is an if (condition), while (condition),
- * for( expression), do, else, and there is no statement after that </p>
- *
- * @param position the insert position of the new character
- * @param bound the lowest position to consider
- * @return <code>true</code> if the code is a conditional statement or loop without a block, <code>false</code> otherwise
- */
- public boolean isBracelessBlockStart(int position, int bound) {
- if (position < 1)
- return false;
-
- switch (previousToken(position, bound)) {
- case TokenDO:
- case TokenELSE:
- return true;
- case TokenRPAREN:
- position= findOpeningPeer(fPos, STPHeuristicScanner.UNBOUND, LPAREN, RPAREN);
- if (position > 0) {
- switch (previousToken(position - 1, bound)) {
- case TokenIF:
- case TokenFOR:
- case TokenFOREACH:
- case TokenWHILE:
- return true;
- }
- }
- }
-
- return false;
- }
-
- /**
- * Returns <code>true</code> if the document, when scanned backwards from <code>start</code>
- * appears to be a composite type (class, struct, union) or enum definition. Examples:
- *
- * <pre>
- * class A {
- * struct A {
- * class A : B {
- * class A : virtual public B, protected C&lt;T&gt; {
- * enum E {
- * </pre>
- *
- * @param start the position of the opening brace.
- * @param bound the first position in <code>fDocument</code> to not consider any more, with
- * <code>bound</code> &lt; <code>start</code>, or <code>UNBOUND</code>
- * @return <code>true</code> if the current position looks like a composite type definition
- */
- public boolean looksLikeCompositeTypeDefinitionBackward(int start, int bound) {
- int token= previousToken(start - 1, bound);
- switch (token) {
- case STPSymbols.TokenSTRUCT:
- case STPSymbols.TokenUNION:
- case STPSymbols.TokenENUM:
- return true; // anonymous
- case STPSymbols.TokenIDENT:
- token= previousToken(getPosition(), bound);
- switch (token) {
- case STPSymbols.TokenCLASS:
- case STPSymbols.TokenSTRUCT:
- case STPSymbols.TokenUNION:
- case STPSymbols.TokenENUM:
- return true; // no base-clause
- default:
- // backtrack
- token= previousToken(start - 1, bound);
- }
- break;
- default:
- // backtrack
- token= previousToken(start - 1, bound);
- break;
- }
- // match base-clause
- if (token == STPSymbols.TokenGREATERTHAN) {
- findOpeningPeer(getPosition(), bound, '<', '>');
- token= previousToken(getPosition(), bound);
- if (token != STPSymbols.TokenLESSTHAN) {
- return false;
- }
- token= previousToken(getPosition(), bound);
- }
- outerWhile: while (token == STPSymbols.TokenIDENT) {// type name or base type
- token= previousToken(getPosition(), bound);
- // match nested-name-specifier
- while (token == STPSymbols.TokenCOLON) { // colon of qualification
- token= previousToken(getPosition(), bound);
- if (token != STPSymbols.TokenCOLON) { // second colon of qualification
- break outerWhile;
- }
- token= previousToken(getPosition(), bound);
- if (token != STPSymbols.TokenIDENT) // qualification name?
- break;
- token= previousToken(getPosition(), bound);
- }
- switch (token) {
- case STPSymbols.TokenVIRTUAL:
- token= previousToken(getPosition(), bound);
- //$FALL-THROUGH$
- case STPSymbols.TokenPUBLIC:
- case STPSymbols.TokenPROTECTED:
- case STPSymbols.TokenPRIVATE:
- token= previousToken(getPosition(), bound);
- if (token == STPSymbols.TokenVIRTUAL) {
- token= previousToken(getPosition(), bound);
- }
- if (token == STPSymbols.TokenCOMMA) {
- token= previousToken(getPosition(), bound);
- if (token == STPSymbols.TokenGREATERTHAN) {
- findOpeningPeer(getPosition(), bound, '<', '>');
- token= previousToken(getPosition(), bound);
- if (token != STPSymbols.TokenLESSTHAN) {
- return false;
- }
- token= previousToken(getPosition(), bound);
- }
- continue; // another base type
- }
- if (token != STPSymbols.TokenCOLON) // colon after class def identifier
- return false;
- //$FALL-THROUGH$
- case STPSymbols.TokenCOLON:
- token= previousToken(getPosition(), bound);
- break outerWhile;
- case STPSymbols.TokenCOMMA:
- token= previousToken(getPosition(), bound);
- if (token == STPSymbols.TokenGREATERTHAN) {
- findOpeningPeer(getPosition(), bound, '<', '>');
- token= previousToken(getPosition(), bound);
- if (token != STPSymbols.TokenLESSTHAN) {
- return false;
- }
- token= previousToken(getPosition(), bound);
- }
- continue; // another base type
- case STPSymbols.TokenIDENT:
- break outerWhile;
- default:
- return false;
- }
- }
- if (token != STPSymbols.TokenIDENT) {
- return false;
- }
- token= previousToken(getPosition(), bound);
- switch (token) {
- case STPSymbols.TokenCLASS:
- case STPSymbols.TokenSTRUCT:
- case STPSymbols.TokenUNION:
- case STPSymbols.TokenENUM: // enum is actually not valid here
- return true;
- default:
- return false;
- }
- }
+ /**
+ * Returned by all methods when the requested position could not be found, or if a
+ * {@link BadLocationException} was thrown while scanning.
+ */
+ public static final int NOT_FOUND= -1;
+
+ /**
+ * Special bound parameter that means either -1 (backward scanning) or
+ * <code>fDocument.getLength()</code> (forward scanning).
+ */
+ public static final int UNBOUND= -2;
+
+
+ /* character constants */
+ private static final char LBRACE= '{';
+ private static final char RBRACE= '}';
+ private static final char LPAREN= '(';
+ private static final char RPAREN= ')';
+ private static final char SEMICOLON= ';';
+ private static final char COLON= ':';
+ private static final char COMMA= ',';
+ private static final char LBRACKET= '[';
+ private static final char RBRACKET= ']';
+ private static final char QUESTIONMARK= '?';
+ private static final char EQUAL= '=';
+ private static final char LANGLE= '<';
+ private static final char RANGLE= '>';
+ private static final char DOT= '.';
+ private static final char MINUS= '-';
+ private static final char PLUS= '+';
+ private static final char TILDE= '~';
+
+ /**
+ * Specifies the stop condition, upon which the <code>scanXXX</code> methods will decide whether
+ * to keep scanning or not. This interface may implemented by clients.
+ */
+ private static abstract class StopCondition {
+ /**
+ * Instructs the scanner to return the current position.
+ *
+ * @param ch the char at the current position
+ * @param position the current position
+ * @param forward the iteration direction
+ * @return <code>true</code> if the stop condition is met.
+ */
+ public abstract boolean stop(char ch, int position, boolean forward);
+
+ /**
+ * Asks the condition to return the next position to query. The default
+ * is to return the next/previous position.
+ *
+ * @return the next position to scan
+ */
+ public int nextPosition(int position, boolean forward) {
+ return forward ? position + 1 : position - 1;
+ }
+ }
+
+ /**
+ * Stops upon a non-whitespace (as defined by {@link Character#isWhitespace(char)}) character.
+ */
+ private static class NonWhitespace extends StopCondition {
+ /*
+ * @see org.eclipse.cdt.internal.ui.text.CHeuristicScanner.StopCondition#stop(char)
+ */
+ @Override
+ public boolean stop(char ch, int position, boolean forward) {
+ return !Character.isWhitespace(ch);
+ }
+ }
+
+ /**
+ * Stops upon a non-whitespace character in the default partition.
+ *
+ * @see NonWhitespace
+ */
+ private final class NonWhitespaceDefaultPartition extends NonWhitespace {
+ /*
+ * @see org.eclipse.cdt.internal.ui.text.CHeuristicScanner.StopCondition#stop(char)
+ */
+ @Override
+ public boolean stop(char ch, int position, boolean forward) {
+ return super.stop(ch, position, true) && isDefaultPartition(position);
+ }
+
+ /*
+ * @see org.eclipse.cdt.internal.ui.text.CHeuristicScanner.StopCondition#nextPosition(int, boolean)
+ */
+ @Override
+ public int nextPosition(int position, boolean forward) {
+ ITypedRegion partition= getPartition(position);
+ if (fPartition.equals(partition.getType()))
+ return super.nextPosition(position, forward);
+
+ if (forward) {
+ int end= partition.getOffset() + partition.getLength();
+ if (position < end)
+ return end;
+ } else {
+ int offset= partition.getOffset();
+ if (position > offset)
+ return offset - 1;
+ }
+ return super.nextPosition(position, forward);
+ }
+ }
+
+ /**
+ * Stops upon a non-java identifier (as defined by {@link Character#isJavaIdentifierPart(char)}) character.
+ */
+ private static class NonJavaIdentifierPart extends StopCondition {
+ /*
+ * @see org.eclipse.cdt.internal.ui.text.CHeuristicScanner.StopCondition#stop(char)
+ */
+ @Override
+ public boolean stop(char ch, int position, boolean forward) {
+ return !Character.isJavaIdentifierPart(ch);
+ }
+ }
+
+ /**
+ * Stops upon a non-java identifier character in the default partition.
+ *
+ * @see NonJavaIdentifierPart
+ */
+ private final class NonJavaIdentifierPartDefaultPartition extends NonJavaIdentifierPart {
+ /*
+ * @see org.eclipse.cdt.internal.ui.text.CHeuristicScanner.StopCondition#stop(char)
+ */
+ @Override
+ public boolean stop(char ch, int position, boolean forward) {
+ return super.stop(ch, position, true) || !isDefaultPartition(position);
+ }
+
+ /*
+ * @see org.eclipse.cdt.internal.ui.text.CHeuristicScanner.StopCondition#nextPosition(int, boolean)
+ */
+ @Override
+ public int nextPosition(int position, boolean forward) {
+ ITypedRegion partition= getPartition(position);
+ if (fPartition.equals(partition.getType()))
+ return super.nextPosition(position, forward);
+
+ if (forward) {
+ int end= partition.getOffset() + partition.getLength();
+ if (position < end)
+ return end;
+ } else {
+ int offset= partition.getOffset();
+ if (position > offset)
+ return offset - 1;
+ }
+ return super.nextPosition(position, forward);
+ }
+ }
+
+ /**
+ * Stops upon a character in the default partition that matches the given character list.
+ */
+ private final class CharacterMatch extends StopCondition {
+ private final char[] fChars;
+
+ /**
+ * Creates a new instance.
+ * @param ch the single character to match
+ */
+ public CharacterMatch(char ch) {
+ this(new char[] {ch});
+ }
+
+ /**
+ * Creates a new instance.
+ * @param chars the chars to match.
+ */
+ public CharacterMatch(char[] chars) {
+ Assert.isNotNull(chars);
+ Assert.isTrue(chars.length > 0);
+ fChars= chars;
+ Arrays.sort(chars);
+ }
+
+ /*
+ * @see org.eclipse.cdt.internal.ui.text.CHeuristicScanner.StopCondition#stop(char, int)
+ */
+ @Override
+ public boolean stop(char ch, int position, boolean forward) {
+ return Arrays.binarySearch(fChars, ch) >= 0 && isDefaultPartition(position);
+ }
+
+ /*
+ * @see org.eclipse.cdt.internal.ui.text.CHeuristicScanner.StopCondition#nextPosition(int, boolean)
+ */
+ @Override
+ public int nextPosition(int position, boolean forward) {
+ ITypedRegion partition= getPartition(position);
+ if (fPartition.equals(partition.getType()))
+ return super.nextPosition(position, forward);
+
+ if (forward) {
+ int end= partition.getOffset() + partition.getLength();
+ if (position < end)
+ return end;
+ } else {
+ int offset= partition.getOffset();
+ if (position > offset)
+ return offset - 1;
+ }
+ return super.nextPosition(position, forward);
+ }
+ }
+
+ /** The document being scanned. */
+ private final IDocument fDocument;
+ /** The partitioning being used for scanning. */
+ private final String fPartitioning;
+ /** The partition to scan in. */
+ private final String fPartition;
+
+ /* internal scan state */
+
+ /** the most recently read character. */
+ private char fChar;
+ /** the most recently read position. */
+ private int fPos;
+ /**
+ * The most recently used partition.
+ */
+ private ITypedRegion fCachedPartition= new TypedRegion(-1, 0, "__no_partition_at_all"); //$NON-NLS-1$
+
+ /* preset stop conditions */
+ private final StopCondition fNonWSDefaultPart= new NonWhitespaceDefaultPartition();
+ private static final StopCondition fNonWS= new NonWhitespace();
+ private final StopCondition fNonIdent= new NonJavaIdentifierPartDefaultPartition();
+
+ /**
+ * Creates a new instance.
+ *
+ * @param document the document to scan
+ * @param partitioning the partitioning to use for scanning
+ * @param partition the partition to scan in
+ */
+ public STPHeuristicScanner(IDocument document, String partitioning, String partition) {
+ Assert.isLegal(document != null);
+ Assert.isLegal(partitioning != null);
+ Assert.isLegal(partition != null);
+ fDocument= document;
+ fPartitioning= partitioning;
+ fPartition= partition;
+ }
+
+ /**
+ * Calls <code>this(document, STPPartitionScanner.STP_PARTITIONING, IDocument.DEFAULT_CONTENT_TYPE)</code>.
+ *
+ * @param document the document to scan.
+ */
+ public STPHeuristicScanner(IDocument document) {
+ this(document, STPPartitionScanner.STP_PARTITIONING, IDocument.DEFAULT_CONTENT_TYPE);
+ }
+
+ /**
+ * Returns the most recent internal scan position.
+ *
+ * @return the most recent internal scan position.
+ */
+ public int getPosition() {
+ return fPos;
+ }
+
+ /**
+ * Returns the next token in forward direction, starting at <code>start</code>, and not extending
+ * further than <code>bound</code>. The return value is one of the constants defined in {@link STPSymbols}.
+ * After a call, {@link #getPosition()} will return the position just after the scanned token
+ * (i.e. the next position that will be scanned).
+ *
+ * @param start the first character position in the document to consider
+ * @param bound the first position not to consider any more
+ * @return a constant from {@link STPSymbols} describing the next token
+ */
+ public int nextToken(int start, int bound) {
+ int pos= scanForward(start, bound, fNonWS);
+ if (pos == NOT_FOUND)
+ return TokenEOF;
+ try {
+ // check for string or char literal
+ char ch = fDocument.getChar(pos);
+ if (ch == '"' || ch == '\'') {
+ fChar= ch;
+ fPos= fNonWSDefaultPart.nextPosition(pos, true);
+ return TokenOTHER;
+ }
+ } catch (BadLocationException exc) {
+ }
+ pos= scanForward(pos, bound, fNonWSDefaultPart);
+ if (pos == NOT_FOUND)
+ return TokenEOF;
+
+ fPos++;
+
+ switch (fChar) {
+ case LBRACE:
+ return TokenLBRACE;
+ case RBRACE:
+ return TokenRBRACE;
+ case LBRACKET:
+ return TokenLBRACKET;
+ case RBRACKET:
+ return TokenRBRACKET;
+ case LPAREN:
+ return TokenLPAREN;
+ case RPAREN:
+ return TokenRPAREN;
+ case SEMICOLON:
+ return TokenSEMICOLON;
+ case COLON:
+ switch (peekNextChar()) {
+ case COLON:
+ ++fPos;
+ return TokenDOUBLECOLON;
+ }
+ return TokenCOLON;
+ case COMMA:
+ return TokenCOMMA;
+ case QUESTIONMARK:
+ return TokenQUESTIONMARK;
+ case EQUAL:
+ return TokenEQUAL;
+ case LANGLE:
+ switch (peekNextChar()) {
+ case LANGLE:
+ ++fPos;
+ if (peekNextChar() == LANGLE) {
+ ++fPos;
+ return TokenAGGREGATE;
+ }
+ return TokenSHIFTLEFT;
+ case EQUAL:
+ ++fPos;
+ return TokenOTHER;
+ }
+ return TokenLESSTHAN;
+ case RANGLE:
+ switch (peekNextChar()) {
+ case RANGLE:
+ ++fPos;
+ return TokenSHIFTRIGHT;
+ case EQUAL:
+ ++fPos;
+ return TokenOTHER;
+ }
+ return TokenGREATERTHAN;
+ case DOT:
+ return TokenDOT;
+ case MINUS:
+ switch (peekNextChar()) {
+ case RANGLE:
+ ++fPos;
+ return TokenARROW;
+ }
+ return TokenMINUS;
+ case PLUS:
+ return TokenPLUS;
+ case TILDE:
+ return TokenTILDE;
+ }
+
+ // else
+ if (Character.isJavaIdentifierPart(fChar)) {
+ // assume an identifier or keyword
+ int from= pos, to;
+ pos= scanForward(pos + 1, bound, fNonIdent);
+ if (pos == NOT_FOUND)
+ to= bound == UNBOUND ? fDocument.getLength() : bound;
+ else
+ to= pos;
+
+ String identOrKeyword;
+ try {
+ identOrKeyword= fDocument.get(from, to - from);
+ } catch (BadLocationException e) {
+ return TokenEOF;
+ }
+
+ return getToken(identOrKeyword);
+
+
+ }
+ // operators, number literals etc
+ return TokenOTHER;
+ }
+
+ /**
+ * Returns the next token in backward direction, starting at <code>start</code>, and not extending
+ * further than <code>bound</code>. The return value is one of the constants defined in {@link STPSymbols}.
+ * After a call, {@link #getPosition()} will return the position just before the scanned token
+ * starts (i.e. the next position that will be scanned).
+ *
+ * @param start the first character position in the document to consider
+ * @param bound the first position not to consider any more
+ * @return a constant from {@link STPSymbols} describing the previous token
+ */
+ public int previousToken(int start, int bound) {
+ int pos= scanBackward(start, bound, fNonWSDefaultPart);
+ if (pos == NOT_FOUND)
+ return TokenEOF;
+
+ fPos--;
+
+ switch (fChar) {
+ case LBRACE:
+ return TokenLBRACE;
+ case RBRACE:
+ return TokenRBRACE;
+ case LBRACKET:
+ return TokenLBRACKET;
+ case RBRACKET:
+ return TokenRBRACKET;
+ case LPAREN:
+ return TokenLPAREN;
+ case RPAREN:
+ return TokenRPAREN;
+ case SEMICOLON:
+ return TokenSEMICOLON;
+ case COLON:
+ switch (peekPreviousChar()) {
+ case COLON:
+ --fPos;
+ return TokenDOUBLECOLON;
+ }
+ return TokenCOLON;
+ case COMMA:
+ return TokenCOMMA;
+ case QUESTIONMARK:
+ return TokenQUESTIONMARK;
+ case EQUAL:
+ switch (peekPreviousChar()) {
+ case RANGLE:
+ case LANGLE:
+ --fPos;
+ return TokenOTHER;
+ }
+ return TokenEQUAL;
+ case LANGLE:
+ switch (peekPreviousChar()) {
+ case LANGLE:
+ --fPos;
+ return TokenSHIFTLEFT;
+ }
+ return TokenLESSTHAN;
+ case RANGLE:
+ switch (peekPreviousChar()) {
+ case RANGLE:
+ --fPos;
+ return TokenSHIFTRIGHT;
+ case MINUS:
+ --fPos;
+ return TokenARROW;
+ }
+ return TokenGREATERTHAN;
+ case DOT:
+ return TokenDOT;
+ case MINUS:
+ return TokenMINUS;
+ case PLUS:
+ return TokenPLUS;
+ case TILDE:
+ return TokenTILDE;
+ }
+
+ // else
+ if (Character.isJavaIdentifierPart(fChar)) {
+ // assume an ident or keyword
+ int from, to= pos + 1;
+ pos= scanBackward(pos - 1, bound, fNonIdent);
+ if (pos == NOT_FOUND)
+ from= bound == UNBOUND ? 0 : bound + 1;
+ else
+ from= pos + 1;
+
+ String identOrKeyword;
+ try {
+ identOrKeyword= fDocument.get(from, to - from);
+ } catch (BadLocationException e) {
+ return TokenEOF;
+ }
+
+ return getToken(identOrKeyword);
+ }
+ // operators, number literals etc
+ return TokenOTHER;
+ }
+
+ /**
+ * @return the next char without shifting the position
+ */
+ private char peekNextChar() {
+ if (fPos + 1 < fDocument.getLength()) {
+ try {
+ return fDocument.getChar(fPos + 1);
+ } catch (BadLocationException exc) {
+ }
+ }
+ return (char)-1;
+ }
+
+ /**
+ * @return the previous char without shifting the position
+ */
+ private char peekPreviousChar() {
+ if (fPos >= 0) {
+ try {
+ return fDocument.getChar(fPos);
+ } catch (BadLocationException e) {
+ }
+ }
+ return (char)-1;
+ }
+
+ /**
+ * Returns one of the keyword constants or <code>TokenIDENT</code> for a scanned identifier.
+ *
+ * @param s a scanned identifier
+ * @return one of the constants defined in {@link STPSymbols}
+ */
+ private int getToken(String s) {
+ Assert.isNotNull(s);
+
+ switch (s.length()) {
+ case 2:
+ if ("if".equals(s)) //$NON-NLS-1$
+ return TokenIF;
+ if ("do".equals(s)) //$NON-NLS-1$
+ return TokenDO;
+ break;
+ case 3:
+ if ("for".equals(s)) //$NON-NLS-1$
+ return TokenFOR;
+ if ("try".equals(s)) //$NON-NLS-1$
+ return TokenTRY;
+ if ("new".equals(s)) //$NON-NLS-1$
+ return TokenNEW;
+ break;
+ case 4:
+ if ("case".equals(s)) //$NON-NLS-1$
+ return TokenCASE;
+ if ("else".equals(s)) //$NON-NLS-1$
+ return TokenELSE;
+ if ("enum".equals(s)) //$NON-NLS-1$
+ return TokenENUM;
+ if ("goto".equals(s)) //$NON-NLS-1$
+ return TokenGOTO;
+ break;
+ case 5:
+ if ("break".equals(s)) //$NON-NLS-1$
+ return TokenBREAK;
+ if ("catch".equals(s)) //$NON-NLS-1$
+ return TokenCATCH;
+ if ("class".equals(s)) //$NON-NLS-1$
+ return TokenCLASS;
+ if ("const".equals(s)) //$NON-NLS-1$
+ return TokenCONST;
+ if ("while".equals(s)) //$NON-NLS-1$
+ return TokenWHILE;
+ if ("union".equals(s)) //$NON-NLS-1$
+ return TokenUNION;
+ if ("using".equals(s)) //$NON-NLS-1$
+ return TokenUSING;
+ if ("throw".equals(s)) //$NON-NLS-1$
+ return TokenTHROW;
+ break;
+ case 6:
+ if ("delete".equals(s)) //$NON-NLS-1$
+ return TokenDELETE;
+ if ("public".equals(s)) //$NON-NLS-1$
+ return TokenPUBLIC;
+ if ("return".equals(s)) //$NON-NLS-1$
+ return TokenRETURN;
+ if ("static".equals(s)) //$NON-NLS-1$
+ return TokenSTATIC;
+ if ("struct".equals(s)) //$NON-NLS-1$
+ return TokenSTRUCT;
+ if ("switch".equals(s)) //$NON-NLS-1$
+ return TokenSWITCH;
+ if ("extern".equals(s)) //$NON-NLS-1$
+ return TokenEXTERN;
+ break;
+ case 7:
+ if ("default".equals(s)) //$NON-NLS-1$
+ return TokenDEFAULT;
+ if ("foreach".equals(s)) //$NON-NLS-1$
+ return TokenFOREACH;
+ if ("private".equals(s)) //$NON-NLS-1$
+ return TokenPRIVATE;
+ if ("typedef".equals(s)) //$NON-NLS-1$
+ return TokenTYPEDEF;
+ if ("virtual".equals(s)) //$NON-NLS-1$
+ return TokenVIRTUAL;
+ break;
+ case 8:
+ if ("operator".equals(s)) //$NON-NLS-1$
+ return TokenOPERATOR;
+ if ("template".equals(s)) //$NON-NLS-1$
+ return TokenTEMPLATE;
+ if ("typename".equals(s)) //$NON-NLS-1$
+ return TokenTYPENAME;
+ break;
+ case 9:
+ if ("namespace".equals(s)) //$NON-NLS-1$
+ return TokenNAMESPACE;
+ if ("protected".equals(s)) //$NON-NLS-1$
+ return TokenPROTECTED;
+ }
+ return TokenIDENT;
+ }
+
+ /**
+ * Returns the position of the closing peer character (forward search). Any scopes introduced
+ * by opening peers are skipped. All peers accounted for must reside in the default partition.
+ *
+ * <p>Note that <code>start</code> must not point to the opening peer, but to the first
+ * character being searched.</p>
+ *
+ * @param start the start position
+ * @param openingPeer the opening peer character (e.g. '{')
+ * @param closingPeer the closing peer character (e.g. '}')
+ * @return the matching peer character position, or <code>NOT_FOUND</code>
+ */
+ public int findClosingPeer(int start, final char openingPeer, final char closingPeer) {
+ return findClosingPeer(start, UNBOUND, openingPeer, closingPeer);
+ }
+
+ /**
+ * Returns the position of the closing peer character (forward search). Any scopes introduced by opening peers
+ * are skipped. All peers accounted for must reside in the default partition.
+ *
+ * <p>Note that <code>start</code> must not point to the opening peer, but to the first
+ * character being searched.</p>
+ *
+ * @param start the start position
+ * @param bound the bound
+ * @param openingPeer the opening peer character (e.g. '{')
+ * @param closingPeer the closing peer character (e.g. '}')
+ * @return the matching peer character position, or <code>NOT_FOUND</code>
+ */
+ private int findClosingPeer(int start, int bound, final char openingPeer, final char closingPeer) {
+ Assert.isLegal(start >= 0);
+
+ try {
+ int depth= 1;
+ start -= 1;
+ while (true) {
+ start= scanForward(start + 1, bound, new CharacterMatch(new char[] {openingPeer, closingPeer}));
+ if (start == NOT_FOUND)
+ return NOT_FOUND;
+
+ if (fDocument.getChar(start) == openingPeer)
+ depth++;
+ else
+ depth--;
+
+ if (depth == 0)
+ return start;
+ }
+
+ } catch (BadLocationException e) {
+ return NOT_FOUND;
+ }
+ }
+
+ /**
+ * Returns the position of the opening peer character (backward search). Any scopes introduced by closing peers
+ * are skipped. All peers accounted for must reside in the default partition.
+ *
+ * <p>Note that <code>start</code> must not point to the closing peer, but to the first
+ * character being searched.</p>
+ *
+ * @param start the start position
+ * @param openingPeer the opening peer character (e.g. '{')
+ * @param closingPeer the closing peer character (e.g. '}')
+ * @return the matching peer character position, or <code>NOT_FOUND</code>
+ */
+ public int findOpeningPeer(int start, char openingPeer, char closingPeer) {
+ return findOpeningPeer(start, STPHeuristicScanner.UNBOUND, openingPeer, closingPeer);
+ }
+
+ /**
+ * Returns the position of the opening peer character (backward search). Any scopes introduced by closing peers
+ * are skipped. All peers accounted for must reside in the default partition.
+ *
+ * <p>Note that <code>start</code> must not point to the closing peer, but to the first
+ * character being searched.</p>
+ *
+ * @param start the start position
+ * @param bound the bound
+ * @param openingPeer the opening peer character (e.g. '{')
+ * @param closingPeer the closing peer character (e.g. '}')
+ * @return the matching peer character position, or <code>NOT_FOUND</code>
+ */
+ public int findOpeningPeer(int start, int bound, char openingPeer, char closingPeer) {
+ Assert.isLegal(start < fDocument.getLength());
+
+ try {
+ final CharacterMatch match= new CharacterMatch(new char[] {openingPeer, closingPeer});
+ int depth= 1;
+ start += 1;
+ while (true) {
+ start= scanBackward(start - 1, bound, match);
+ if (start == NOT_FOUND)
+ return NOT_FOUND;
+
+ if (fDocument.getChar(start) == closingPeer)
+ depth++;
+ else
+ depth--;
+
+ if (depth == 0)
+ return start;
+ }
+
+ } catch (BadLocationException e) {
+ return NOT_FOUND;
+ }
+ }
+
+ /**
+ * Finds the smallest position in <code>fDocument</code> such that the position is &gt;= <code>position</code>
+ * and &lt; <code>bound</code> and <code>Character.isWhitespace(fDocument.getChar(pos))</code> evaluates to <code>false</code>.
+ *
+ * @param position the first character position in <code>fDocument</code> to be considered
+ * @param bound the first position in <code>fDocument</code> to not consider any more, with <code>bound</code> &gt; <code>position</code>, or <code>UNBOUND</code>
+ * @return the smallest position of a non-whitespace character in [<code>position</code>, <code>bound</code>), or <code>NOT_FOUND</code> if none can be found
+ */
+ public int findNonWhitespaceForwardInAnyPartition(int position, int bound) {
+ return scanForward(position, bound, fNonWS);
+ }
+
+ /**
+ * Finds the highest position in <code>fDocument</code> such that the position is &lt;= <code>position</code>
+ * and &gt; <code>bound</code> and <code>Character.isWhitespace(fDocument.getChar(pos))</code> evaluates to <code>false</code>
+ * and the position is in the default partition.
+ *
+ * @param position the first character position in <code>fDocument</code> to be considered
+ * @param bound the first position in <code>fDocument</code> to not consider any more, with <code>bound</code> &lt; <code>position</code>, or <code>UNBOUND</code>
+ * @return the highest position of a non-whitespace character in (<code>bound</code>, <code>position</code>] that resides in a C partition, or <code>NOT_FOUND</code> if none can be found
+ */
+ public int findNonWhitespaceBackward(int position, int bound) {
+ return scanBackward(position, bound, fNonWSDefaultPart);
+ }
+
+ /**
+ * Finds the lowest position <code>p</code> in <code>fDocument</code> such that <code>start</code> &lt;= p &lt;
+ * <code>bound</code> and <code>condition.stop(fDocument.getChar(p), p)</code> evaluates to <code>true</code>.
+ *
+ * @param start the first character position in <code>fDocument</code> to be considered
+ * @param bound the first position in <code>fDocument</code> to not consider any more, with <code>bound</code> &gt; <code>start</code>, or <code>UNBOUND</code>
+ * @param condition the <code>StopCondition</code> to check
+ * @return the lowest position in [<code>start</code>, <code>bound</code>) for which <code>condition</code> holds, or <code>NOT_FOUND</code> if none can be found
+ */
+ private int scanForward(int start, int bound, StopCondition condition) {
+ Assert.isLegal(start >= 0);
+
+ if (bound == UNBOUND)
+ bound= fDocument.getLength();
+
+ Assert.isLegal(bound <= fDocument.getLength());
+
+ try {
+ fPos= start;
+ while (fPos < bound) {
+
+ fChar= fDocument.getChar(fPos);
+ if (condition.stop(fChar, fPos, true))
+ return fPos;
+
+ fPos= condition.nextPosition(fPos, true);
+ }
+ } catch (BadLocationException e) {
+ }
+ return NOT_FOUND;
+ }
+
+
+ /**
+ * Finds the lowest position in <code>fDocument</code> such that the position is &gt;= <code>position</code>
+ * and &lt; <code>bound</code> and <code>fDocument.getChar(position) == ch</code> evaluates to <code>true</code>
+ * and the position is in the default partition.
+ *
+ * @param position the first character position in <code>fDocument</code> to be considered
+ * @param bound the first position in <code>fDocument</code> to not consider any more, with <code>bound</code> &gt; <code>position</code>, or <code>UNBOUND</code>
+ * @param ch the <code>char</code> to search for
+ * @return the lowest position of <code>ch</code> in (<code>bound</code>, <code>position</code>] that resides in a C partition, or <code>NOT_FOUND</code> if none can be found
+ */
+ public int scanForward(int position, int bound, char ch) {
+ return scanForward(position, bound, new CharacterMatch(ch));
+ }
+
+ /**
+ * Finds the highest position <code>p</code> in <code>fDocument</code> such that <code>bound</code> &lt; <code>p</code> &lt;= <code>start</code>
+ * and <code>condition.stop(fDocument.getChar(p), p)</code> evaluates to <code>true</code>.
+ *
+ * @param start the first character position in <code>fDocument</code> to be considered
+ * @param bound the first position in <code>fDocument</code> to not consider any more, with <code>bound</code> &lt; <code>start</code>, or <code>UNBOUND</code>
+ * @param condition the <code>StopCondition</code> to check
+ * @return the highest position in (<code>bound</code>, <code>start</code> for which <code>condition</code> holds, or <code>NOT_FOUND</code> if none can be found
+ */
+ private int scanBackward(int start, int bound, StopCondition condition) {
+ if (bound == UNBOUND)
+ bound= -1;
+
+ Assert.isLegal(bound >= -1);
+ Assert.isLegal(start < fDocument.getLength() );
+
+ try {
+ fPos= start;
+ while (fPos > bound) {
+
+ fChar= fDocument.getChar(fPos);
+ if (condition.stop(fChar, fPos, false))
+ return fPos;
+
+ fPos= condition.nextPosition(fPos, false);
+ }
+ } catch (BadLocationException e) {
+ }
+ return NOT_FOUND;
+ }
+
+ /**
+ * Checks whether <code>position</code> resides in a default (C) partition of <code>fDocument</code>.
+ *
+ * @param position the position to be checked
+ * @return <code>true</code> if <code>position</code> is in the default partition of <code>fDocument</code>, <code>false</code> otherwise
+ */
+ private boolean isDefaultPartition(int position) {
+ String type = getPartition(position).getType();
+ return fPartition.equals(type);
+ }
+
+ /**
+ * Returns the partition at <code>position</code>.
+ *
+ * @param position the position to get the partition for
+ * @return the partition at <code>position</code> or a dummy zero-length
+ * partition if accessing the document fails
+ */
+ private ITypedRegion getPartition(int position) {
+ if (!contains(fCachedPartition, position)) {
+ Assert.isTrue(position >= 0);
+ Assert.isTrue(position <= fDocument.getLength());
+
+ try {
+ fCachedPartition= TextUtilities.getPartition(fDocument, fPartitioning, position, false);
+ } catch (BadLocationException e) {
+ fCachedPartition= new TypedRegion(position, 0, "__no_partition_at_all"); //$NON-NLS-1$
+ }
+ }
+
+ return fCachedPartition;
+ }
+
+ /**
+ * Returns <code>true</code> if <code>region</code> contains <code>position</code>.
+ *
+ * @param region a region
+ * @param position an offset
+ * @return <code>true</code> if <code>region</code> contains <code>position</code>
+ */
+ private boolean contains(IRegion region, int position) {
+ int offset= region.getOffset();
+ return offset <= position && position < offset + region.getLength();
+ }
+
+ /**
+ * Checks if the line seems to be an open condition not followed by a block (i.e. an if, while,
+ * or for statement with just one following statement, see example below).
+ *
+ * <pre>
+ * if (condition)
+ * doStuff();
+ * </pre>
+ *
+ * <p>Algorithm: if the last non-WS, non-Comment code on the line is an if (condition), while (condition),
+ * for( expression), do, else, and there is no statement after that </p>
+ *
+ * @param position the insert position of the new character
+ * @param bound the lowest position to consider
+ * @return <code>true</code> if the code is a conditional statement or loop without a block, <code>false</code> otherwise
+ */
+ public boolean isBracelessBlockStart(int position, int bound) {
+ if (position < 1)
+ return false;
+
+ switch (previousToken(position, bound)) {
+ case TokenDO:
+ case TokenELSE:
+ return true;
+ case TokenRPAREN:
+ position= findOpeningPeer(fPos, STPHeuristicScanner.UNBOUND, LPAREN, RPAREN);
+ if (position > 0) {
+ switch (previousToken(position - 1, bound)) {
+ case TokenIF:
+ case TokenFOR:
+ case TokenFOREACH:
+ case TokenWHILE:
+ return true;
+ }
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Returns <code>true</code> if the document, when scanned backwards from <code>start</code>
+ * appears to be a composite type (class, struct, union) or enum definition. Examples:
+ *
+ * <pre>
+ * class A {
+ * struct A {
+ * class A : B {
+ * class A : virtual public B, protected C&lt;T&gt; {
+ * enum E {
+ * </pre>
+ *
+ * @param start the position of the opening brace.
+ * @param bound the first position in <code>fDocument</code> to not consider any more, with
+ * <code>bound</code> &lt; <code>start</code>, or <code>UNBOUND</code>
+ * @return <code>true</code> if the current position looks like a composite type definition
+ */
+ public boolean looksLikeCompositeTypeDefinitionBackward(int start, int bound) {
+ int token= previousToken(start - 1, bound);
+ switch (token) {
+ case STPSymbols.TokenSTRUCT:
+ case STPSymbols.TokenUNION:
+ case STPSymbols.TokenENUM:
+ return true; // anonymous
+ case STPSymbols.TokenIDENT:
+ token= previousToken(getPosition(), bound);
+ switch (token) {
+ case STPSymbols.TokenCLASS:
+ case STPSymbols.TokenSTRUCT:
+ case STPSymbols.TokenUNION:
+ case STPSymbols.TokenENUM:
+ return true; // no base-clause
+ default:
+ // backtrack
+ token= previousToken(start - 1, bound);
+ }
+ break;
+ default:
+ // backtrack
+ token= previousToken(start - 1, bound);
+ break;
+ }
+ // match base-clause
+ if (token == STPSymbols.TokenGREATERTHAN) {
+ findOpeningPeer(getPosition(), bound, '<', '>');
+ token= previousToken(getPosition(), bound);
+ if (token != STPSymbols.TokenLESSTHAN) {
+ return false;
+ }
+ token= previousToken(getPosition(), bound);
+ }
+ outerWhile: while (token == STPSymbols.TokenIDENT) {// type name or base type
+ token= previousToken(getPosition(), bound);
+ // match nested-name-specifier
+ while (token == STPSymbols.TokenCOLON) { // colon of qualification
+ token= previousToken(getPosition(), bound);
+ if (token != STPSymbols.TokenCOLON) { // second colon of qualification
+ break outerWhile;
+ }
+ token= previousToken(getPosition(), bound);
+ if (token != STPSymbols.TokenIDENT) // qualification name?
+ break;
+ token= previousToken(getPosition(), bound);
+ }
+ switch (token) {
+ case STPSymbols.TokenVIRTUAL:
+ token= previousToken(getPosition(), bound);
+ //$FALL-THROUGH$
+ case STPSymbols.TokenPUBLIC:
+ case STPSymbols.TokenPROTECTED:
+ case STPSymbols.TokenPRIVATE:
+ token= previousToken(getPosition(), bound);
+ if (token == STPSymbols.TokenVIRTUAL) {
+ token= previousToken(getPosition(), bound);
+ }
+ if (token == STPSymbols.TokenCOMMA) {
+ token= previousToken(getPosition(), bound);
+ if (token == STPSymbols.TokenGREATERTHAN) {
+ findOpeningPeer(getPosition(), bound, '<', '>');
+ token= previousToken(getPosition(), bound);
+ if (token != STPSymbols.TokenLESSTHAN) {
+ return false;
+ }
+ token= previousToken(getPosition(), bound);
+ }
+ continue; // another base type
+ }
+ if (token != STPSymbols.TokenCOLON) // colon after class def identifier
+ return false;
+ //$FALL-THROUGH$
+ case STPSymbols.TokenCOLON:
+ token= previousToken(getPosition(), bound);
+ break outerWhile;
+ case STPSymbols.TokenCOMMA:
+ token= previousToken(getPosition(), bound);
+ if (token == STPSymbols.TokenGREATERTHAN) {
+ findOpeningPeer(getPosition(), bound, '<', '>');
+ token= previousToken(getPosition(), bound);
+ if (token != STPSymbols.TokenLESSTHAN) {
+ return false;
+ }
+ token= previousToken(getPosition(), bound);
+ }
+ continue; // another base type
+ case STPSymbols.TokenIDENT:
+ break outerWhile;
+ default:
+ return false;
+ }
+ }
+ if (token != STPSymbols.TokenIDENT) {
+ return false;
+ }
+ token= previousToken(getPosition(), bound);
+ switch (token) {
+ case STPSymbols.TokenCLASS:
+ case STPSymbols.TokenSTRUCT:
+ case STPSymbols.TokenUNION:
+ case STPSymbols.TokenENUM: // enum is actually not valid here
+ return true;
+ default:
+ return false;
+ }
+ }
}
diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/STPIndenter.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/STPIndenter.java
index 537dd24d91..743a5adc17 100644
--- a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/STPIndenter.java
+++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/STPIndenter.java
@@ -41,2298 +41,2298 @@ import org.eclipse.linuxtools.internal.systemtap.ui.ide.IDEPlugin;
* </p>
*/
public final class STPIndenter {
- /**
- * The CDT Core preferences.
- */
- private final class CorePrefs {
- private final boolean prefUseTabs;
- private final boolean prefArrayDimensionsDeepIndent;
- private final int prefArrayIndent;
- private final boolean prefArrayDeepIndent;
- private final boolean prefTernaryDeepAlign;
- private final int prefTernaryIndent;
- private final int prefCaseIndent;
- private final int prefCaseBlockIndent;
- private final int prefAssignmentIndent;
- private final int prefSimpleIndent;
- private final int prefBracketIndent;
- private final boolean prefMethodDeclDeepIndent;
- private final boolean prefMethodDeclFirstParameterDeepIndent;
- private final int prefMethodDeclIndent;
- private final boolean prefMethodCallDeepIndent;
- private final boolean prefMethodCallFirstParameterDeepIndent;
- private final int prefMethodCallIndent;
- private final boolean prefParenthesisDeepIndent;
- private final int prefParenthesisIndent;
- private final int prefBlockIndent;
- private final int prefMethodBodyIndent;
- private final int prefTypeIndent;
- private final int prefAccessSpecifierIndent;
- private final int prefAccessSpecifierExtraSpaces;
- private final int prefNamespaceBodyIndent;
- private final boolean prefIndentBracesForBlocks;
- private final boolean prefIndentBracesForArrays;
- private final boolean prefIndentBracesForMethods;
- private final boolean prefIndentBracesForTypes;
- private final int prefContinuationIndent;
- private final boolean prefHasTemplates;
- private final String prefTabChar;
-
- private final IPreferencesService preferenceService;
- private final IScopeContext[] preferenceContexts;
-
- /**
- * Returns the possibly project-specific core preference defined under <code>key</code>.
- *
- * @param key the key of the preference
- * @return the value of the preference
- */
- private String getCoreFormatterOption(String key) {
- return getCoreFormatterOption(key, null);
- }
-
- private String getCoreFormatterOption(String key, String defaultValue) {
- return preferenceService.getString(IDEPlugin.PLUGIN_ID, key, defaultValue, preferenceContexts);
- }
-
- private int getCoreFormatterOption(String key, int defaultValue) {
- return preferenceService.getInt(IDEPlugin.PLUGIN_ID, key, defaultValue, preferenceContexts);
- }
-
- CorePrefs(IProject project) {
- preferenceService = Platform.getPreferencesService();
- preferenceContexts = project != null ?
- new IScopeContext[] { new ProjectScope(project.getProject()),
- InstanceScope.INSTANCE, DefaultScope.INSTANCE } :
- new IScopeContext[] { InstanceScope.INSTANCE, DefaultScope.INSTANCE };
- prefUseTabs= prefUseTabs();
- prefArrayDimensionsDeepIndent= prefArrayDimensionsDeepIndent();
- prefContinuationIndent= prefContinuationIndent();
- prefBlockIndent= prefBlockIndent();
- prefArrayIndent= prefArrayIndent();
- prefArrayDeepIndent= prefArrayDeepIndent();
- prefTernaryDeepAlign= false;
- prefTernaryIndent= prefContinuationIndent();
- prefCaseIndent= prefCaseIndent();
- prefCaseBlockIndent= prefCaseBlockIndent();
- prefAssignmentIndent= prefAssignmentIndent();
- prefIndentBracesForBlocks= prefIndentBracesForBlocks();
- prefSimpleIndent= prefSimpleIndent();
- prefBracketIndent= prefBracketIndent();
- prefMethodDeclDeepIndent= prefMethodDeclDeepIndent();
- prefMethodDeclFirstParameterDeepIndent= prefMethodDeclFirstParameterDeepIndent();
- prefMethodDeclIndent= prefMethodDeclIndent();
- prefMethodCallDeepIndent= prefMethodCallDeepIndent();
- prefMethodCallFirstParameterDeepIndent= prefMethodCallFirstParameterDeepIndent();
- prefMethodCallIndent= prefMethodCallIndent();
- prefParenthesisDeepIndent= prefParenthesisDeepIndent();
- prefParenthesisIndent= prefParenthesisIndent();
- prefMethodBodyIndent= prefMethodBodyIndent();
- prefTypeIndent= prefTypeIndent();
- prefAccessSpecifierIndent= prefAccessSpecifierIndent();
- prefAccessSpecifierExtraSpaces= prefAccessSpecifierExtraSpaces();
- prefNamespaceBodyIndent= prefNamespaceBodyIndent();
- prefIndentBracesForArrays= prefIndentBracesForArrays();
- prefIndentBracesForMethods= prefIndentBracesForMethods();
- prefIndentBracesForTypes= prefIndentBracesForTypes();
- prefHasTemplates= hasTemplates();
- prefTabChar= getCoreFormatterOption(STPDefaultCodeFormatterConstants.FORMATTER_TAB_CHAR);
- }
-
- private boolean prefUseTabs() {
- return !IDEPlugin.SPACE.equals(getCoreFormatterOption(STPDefaultCodeFormatterConstants.FORMATTER_TAB_CHAR));
- }
-
- private boolean prefArrayDimensionsDeepIndent() {
- return true; // sensible default, no formatter setting
- }
-
- private int prefArrayIndent() {
- String option= getCoreFormatterOption(STPDefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_EXPRESSIONS_IN_INITIALIZER_LIST);
- try {
- if (STPDefaultCodeFormatterConstants.getIndentStyle(option) == STPDefaultCodeFormatterConstants.INDENT_BY_ONE)
- return 1;
- } catch (IllegalArgumentException e) {
- // ignore and return default
- }
-
- return prefContinuationIndent(); // default
- }
-
- private boolean prefArrayDeepIndent() {
- String option= getCoreFormatterOption(STPDefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_EXPRESSIONS_IN_INITIALIZER_LIST);
- try {
- return STPDefaultCodeFormatterConstants.getIndentStyle(option) == STPDefaultCodeFormatterConstants.INDENT_ON_COLUMN;
- } catch (IllegalArgumentException e) {
- // ignore and return default
- }
-
- return true;
- }
-
- private int prefCaseIndent() {
- if (STPDefaultCodeFormatterConstants.TRUE.equals(getCoreFormatterOption(STPDefaultCodeFormatterConstants.FORMATTER_INDENT_SWITCHSTATEMENTS_COMPARE_TO_SWITCH)))
- return 1;
- else
- return 0;
- }
-
- private int prefCaseBlockIndent() {
- if (STPDefaultCodeFormatterConstants.TRUE.equals(getCoreFormatterOption(STPDefaultCodeFormatterConstants.FORMATTER_INDENT_SWITCHSTATEMENTS_COMPARE_TO_CASES)))
- return 1;
- else
- return 0;
- }
-
- private int prefAssignmentIndent() {
- return prefContinuationIndent();
- }
-
- private int prefSimpleIndent() {
- if (prefIndentBracesForBlocks() && prefBlockIndent() == 0)
- return 1;
- else
- return prefBlockIndent();
- }
-
- private int prefBracketIndent() {
- return prefBlockIndent();
- }
-
- private boolean prefMethodDeclDeepIndent() {
- String option= getCoreFormatterOption(STPDefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_PARAMETERS_IN_METHOD_DECLARATION);
- try {
- int indentStyle = STPDefaultCodeFormatterConstants.getIndentStyle(option);
- return indentStyle == STPDefaultCodeFormatterConstants.INDENT_ON_COLUMN;
- } catch (IllegalArgumentException e) {
- // ignore and return default
- }
-
- return false;
- }
-
- private boolean prefMethodDeclFirstParameterDeepIndent() {
- String option= getCoreFormatterOption(STPDefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_PARAMETERS_IN_METHOD_DECLARATION);
- try {
- int indentStyle = STPDefaultCodeFormatterConstants.getIndentStyle(option);
- int wrappingStyle = STPDefaultCodeFormatterConstants.getWrappingStyle(option);
- return indentStyle == STPDefaultCodeFormatterConstants.INDENT_ON_COLUMN &&
- (wrappingStyle == STPDefaultCodeFormatterConstants.WRAP_COMPACT_FIRST_BREAK ||
- wrappingStyle == STPDefaultCodeFormatterConstants.WRAP_ONE_PER_LINE);
- } catch (IllegalArgumentException e) {
- // ignore and return default
- }
-
- return false;
- }
-
- private int prefMethodDeclIndent() {
- String option= getCoreFormatterOption(STPDefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_PARAMETERS_IN_METHOD_DECLARATION);
- try {
- if (STPDefaultCodeFormatterConstants.getIndentStyle(option) == STPDefaultCodeFormatterConstants.INDENT_BY_ONE)
- return 1;
- else
- return prefContinuationIndent();
- } catch (IllegalArgumentException e) {
- // ignore and return default
- }
- return 1;
- }
-
- private boolean prefMethodCallDeepIndent() {
- String option= getCoreFormatterOption(STPDefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_ARGUMENTS_IN_METHOD_INVOCATION);
- try {
- int indentStyle = STPDefaultCodeFormatterConstants.getIndentStyle(option);
- return indentStyle == STPDefaultCodeFormatterConstants.INDENT_ON_COLUMN;
- } catch (IllegalArgumentException e) {
- // ignore and return default
- }
- return false; // sensible default
- }
-
- private boolean prefMethodCallFirstParameterDeepIndent() {
- String option= getCoreFormatterOption(STPDefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_ARGUMENTS_IN_METHOD_INVOCATION);
- try {
- int indentStyle = STPDefaultCodeFormatterConstants.getIndentStyle(option);
- int wrappingStyle = STPDefaultCodeFormatterConstants.getWrappingStyle(option);
- return indentStyle == STPDefaultCodeFormatterConstants.INDENT_ON_COLUMN &&
- (wrappingStyle == STPDefaultCodeFormatterConstants.WRAP_COMPACT_FIRST_BREAK ||
- wrappingStyle == STPDefaultCodeFormatterConstants.WRAP_ONE_PER_LINE);
- } catch (IllegalArgumentException e) {
- // ignore and return default
- }
- return false; // sensible default
- }
-
- private int prefMethodCallIndent() {
- String option= getCoreFormatterOption(STPDefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_ARGUMENTS_IN_METHOD_INVOCATION);
- try {
- if (STPDefaultCodeFormatterConstants.getIndentStyle(option) == STPDefaultCodeFormatterConstants.INDENT_BY_ONE)
- return 1;
- else
- return prefContinuationIndent();
- } catch (IllegalArgumentException e) {
- // ignore and return default
- }
-
- return 1; // sensible default
- }
-
- private boolean prefParenthesisDeepIndent() {
- return false;
- }
-
- private int prefParenthesisIndent() {
- return prefContinuationIndent();
- }
-
- private int prefBlockIndent() {
- String option= getCoreFormatterOption(STPDefaultCodeFormatterConstants.FORMATTER_INDENT_STATEMENTS_COMPARE_TO_BLOCK);
- if (STPDefaultCodeFormatterConstants.FALSE.equals(option))
- return 0;
-
- return 1; // sensible default
- }
-
- private int prefMethodBodyIndent() {
- if (STPDefaultCodeFormatterConstants.FALSE.equals(getCoreFormatterOption(STPDefaultCodeFormatterConstants.FORMATTER_INDENT_STATEMENTS_COMPARE_TO_BODY)))
- return 0;
-
- return 1; // sensible default
- }
-
- private int prefTypeIndent() {
- String option= getCoreFormatterOption(STPDefaultCodeFormatterConstants.FORMATTER_INDENT_BODY_DECLARATIONS_COMPARE_TO_ACCESS_SPECIFIER);
- if (STPDefaultCodeFormatterConstants.FALSE.equals(option))
- return 0;
-
- return 1; // sensible default
- }
-
- private int prefAccessSpecifierIndent() {
- if (STPDefaultCodeFormatterConstants.TRUE.equals(getCoreFormatterOption(STPDefaultCodeFormatterConstants.FORMATTER_INDENT_ACCESS_SPECIFIER_COMPARE_TO_TYPE_HEADER)))
- return 1;
- else
- return 0;
- }
-
- private int prefAccessSpecifierExtraSpaces() {
- return getCoreFormatterOption(STPDefaultCodeFormatterConstants.FORMATTER_INDENT_ACCESS_SPECIFIER_EXTRA_SPACES, 0);
- }
-
- private int prefNamespaceBodyIndent() {
- if (STPDefaultCodeFormatterConstants.TRUE.equals(getCoreFormatterOption(STPDefaultCodeFormatterConstants.FORMATTER_INDENT_BODY_DECLARATIONS_COMPARE_TO_NAMESPACE_HEADER)))
- return prefBlockIndent();
- else
- return 0;
- }
-
- private boolean prefIndentBracesForBlocks() {
- return STPDefaultCodeFormatterConstants.NEXT_LINE_SHIFTED.equals(getCoreFormatterOption(STPDefaultCodeFormatterConstants.FORMATTER_BRACE_POSITION_FOR_BLOCK));
- }
-
- private boolean prefIndentBracesForArrays() {
- return STPDefaultCodeFormatterConstants.NEXT_LINE_SHIFTED.equals(getCoreFormatterOption(STPDefaultCodeFormatterConstants.FORMATTER_BRACE_POSITION_FOR_INITIALIZER_LIST));
- }
-
- private boolean prefIndentBracesForMethods() {
- return STPDefaultCodeFormatterConstants.NEXT_LINE_SHIFTED.equals(getCoreFormatterOption(STPDefaultCodeFormatterConstants.FORMATTER_BRACE_POSITION_FOR_METHOD_DECLARATION));
- }
-
- private boolean prefIndentBracesForTypes() {
- return STPDefaultCodeFormatterConstants.NEXT_LINE_SHIFTED.equals(getCoreFormatterOption(STPDefaultCodeFormatterConstants.FORMATTER_BRACE_POSITION_FOR_TYPE_DECLARATION));
- }
-
- private int prefContinuationIndent() {
- try {
- return Integer.parseInt(getCoreFormatterOption(STPDefaultCodeFormatterConstants.FORMATTER_CONTINUATION_INDENTATION));
- } catch (NumberFormatException e) {
- // ignore and return default
- }
-
- return 2; // sensible default
- }
-
- private boolean hasTemplates() {
- return true;
- }
- }
-
- /** The document being scanned. */
- private final IDocument fDocument;
- /** The indentation accumulated by <code>findReferencePosition</code>. */
- private int fIndent;
- /** Extra spaces to add on top of fIndent */
- private int fExtraSpaces;
- /**
- * The absolute (character-counted) indentation offset for special cases
- * (method definitions, array initializers)
- */
- private int fAlign;
- /** The stateful scan position for the indentation methods. */
- private int fPosition;
- /** The previous position. */
- private int fPreviousPos;
- /** The most recent token. */
- private int fToken;
- /** The line of <code>fPosition</code>. */
- private int fLine;
- /**
- * The scanner we will use to scan the document. It has to be installed
- * on the same document as the one we get.
- */
- private final STPHeuristicScanner fScanner;
- /**
- * The CDT Core preferences.
- */
- private final CorePrefs fPrefs;
-
- /**
- * Creates a new instance.
- *
- * @param document the document to scan
- * @param scanner the {@link STPHeuristicScanner} to be used for scanning
- * the document. It must be installed on the same <code>IDocument</code>.
- */
- public STPIndenter(IDocument document, STPHeuristicScanner scanner) {
- this(document, scanner, null);
- }
-
- /**
- * Creates a new instance.
- *
- * @param document the document to scan
- * @param scanner the {@link STPHeuristicScanner} to be used for scanning
- * the document. It must be installed on the same
- * <code>IDocument</code>.
- * @param project the C/C++ project to get the formatter preferences from, or
- * <code>null</code> to use the workspace settings
- */
- public STPIndenter(IDocument document, STPHeuristicScanner scanner, IProject project) {
- Assert.isNotNull(document);
- Assert.isNotNull(scanner);
- fDocument= document;
- fScanner= scanner;
- fPrefs= new CorePrefs(project);
- }
-
- /**
- * Computes the indentation at the reference point of <code>position</code>.
- *
- * @param offset the offset in the document
- * @return a String which reflects the indentation at the line in which the
- * reference position to <code>offset</code> resides, or <code>null</code>
- * if it cannot be determined
- */
- public StringBuilder getReferenceIndentation(int offset) {
- return getReferenceIndentation(offset, false);
- }
-
- /**
- * Computes the indentation at the reference point of <code>position</code>.
- *
- * @param offset the offset in the document
- * @param assumeOpeningBrace <code>true</code> if an opening brace should be assumed
- * @return a String which reflects the indentation at the line in which the
- * reference position to <code>offset</code> resides, or <code>null</code>
- * if it cannot be determined
- */
- private StringBuilder getReferenceIndentation(int offset, boolean assumeOpeningBrace) {
- int unit= findReferencePosition(offset,
- assumeOpeningBrace ? STPSymbols.TokenLBRACE : peekToken(offset));
-
- // if we were unable to find anything, return null
- if (unit == NOT_FOUND)
- return null;
-
- return getLeadingWhitespace(unit);
- }
-
- /**
- * Computes the indentation at <code>offset</code>.
- *
- * @param offset the offset in the document
- * @return a String which reflects the correct indentation for the line in
- * which offset resides, or <code>null</code> if it cannot be
- * determined
- */
- public StringBuilder computeIndentation(int offset) {
- return computeIndentation(offset, false);
- }
-
- /**
- * Computes the indentation at <code>offset</code>.
- *
- * @param offset the offset in the document
- * @param assumeOpeningBrace <code>true</code> if an opening brace should be assumed
- * @return a String which reflects the correct indentation for the line in
- * which offset resides, or <code>null</code> if it cannot be
- * determined
- */
- public StringBuilder computeIndentation(int offset, boolean assumeOpeningBrace) {
- StringBuilder reference= getReferenceIndentation(offset, assumeOpeningBrace);
-
- // handle special alignment
- if (fAlign != NOT_FOUND) {
- try {
- // a special case has been detected.
- IRegion line= fDocument.getLineInformationOfOffset(fAlign);
- int lineOffset= line.getOffset();
- return createIndent(lineOffset, fAlign, false);
- } catch (BadLocationException e) {
- return null;
- }
- }
-
- if (reference == null)
- return null;
-
- // Add additional indent
- return createReusingIndent(reference, fIndent, fExtraSpaces);
- }
-
- /**
- * Computes the length of a <code>CharacterSequence</code>, counting
- * a tab character as the size until the next tab stop and every other
- * character as one.
- *
- * @param indent the string to measure
- * @return the visual length in characters
- */
- private int computeVisualLength(CharSequence indent) {
- final int tabSize= CodeFormatterUtil.getTabWidth();
- int length= 0;
- for (int i= 0; i < indent.length(); i++) {
- char ch= indent.charAt(i);
- switch (ch) {
- case '\t':
- if (tabSize > 0) {
- int reminder= length % tabSize;
- length += tabSize - reminder;
- }
- break;
- case ' ':
- length++;
- break;
- }
- }
- return length;
- }
-
- /**
- * Strips any characters off the end of <code>reference</code> that exceed
- * <code>indentLength</code>.
- *
- * @param reference the string to measure
- * @param indentLength the maximum visual indentation length
- * @return the stripped <code>reference</code>
- */
- private StringBuilder stripExceedingChars(StringBuilder reference, int indentLength) {
- final int tabSize= CodeFormatterUtil.getTabWidth();
- int measured= 0;
- int chars= reference.length();
- int i= 0;
- for (; measured < indentLength && i < chars; i++) {
- char ch= reference.charAt(i);
- switch (ch) {
- case '\t':
- if (tabSize > 0) {
- int reminder= measured % tabSize;
- measured += tabSize - reminder;
- }
- break;
- case ' ':
- measured++;
- break;
- }
- }
- int deleteFrom= measured > indentLength ? i - 1 : i;
-
- return reference.delete(deleteFrom, chars);
- }
-
- /**
- * Returns the indentation of the line at <code>offset</code> as a
- * <code>StringBuilder</code>. If the offset is not valid, the empty string
- * is returned.
- *
- * @param offset the offset in the document
- * @return the indentation (leading whitespace) of the line in which
- * <code>offset</code> is located
- */
- private StringBuilder getLeadingWhitespace(int offset) {
- StringBuilder indent= new StringBuilder();
- try {
- IRegion line= fDocument.getLineInformationOfOffset(offset);
- int lineOffset= line.getOffset();
- int nonWS= fScanner.findNonWhitespaceForwardInAnyPartition(lineOffset, lineOffset + line.getLength());
- indent.append(fDocument.get(lineOffset, nonWS - lineOffset));
- return indent;
- } catch (BadLocationException e) {
- return indent;
- }
- }
-
- /**
- * Creates an indentation string of the length indent - start, consisting of
- * the content in <code>fDocument</code> in the range [start, indent),
- * with every character replaced by a space except for tabs, which are kept
- * as such.
- * <p>
- * If <code>convertSpaceRunsToTabs</code> is <code>true</code>, every
- * run of the number of spaces that make up a tab are replaced by a tab
- * character. If it is not set, no conversion takes place, but tabs in the
- * original range are still copied verbatim.
- * </p>
- *
- * @param start the start of the document region to copy the indent from
- * @param indent the exclusive end of the document region to copy the indent
- * from
- * @param convertSpaceRunsToTabs whether to convert consecutive runs of
- * spaces to tabs
- * @return the indentation corresponding to the document content specified
- * by <code>start</code> and <code>indent</code>
- */
- private StringBuilder createIndent(int start, final int indent, final boolean convertSpaceRunsToTabs) {
- final boolean convertTabs= fPrefs.prefUseTabs && convertSpaceRunsToTabs;
- final int tabLen= CodeFormatterUtil.getTabWidth();
- final StringBuilder ret= new StringBuilder();
- try {
- int spaces= 0;
- while (start < indent) {
- char ch= fDocument.getChar(start);
- if (ch == '\t') {
- ret.append('\t');
- spaces= 0;
- } else if (convertTabs) {
- spaces++;
- if (spaces == tabLen) {
- ret.append('\t');
- spaces= 0;
- }
- } else {
- ret.append(' ');
- }
-
- start++;
- }
- // remainder
- while (spaces-- > 0)
- ret.append(' ');
- } catch (BadLocationException e) {
- }
-
- return ret;
- }
-
- /**
- * Creates a string with a visual length of the given
- * <code>indentationSize</code>.
- *
- * @param buffer the original indent to reuse if possible
- * @param additional the additional indentation units to add or subtract to
- * reference
- * @param extraSpaces additional spaces to add to indentation.
- * @return the modified <code>buffer</code> reflecting the indentation
- * adapted to <code>additional</code>
- */
- public StringBuilder createReusingIndent(StringBuilder buffer, int additional, int extraSpaces) {
- int refLength= computeVisualLength(buffer);
- int addLength= CodeFormatterUtil.getIndentWidth() * additional + extraSpaces; // may be < 0
- int totalLength= Math.max(0, refLength + addLength);
-
- // copy the reference indentation for the indent up to the last tab
- // stop within the maxCopy area
- int minLength= Math.min(totalLength, refLength);
- int tabSize= CodeFormatterUtil.getTabWidth();
- int maxCopyLength= tabSize > 0 ? minLength - minLength % tabSize : minLength; // maximum indent to copy
- stripExceedingChars(buffer, maxCopyLength);
-
- // add additional indent
- int missing= totalLength - maxCopyLength;
- int tabs, spaces;
- if (IDEPlugin.SPACE.equals(fPrefs.prefTabChar)) {
- tabs= 0;
- spaces= missing;
- } else {
- tabs= tabSize > 0 ? missing / tabSize : 0;
- spaces= tabSize > 0 ? missing % tabSize : missing;
- }
- for (int i= 0; i < tabs; i++)
- buffer.append('\t');
- for (int i= 0; i < spaces; i++)
- buffer.append(' ');
- return buffer;
- }
-
- /**
- * Returns relative indent of continuation lines.
- * @return a number of indentation units.
- */
- public int getContinuationLineIndent() {
- return fPrefs.prefContinuationIndent;
- }
-
- /**
- * Returns the reference position regarding to indentation for <code>offset</code>,
- * or {@link STPHeuristicScanner#NOT_FOUND NOT_FOUND}. This method calls
- * {@link #findReferencePosition(int, int) findReferencePosition(offset, nextChar)} where
- * <code>nextChar</code> is the next character after <code>offset</code>.
- *
- * @param offset the offset for which the reference is computed
- * @return the reference statement relative to which <code>offset</code>
- * should be indented, or {@link STPHeuristicScanner#NOT_FOUND NOT_FOUND}
- */
- public int findReferencePosition(int offset) {
- return findReferencePosition(offset, peekToken(offset));
- }
-
- /**
- * Peeks the next token in the document that comes after <code>offset</code>
- * on the same line as <code>offset</code>.
- *
- * @param offset the offset into document
- * @return the token symbol of the next element, or TokenEOF if there is none
- */
- private int peekToken(int offset) {
- if (offset < fDocument.getLength()) {
- try {
- IRegion line= fDocument.getLineInformationOfOffset(offset);
- int lineEnd= line.getOffset() + line.getLength();
- int next= fScanner.nextToken(offset, lineEnd);
- return next;
- } catch (BadLocationException e) {
- }
- }
- return STPSymbols.TokenEOF;
- }
-
- /**
- * Peeks the second next token in the document that comes after <code>offset</code>
- * on the same line as <code>offset</code>.
- *
- * @param offset the offset into document
- * @return the token symbol of the second next element, or TokenEOF if there is none
- */
- private int peekSecondToken(int offset) {
- if (offset < fDocument.getLength()) {
- try {
- IRegion line= fDocument.getLineInformationOfOffset(offset);
- int lineEnd= line.getOffset() + line.getLength();
- fScanner.nextToken(offset, lineEnd);
- int next = fScanner.nextToken(fScanner.getPosition(), lineEnd);
- return next;
- } catch (BadLocationException e) {
- }
- }
- return STPSymbols.TokenEOF;
- }
-
- /**
- * Returns the reference position regarding to indentation for <code>position</code>,
- * or {@link STPHeuristicScanner#NOT_FOUND NOT_FOUND}.
- *
- * <p>If <code>peekNextChar</code> is <code>true</code>, the next token after
- * <code>offset</code> is read and taken into account when computing the
- * indentation. Currently, if the next token is the first token on the line
- * (i.e. only preceded by whitespace), the following tokens are specially
- * handled:
- * <ul>
- * <li><code>switch</code> labels are indented relative to the switch block</li>
- * <li>opening curly braces are aligned correctly with the introducing code</li>
- * <li>closing curly braces are aligned properly with the introducing code of
- * the matching opening brace</li>
- * <li>closing parenthesis' are aligned with their opening peer</li>
- * <li>the <code>else</code> keyword is aligned with its <code>if</code>, anything
- * else is aligned normally (i.e. with the base of any introducing statements).</li>
- * <li>if there is no token on the same line after <code>offset</code>, the indentation
- * is the same as for an <code>else</code> keyword</li>
- * </ul>
- *
- * @param offset the offset for which the reference is computed
- * @param nextToken the next token to assume in the document
- * @return the reference statement relative to which <code>offset</code>
- * should be indented, or {@link STPHeuristicScanner#NOT_FOUND NOT_FOUND}
- */
- private int findReferencePosition(int offset, int nextToken) {
- boolean danglingElse= false;
- boolean cancelIndent= false; // If set to true, fIndent is ignored.
- int extraIndent= 0; // Can be either positive or negative.
- MatchMode matchMode = MatchMode.REGULAR;
-
- // Account for un-indentation characters already typed in, but after position.
- // If they are on a line by themselves, the indentation gets adjusted accordingly.
- //
- // Also account for a dangling else.
- if (offset < fDocument.getLength()) {
- try {
- IRegion line= fDocument.getLineInformationOfOffset(offset);
- int lineOffset= line.getOffset();
- int prevPos= Math.max(offset - 1, 0);
- boolean isFirstTokenOnLine=
- fDocument.get(lineOffset, prevPos + 1 - lineOffset).trim().length() == 0;
- int prevToken= fScanner.previousToken(prevPos, STPHeuristicScanner.UNBOUND);
- boolean bracelessBlockStart= fScanner.isBracelessBlockStart(prevPos, STPHeuristicScanner.UNBOUND);
-
- switch (nextToken) {
- case STPSymbols.TokenELSE:
- danglingElse= true;
- break;
-
- case STPSymbols.TokenCASE:
- case STPSymbols.TokenDEFAULT:
- if (isFirstTokenOnLine)
- matchMode = MatchMode.MATCH_CASE;
- break;
-
- case STPSymbols.TokenPUBLIC:
- case STPSymbols.TokenPROTECTED:
- case STPSymbols.TokenPRIVATE:
- if (isFirstTokenOnLine && peekSecondToken(offset) != STPSymbols.TokenIDENT)
- matchMode = MatchMode.MATCH_ACCESS_SPECIFIER;
- break;
-
- case STPSymbols.TokenLBRACE: // for opening-brace-on-new-line style
- if (bracelessBlockStart) {
- extraIndent= fPrefs.prefIndentBracesForBlocks ? 0 : -1;
- } else if (prevToken == STPSymbols.TokenCOLON && !fPrefs.prefIndentBracesForBlocks) {
- extraIndent= -1;
- } else if ((prevToken == STPSymbols.TokenEQUAL || prevToken == STPSymbols.TokenRBRACKET) &&
- !fPrefs.prefIndentBracesForArrays) {
- cancelIndent= true;
- } else if ((prevToken == STPSymbols.TokenRPAREN || prevToken == STPSymbols.TokenCONST) && fPrefs.prefIndentBracesForMethods) {
- extraIndent= 1;
- } else if (prevToken == STPSymbols.TokenIDENT) {
- if (fPrefs.prefIndentBracesForTypes) {
- extraIndent= 1;
- }
- int pos = fPosition;
- fPosition = offset;
- if (matchTypeDeclaration() != NOT_FOUND) {
- matchMode = MatchMode.MATCH_TYPE_DECLARATION;
- }
- fPosition = pos;
- }
- break;
-
- case STPSymbols.TokenRBRACE: // closing braces get unindented
- if (isFirstTokenOnLine || prevToken != STPSymbols.TokenLBRACE)
- matchMode = MatchMode.MATCH_BRACE;
- break;
-
- case STPSymbols.TokenRPAREN:
- if (isFirstTokenOnLine)
- matchMode = MatchMode.MATCH_PAREN;
- break;
- }
- } catch (BadLocationException e) {
- }
- } else {
- // Don't assume an else could come if we are at the end of file.
- danglingElse= false;
- }
-
- int ref= findReferencePosition(offset, danglingElse, matchMode);
- if (cancelIndent) {
- fIndent = 0;
- } else if (extraIndent > 0) {
- fAlign= NOT_FOUND;
- fIndent += extraIndent;
- } else {
- fIndent += extraIndent;
- }
- return ref;
- }
-
- /**
- * Enumeration used by {@link #findReferencePosition(int, boolean, MatchMode)} method.
- */
- public enum MatchMode {
- /**
- * The reference position should be returned based on the regular code analysis.
- */
- REGULAR,
- /**
- * The position of the matching brace should be returned instead of doing code analysis.
- */
- MATCH_BRACE,
- /**
- * The position of the matching parenthesis should be returned instead of doing code
- * analysis.
- */
- MATCH_PAREN,
- /**
- * The position of a switch statement reference should be returned (either an earlier case
- * statement or the switch block brace).
- */
- MATCH_CASE,
- /**
- * The position of a class body reference should be returned (either an earlier
- * public/protected/private or the class body brace).
- */
- MATCH_ACCESS_SPECIFIER,
- /**
- * The position of a class declaration should be returned.
- */
- MATCH_TYPE_DECLARATION
- }
-
- /**
- * Returns the reference position regarding to indentation for <code>position</code>,
- * or {@link STPHeuristicScanner#NOT_FOUND NOT_FOUND}. <code>fIndent</code> will contain
- * the relative indentation (in indentation units, not characters) after the call. If there is
- * a special alignment (e.g. for a method declaration where parameters should be aligned),
- * <code>fAlign</code> will contain the absolute position of the alignment reference
- * in <code>fDocument</code>, otherwise <code>fAlign</code> is set to
- * {@link STPHeuristicScanner#NOT_FOUND}.
- *
- * @param offset the offset for which the reference is computed
- * @param danglingElse whether a dangling else should be assumed at <code>position</code>
- * @param matchMode determines what kind of reference position should be returned.
- * See {@link MatchMode}.
- * @return the reference statement relative to which <code>position</code>
- * should be indented, or {@link STPHeuristicScanner#NOT_FOUND}
- */
- public int findReferencePosition(int offset, boolean danglingElse, MatchMode matchMode) {
- fIndent= 0; // The indentation modification
- fExtraSpaces= 0;
- fAlign= NOT_FOUND;
- fPosition= offset;
-
- // Forward cases.
- // An unindentation happens sometimes if the next token is special, namely on braces,
- // parens and case labels align braces, but handle the case where we align with the method
- // declaration start instead of the opening brace.
- switch (matchMode) {
- case MATCH_BRACE:
- if (skipScope(STPSymbols.TokenLBRACE, STPSymbols.TokenRBRACE)) {
- try {
- // Align with the opening brace that is on a line by its own
- int lineOffset= fDocument.getLineOffset(fLine);
- if (lineOffset <= fPosition &&
- fDocument.get(lineOffset, fPosition - lineOffset).trim().isEmpty()) {
- return fPosition;
- }
- } catch (BadLocationException e) {
- // Concurrent modification - walk default path
- }
- // If the opening brace is not on the start of the line, skip to the start.
- int pos= skipToStatementStart(true, true);
- fIndent= 0; // indent is aligned with reference position
- return pos;
- } else {
- // If we can't find the matching brace, the heuristic is to unindent
- // by one against the normal position
- int pos= findReferencePosition(offset, danglingElse, MatchMode.REGULAR);
- fIndent--;
- return pos;
- }
-
- case MATCH_PAREN:
- // Align parentheses.
- if (skipScope(STPSymbols.TokenLPAREN, STPSymbols.TokenRPAREN)) {
- return fPosition;
- } else {
- // If we can't find the matching paren, the heuristic is to unindent by one
- // against the normal position.
- int pos= findReferencePosition(offset, danglingElse, MatchMode.REGULAR);
- fIndent--;
- return pos;
- }
-
- case MATCH_CASE:
- // The only reliable way to get case labels aligned (due to many different styles of
- // using braces in a block) is to go for another case statement, or the scope opening
- // brace.
- return matchCaseAlignment();
-
- case MATCH_ACCESS_SPECIFIER:
- // The only reliable way to get access specifiers aligned (due to many different styles
- // of using braces in a block) is to go for another access specifier, or the scope
- // opening brace.
- return matchAccessSpecifierAlignment();
-
- case MATCH_TYPE_DECLARATION:
- return matchTypeDeclaration();
-
- case REGULAR:
- break;
- }
-
- if (peekToken(offset) == STPSymbols.TokenCOLON) {
- int pos= fPosition;
- if (looksLikeTypeInheritanceDecl()) {
- fIndent = fPrefs.prefContinuationIndent;
- return fPosition;
- }
- fPosition = pos;
- }
-
- nextToken();
- // Skip access specifiers
- while (fToken == STPSymbols.TokenCOLON && isAccessSpecifier()) {
- nextToken();
- }
-
- int line= fLine;
- switch (fToken) {
- case STPSymbols.TokenGREATERTHAN:
- case STPSymbols.TokenRBRACE:
- // Skip the block and fall through.
- // If we can't complete the scope, reset the scan position
- int pos= fPosition;
- if (!skipScope())
- fPosition= pos;
- return skipToStatementStart(danglingElse, false);
-
- case STPSymbols.TokenSEMICOLON:
- // This is the 90% case: after a statement block
- // the end of the previous statement / block previous.end
- // search to the end of the statement / block before the previous;
- // the token just after that is previous.start
- return skipToStatementStart(danglingElse, false);
-
- // Scope introduction: special treat who special is
- case STPSymbols.TokenLPAREN:
- case STPSymbols.TokenLBRACE:
- case STPSymbols.TokenLBRACKET:
- return handleScopeIntroduction(Math.min(offset + 1, fDocument.getLength()), true);
-
- case STPSymbols.TokenEOF:
- // trap when hitting start of document
- return NOT_FOUND;
-
- case STPSymbols.TokenEQUAL:
- // indent assignments, but don't do so if there is a String
- // after the assignment because SystemTap doesn't require
- // semi-colons to end lines and so this should be treated as
- // a complete assignment.
- pos = fPosition;
- while (pos < offset) {
- try {
- ITypedRegion partition = ((IDocumentExtension3)fDocument).getPartition(STPPartitionScanner.STP_PARTITIONING, pos, danglingElse);
- if (STPPartitionScanner.STP_STRING.equals(partition.getType()))
- return skipToStatementStart(danglingElse, false);
- pos = partition.getOffset() + partition.getLength();
- } catch (BadLocationException e) {
- break;
- } catch (BadPartitioningException e) {
- break;
- }
- }
- fIndent= fPrefs.prefAssignmentIndent;
- return fPosition;
- case STPSymbols.TokenCOLON:
- pos= fPosition;
- if (looksLikeCaseStatement()) {
- fIndent= fPrefs.prefCaseBlockIndent;
- return pos;
- }
- fPosition= pos;
- if (looksLikeTypeInheritanceDecl()) {
- fIndent= fPrefs.prefContinuationIndent;
- return pos;
- }
- fPosition= pos;
- if (looksLikeConstructorInitializer()) {
- fIndent= fPrefs.prefBlockIndent;
- return pos;
- }
- fPosition= pos;
- if (isConditional()) {
- fPosition= offset;
- fLine= line;
- return skipToPreviousListItemOrListStart();
- }
- fPosition= pos;
- return skipToPreviousListItemOrListStart();
-
- case STPSymbols.TokenQUESTIONMARK:
- if (fPrefs.prefTernaryDeepAlign) {
- setFirstElementAlignment(fPosition, offset + 1);
- } else {
- fIndent= fPrefs.prefTernaryIndent;
- }
- return fPosition;
-
- // Indentation for blockless introducers:
- case STPSymbols.TokenDO:
- case STPSymbols.TokenWHILE:
- case STPSymbols.TokenELSE:
- fIndent= fPrefs.prefSimpleIndent;
- return fPosition;
-
- case STPSymbols.TokenTRY:
- return skipToStatementStart(danglingElse, false);
-
- case STPSymbols.TokenRETURN:
- case STPSymbols.TokenTYPEDEF:
- case STPSymbols.TokenUSING:
- fIndent = fPrefs.prefContinuationIndent;
- return fPosition;
-
- case STPSymbols.TokenCONST:
- nextToken();
- if (fToken != STPSymbols.TokenRPAREN) {
- return skipToPreviousListItemOrListStart();
- }
- // could be const method decl
- //$FALL-THROUGH$
- case STPSymbols.TokenRPAREN:
- if (skipScope(STPSymbols.TokenLPAREN, STPSymbols.TokenRPAREN)) {
- int scope= fPosition;
- nextToken();
- if (fToken == STPSymbols.TokenIF || fToken == STPSymbols.TokenWHILE || fToken == STPSymbols.TokenFOR
- || fToken == STPSymbols.TokenFOREACH) {
- fIndent= fPrefs.prefSimpleIndent;
- return fPosition;
- }
- if (fToken == STPSymbols.TokenSWITCH) {
- return fPosition;
- }
- fPosition= scope;
- if (looksLikeMethodDecl()) {
- return skipToStatementStart(danglingElse, false);
- }
- if (fToken == STPSymbols.TokenCATCH) {
- return skipToStatementStart(danglingElse, false);
- }
- fPosition= scope;
- if (looksLikeAnonymousTypeDecl()) {
- return skipToStatementStart(danglingElse, false);
- }
- }
- // restore
- fPosition= offset;
- fLine= line;
- // else: fall through to default
- return skipToPreviousListItemOrListStart();
-
- case STPSymbols.TokenCOMMA:
- // Inside a list of some type.
- // Easy if there is already a list item before with its own indentation - we just align.
- // If not: take the start of the list (LPAREN, LBRACE, LBRACKET) and either align or
- // indent by list-indent.
- return skipToPreviousListItemOrListStart();
-
- case STPSymbols.TokenPLUS:
- case STPSymbols.TokenMINUS:
- case STPSymbols.TokenLESSTHAN:
- case STPSymbols.TokenAGGREGATE:
- case STPSymbols.TokenSHIFTRIGHT:
- case STPSymbols.TokenSHIFTLEFT:
- case STPSymbols.TokenOTHER:
- // Math symbol, use skipToPreviousListItemOrListStart.
- return skipToPreviousListItemOrListStart();
- // Otherwise, fall-through
- default:
- // Inside whatever we don't know about:
- // C would treat this as a list, but in SystemTap we might just have a line that doesn't
- // end in a semi-colon. We want to indent to the same level as the statement.
- return skipToStatementStart(danglingElse, false);
- }
- }
-
- /**
- * Test whether an identifier encountered during scanning is part of
- * a type declaration, by scanning backward and ignoring any identifiers, commas,
- * and colons until we hit <code>class</code>, <code>struct</code>, <code>union</code>,
- * or <code>enum</code>. If any braces, semicolons, or parentheses are encountered,
- * this is not a type declaration.
- * @return the reference offset of the start of the statement
- */
- private int matchTypeDeclaration() {
- while (true) {
- nextToken();
- if (fToken == STPSymbols.TokenIDENT
- || fToken == STPSymbols.TokenCOMMA
- || fToken == STPSymbols.TokenCOLON
- || fToken == STPSymbols.TokenPUBLIC
- || fToken == STPSymbols.TokenPROTECTED
- || fToken == STPSymbols.TokenPRIVATE) {
- continue;
- }
- if (fToken == STPSymbols.TokenCLASS
- || fToken == STPSymbols.TokenSTRUCT
- || fToken == STPSymbols.TokenUNION) {
- // inside a type declaration? Only so if not preceded by '(' or ',' as in
- // a parameter list. To be safe, only accept ';' or EOF
- int pos= fPosition;
- nextToken();
- if (fToken == STPSymbols.TokenSEMICOLON || fToken == STPSymbols.TokenEOF) {
- return pos;
- } else {
- return NOT_FOUND;
- }
- } else {
- return NOT_FOUND;
- }
- }
- }
-
- /**
- * Test whether the colon at the current position marks a case statement
- *
- * @return <code>true</code> if this looks like a case statement
- */
- private boolean looksLikeCaseStatement() {
- nextToken();
- switch (fToken) {
- case STPSymbols.TokenCASE:
- // char literal got skipped
- return true;
- case STPSymbols.TokenIDENT:
- nextToken();
- while (skipQualifiers()) {
- nextToken();
- }
- while (fToken == STPSymbols.TokenMINUS || fToken == STPSymbols.TokenPLUS) {
- nextToken();
- }
- if (fToken == STPSymbols.TokenCASE) {
- return true;
- }
- break;
- case STPSymbols.TokenOTHER:
- nextToken();
- if (fToken == STPSymbols.TokenCASE) {
- return true;
- }
- break;
- case STPSymbols.TokenDEFAULT:
- return true;
- }
- return false;
- }
-
- /**
- * Test whether the colon at the current position marks a type inheritance decl.
- *
- * @return <code>true</code> if this looks like a type inheritance decl.
- */
- private boolean looksLikeTypeInheritanceDecl() {
- nextToken();
- switch (fToken) {
- case STPSymbols.TokenIDENT:
- nextToken();
- while (skipQualifiers()) {
- nextToken();
- }
- switch (fToken) {
- case STPSymbols.TokenCLASS:
- case STPSymbols.TokenSTRUCT:
- case STPSymbols.TokenUNION:
- return true;
- }
- break;
- }
- return false;
- }
-
- /**
- * Test whether the colon at the current position marks a constructor initializer list.
- *
- * @return <code>true</code> if this looks like a constructor initializer list.
- */
- private boolean looksLikeConstructorInitializer() {
- nextToken();
- if (fToken != STPSymbols.TokenRPAREN) {
- return false;
- }
- if (!skipScope()) {
- return false;
- }
- nextToken();
- if (fToken == STPSymbols.TokenTHROW) {
- nextToken();
- if (fToken != STPSymbols.TokenRPAREN) {
- return false;
- }
- if (!skipScope()) {
- return false;
- }
- nextToken();
- }
- if (fToken != STPSymbols.TokenIDENT) {
- return false;
- }
- nextToken();
- switch (fToken) {
- case STPSymbols.TokenCOLON:
- nextToken();
- switch (fToken) {
- case STPSymbols.TokenCOLON: // A::A() :
- case STPSymbols.TokenPUBLIC: // public: A() :
- case STPSymbols.TokenPROTECTED:
- case STPSymbols.TokenPRIVATE:
- return true;
- }
- return false;
-
- case STPSymbols.TokenLBRACE: // class A { A() :
- case STPSymbols.TokenRBRACE:
- case STPSymbols.TokenSEMICOLON:
- return true;
- }
- return false;
- }
-
- /**
- * Test whether the left brace at the current position marks an enum decl.
- *
- * @return <code>true</code> if this looks like an enum decl.
- */
- private boolean looksLikeEnumDeclaration() {
- int pos = fPosition;
- nextToken();
- if (fToken == STPSymbols.TokenIDENT) {
- nextToken();
- while (skipQualifiers()) {
- nextToken();
- }
- }
- if (fToken == STPSymbols.TokenENUM) {
- fPosition = pos;
- return true;
- }
- fPosition = pos;
- return false;
- }
-
-
- /**
- * Test whether the colon at the current position marks an access specifier.
- *
- * @return <code>true</code> if current position marks an access specifier
- */
- private boolean isAccessSpecifier() {
- int pos= fPosition;
- int token = fToken;
- nextToken();
- switch (fToken) {
- case STPSymbols.TokenPUBLIC:
- case STPSymbols.TokenPROTECTED:
- case STPSymbols.TokenPRIVATE:
- return true;
- }
- fToken = token;
- fPosition= pos;
- return false;
- }
-
- /**
- * Skips to the start of a statement that ends at the current position.
- *
- * @param danglingElse whether to indent aligned with the last <code>if</code>
- * @param isInBlock whether the current position is inside a block, which limits the search scope to
- * the next scope introducer
- * @return the reference offset of the start of the statement
- */
- private int skipToStatementStart(boolean danglingElse, boolean isInBlock) {
- final int NOTHING= 0;
- final int READ_PARENS= 1;
- final int READ_IDENT= 2;
- int mayBeMethodBody= NOTHING;
- boolean isTypeBody= false;
- int startLine = fLine;
- while (true) {
- int prevToken= fToken;
- nextToken();
-
- if (isInBlock) {
- switch (fToken) {
- // exit on all block introducers
- case STPSymbols.TokenIF:
- case STPSymbols.TokenELSE:
- case STPSymbols.TokenCATCH:
- case STPSymbols.TokenDO:
- case STPSymbols.TokenWHILE:
- case STPSymbols.TokenFOR:
- case STPSymbols.TokenFOREACH:
- case STPSymbols.TokenTRY:
- fIndent += fPrefs.prefIndentBracesForBlocks ? 1 : 0;
- return fPosition;
- case STPSymbols.TokenCLASS:
- case STPSymbols.TokenSTRUCT:
- case STPSymbols.TokenUNION:
- isTypeBody= true;
- break;
-
- case STPSymbols.TokenSWITCH:
- fIndent= fPrefs.prefCaseIndent;
- return fPosition;
- }
- }
-
- if (fToken == STPSymbols.TokenSEMICOLON && fLine == startLine) {
- // Skip semicolons on the same line. Otherwise we may never reach beginning of a 'for'
- // statement.
- continue;
- }
-
- switch (fToken) {
- // scope introduction through: LPAREN, LBRACE, LBRACKET
- // search stop on SEMICOLON, RBRACE, COLON, EOF
- // -> the next token is the start of the statement (i.e. previousPos when backward scanning)
- case STPSymbols.TokenLPAREN:
- if (peekToken() == STPSymbols.TokenFOR) {
- nextToken(); // Consume 'for'
- fIndent = fPrefs.prefContinuationIndent;
- return fPosition;
- }
- break;
-
- case STPSymbols.TokenLBRACE:
- case STPSymbols.TokenSEMICOLON:
- case STPSymbols.TokenEOF:
- if (isInBlock)
- fIndent= getBlockIndent(mayBeMethodBody == READ_IDENT, isTypeBody);
- return fPreviousPos;
-
- case STPSymbols.TokenCOLON:
- switch (prevToken) {
- case STPSymbols.TokenPRIVATE:
- case STPSymbols.TokenPROTECTED:
- case STPSymbols.TokenPUBLIC:
- continue; // Don't stop at colon in a class declaration
-
- case STPSymbols.TokenVIRTUAL:
- switch (peekToken()) {
- case STPSymbols.TokenPRIVATE:
- case STPSymbols.TokenPROTECTED:
- case STPSymbols.TokenPUBLIC:
- break;
- default:
- continue;
- }
- }
- int pos= fPreviousPos;
- if (!isConditional())
- return pos;
- break;
-
- case STPSymbols.TokenRBRACE:
- // RBRACE is a little tricky: it can be the end of an array definition, but
- // usually it is the end of a previous block
- pos= fPreviousPos; // store state
- if (skipScope()) {
- if (looksLikeArrayInitializerIntro()) {
- continue; // it's an array
- }
- if (prevToken == STPSymbols.TokenSEMICOLON) {
- // end of type def
- continue;
- }
- }
- if (isInBlock)
- fIndent= getBlockIndent(mayBeMethodBody == READ_IDENT, isTypeBody);
- return pos; // it's not - do as with all the above
-
- // scopes: skip them
- case STPSymbols.TokenRPAREN:
- if (isInBlock)
- mayBeMethodBody= READ_PARENS;
- // fall thru
- pos= fPreviousPos;
- if (skipScope())
- break;
- else
- return pos;
- case STPSymbols.TokenRBRACKET:
- pos= fPreviousPos;
- if (skipScope())
- break;
- else
- return pos;
-
- // IF / ELSE: align the position after the conditional block with the if
- // so we are ready for an else, except if danglingElse is false
- // in order for this to work, we must skip an else to its if
- case STPSymbols.TokenIF:
- if (danglingElse)
- return fPosition;
- else
- break;
- case STPSymbols.TokenELSE:
- // skip behind the next if, as we have that one covered
- pos= fPosition;
- if (skipNextIF())
- break;
- else
- return pos;
-
- case STPSymbols.TokenDO:
- // align the WHILE position with its do
- return fPosition;
-
- case STPSymbols.TokenWHILE:
- // this one is tricky: while can be the start of a while loop
- // or the end of a do - while
- pos= fPosition;
- if (hasMatchingDo()) {
- // continue searching from the DO on
- break;
- } else {
- // continue searching from the WHILE on
- fPosition= pos;
- break;
- }
- case STPSymbols.TokenIDENT:
- if (mayBeMethodBody == READ_PARENS)
- mayBeMethodBody= READ_IDENT;
- break;
-
- default:
- // keep searching
- }
- }
- }
-
- private int getBlockIndent(boolean isMethodBody, boolean isTypeBody) {
- if (isTypeBody) {
- return fPrefs.prefTypeIndent + fPrefs.prefAccessSpecifierIndent;
- } else if (isMethodBody) {
- return fPrefs.prefMethodBodyIndent + (fPrefs.prefIndentBracesForMethods ? 1 : 0);
- } else {
- return fIndent;
- }
- }
-
- /**
- * Returns <code>true</code> if the colon at the current position is part of a conditional
- * (ternary) expression, <code>false</code> otherwise.
- *
- * @return <code>true</code> if the colon at the current position is part of a conditional
- */
- private boolean isConditional() {
- while (true) {
- int previous= fToken;
- nextToken();
- switch (fToken) {
- // search for case labels, which consist of (possibly qualified) identifiers or numbers
- case STPSymbols.TokenIDENT:
- if (previous == STPSymbols.TokenIDENT) {
- return false;
- }
- // fall thru
- continue;
- case STPSymbols.TokenDOUBLECOLON:
- case STPSymbols.TokenOTHER:
- case STPSymbols.TokenMINUS:
- case STPSymbols.TokenPLUS:
- continue;
-
- case STPSymbols.TokenQUESTIONMARK:
- return true;
-
- case STPSymbols.TokenSEMICOLON:
- case STPSymbols.TokenLBRACE:
- case STPSymbols.TokenRBRACE:
- case STPSymbols.TokenCASE:
- case STPSymbols.TokenDEFAULT:
- case STPSymbols.TokenPUBLIC:
- case STPSymbols.TokenPROTECTED:
- case STPSymbols.TokenPRIVATE:
- case STPSymbols.TokenCLASS:
- case STPSymbols.TokenSTRUCT:
- case STPSymbols.TokenUNION:
- return false;
-
- default:
- return true;
- }
- }
- }
-
- /**
- * Returns as a reference any previous <code>switch</code> labels (<code>case</code>
- * or <code>default</code>) or the offset of the brace that scopes the switch
- * statement. Sets <code>fIndent</code> to <code>prefCaseIndent</code> upon
- * a match.
- *
- * @return the reference offset for a <code>switch</code> label
- */
- private int matchCaseAlignment() {
- while (true) {
- nextToken();
- switch (fToken) {
- // invalid cases: another case label or an LBRACE must come before a case
- // -> bail out with the current position
- case STPSymbols.TokenLPAREN:
- case STPSymbols.TokenLBRACKET:
- case STPSymbols.TokenEOF:
- return fPosition;
-
- case STPSymbols.TokenSWITCH:
- // start of switch statement
- fIndent= fPrefs.prefCaseIndent;
- return fPosition;
-
- case STPSymbols.TokenCASE:
- case STPSymbols.TokenDEFAULT:
- // align with previous label
- fIndent= 0;
- return fPosition;
-
- // scopes: skip them
- case STPSymbols.TokenRPAREN:
- case STPSymbols.TokenRBRACKET:
- case STPSymbols.TokenRBRACE:
- skipScope();
- break;
-
- default:
- // keep searching
- continue;
- }
- }
- }
-
- /**
- * Returns as a reference any previous access specifiers (<code>public</code>,
- * <code>protected</code> or <code>default</code>) or the offset of the brace that
- * scopes the class body.
- * Sets <code>fIndent</code> to <code>prefAccessSpecifierIndent</code> upon
- * a match.
- *
- * @return the reference offset for an access specifier (public/protected/private)
- */
- private int matchAccessSpecifierAlignment() {
- while (true) {
- nextToken();
- switch (fToken) {
- // invalid cases: another access specifier or an LBRACE must come before an access specifier
- // -> bail out with the current position
- case STPSymbols.TokenLPAREN:
- case STPSymbols.TokenLBRACKET:
- case STPSymbols.TokenEOF:
- return fPosition;
-
- case STPSymbols.TokenLBRACE:
- // opening brace of class body
- int pos= fPosition;
- int typeDeclPos= matchTypeDeclaration();
- fIndent= fPrefs.prefAccessSpecifierIndent;
- fExtraSpaces = fPrefs.prefAccessSpecifierExtraSpaces;
- if (typeDeclPos != NOT_FOUND) {
- return typeDeclPos;
- }
- return pos;
- case STPSymbols.TokenPUBLIC:
- case STPSymbols.TokenPROTECTED:
- case STPSymbols.TokenPRIVATE:
- // align with previous access specifier
- fIndent= 0;
- return fPosition;
-
- // scopes: skip them
- case STPSymbols.TokenRPAREN:
- case STPSymbols.TokenRBRACKET:
- case STPSymbols.TokenRBRACE:
- skipScope();
- break;
-
- default:
- // keep searching
- continue;
- }
- }
- }
-
- /**
- * Returns the reference position for a list element. The algorithm
- * tries to match any previous indentation on the same list. If there is none,
- * the reference position returned is determined depending on the type of list:
- * The indentation will either match the list scope introducer (e.g. for
- * method declarations), so called deep indents, or simply increase the
- * indentation by a number of standard indents. See also {@link #handleScopeIntroduction(int, boolean)}.
- * @return the reference position for a list item: either a previous list item
- * that has its own indentation, or the list introduction start.
- */
- private int skipToPreviousListItemOrListStart() {
- int startLine= fLine;
- int startPosition= fPosition;
- int linesSkippedInsideScopes = 0;
- boolean continuationLineCandidate =
- fToken == STPSymbols.TokenEQUAL || fToken == STPSymbols.TokenSHIFTLEFT ||
- fToken == STPSymbols.TokenRPAREN;
- while (true) {
- int previous = fToken;
- nextToken();
-
- // If any line item comes with its own indentation, adapt to it
- if (fLine < startLine - linesSkippedInsideScopes) {
- try {
- int lineOffset= fDocument.getLineOffset(startLine);
- int bound= Math.min(fDocument.getLength(), startPosition + 1);
- if ((fToken == STPSymbols.TokenSEMICOLON || fToken == STPSymbols.TokenRBRACE || fToken == STPSymbols.TokenIDENT ||
- fToken == STPSymbols.TokenLBRACE && !looksLikeArrayInitializerIntro() && !looksLikeEnumDeclaration()) &&
- continuationLineCandidate) {
- fIndent = fPrefs.prefContinuationIndent;
- } else {
- fAlign= fScanner.findNonWhitespaceForwardInAnyPartition(lineOffset, bound);
- // If the reference line starts with a colon, skip the colon.
- if (peekToken(fAlign) == STPSymbols.TokenCOLON) {
- fAlign= fScanner.findNonWhitespaceForwardInAnyPartition(fAlign + 1, bound);
- }
- }
- } catch (BadLocationException e) {
- // Ignore and return just the position
- }
- return startPosition;
- }
-
- int line = fLine;
- switch (fToken) {
- // scopes: skip them
- case STPSymbols.TokenRPAREN:
- continuationLineCandidate = true;
- //$FALL-THROUGH$
- case STPSymbols.TokenRBRACKET:
- case STPSymbols.TokenRBRACE:
- skipScope();
- linesSkippedInsideScopes = line - fLine;
- break;
-
- // scope introduction: special treat who special is
- case STPSymbols.TokenLPAREN:
- case STPSymbols.TokenLBRACE:
- case STPSymbols.TokenLBRACKET:
- return handleScopeIntroduction(startPosition + 1, false);
-
- case STPSymbols.TokenSEMICOLON:
- return fPosition;
-
- case STPSymbols.TokenQUESTIONMARK:
- if (fPrefs.prefTernaryDeepAlign) {
- setFirstElementAlignment(fPosition - 1, fPosition + 1);
- } else {
- fIndent= fPrefs.prefTernaryIndent;
- }
- return fPosition;
-
- case STPSymbols.TokenEQUAL:
- case STPSymbols.TokenSHIFTLEFT:
- continuationLineCandidate = true;
- break;
-
- case STPSymbols.TokenRETURN:
- case STPSymbols.TokenUSING:
- fIndent = fPrefs.prefContinuationIndent;
- return fPosition;
-
- case STPSymbols.TokenTYPEDEF:
- switch (previous) {
- case STPSymbols.TokenSTRUCT:
- case STPSymbols.TokenUNION:
- case STPSymbols.TokenCLASS:
- case STPSymbols.TokenENUM:
- break;
- default:
- fIndent = fPrefs.prefContinuationIndent;
- }
- return fPosition;
-
- case STPSymbols.TokenEOF:
- if (continuationLineCandidate) {
- fIndent = fPrefs.prefContinuationIndent;
- }
- return 0;
- }
- }
- }
-
- /**
- * Skips a scope and positions the cursor (<code>fPosition</code>) on the
- * token that opens the scope. Returns <code>true</code> if a matching peer
- * could be found, <code>false</code> otherwise. The current token when calling
- * must be one out of <code>STPSymbols.TokenRPAREN</code>, <code>STPSymbols.TokenRBRACE</code>,
- * and <code>STPSymbols.TokenRBRACKET</code>.
- *
- * @return <code>true</code> if a matching peer was found, <code>false</code> otherwise
- */
- private boolean skipScope() {
- switch (fToken) {
- case STPSymbols.TokenRPAREN:
- return skipScope(STPSymbols.TokenLPAREN, STPSymbols.TokenRPAREN);
- case STPSymbols.TokenRBRACKET:
- return skipScope(STPSymbols.TokenLBRACKET, STPSymbols.TokenRBRACKET);
- case STPSymbols.TokenRBRACE:
- return skipScope(STPSymbols.TokenLBRACE, STPSymbols.TokenRBRACE);
- case STPSymbols.TokenGREATERTHAN:
- if (!fPrefs.prefHasTemplates)
- return false;
- int storedPosition= fPosition;
- int storedToken= fToken;
- nextToken();
- switch (fToken) {
- case STPSymbols.TokenIDENT:
- fPosition = storedPosition;
- if (skipScope(STPSymbols.TokenLESSTHAN, STPSymbols.TokenGREATERTHAN))
- return true;
- break;
- case STPSymbols.TokenQUESTIONMARK:
- case STPSymbols.TokenGREATERTHAN:
- fPosition = storedPosition;
- if (skipScope(STPSymbols.TokenLESSTHAN, STPSymbols.TokenGREATERTHAN))
- return true;
- break;
- }
- // <> are harder to detect - restore the position if we fail
- fPosition= storedPosition;
- fToken= storedToken;
- return false;
-
- default:
- // programming error
- Assert.isTrue(false);
- return false;
- }
- }
-
- /**
- * Returns the contents of the current token.
- *
- * @return the contents of the current token
- */
- private CharSequence getTokenContent() {
- return new DocumentCharacterIterator(fDocument, fPosition, fPreviousPos);
- }
-
- /**
- * Handles the introduction of a new scope. The current token must be one out
- * of <code>STPSymbols.TokenLPAREN</code>, <code>STPSymbols.TokenLBRACE</code>,
- * and <code>STPSymbols.TokenLBRACKET</code>. Returns as the reference position
- * either the token introducing the scope or - if available - the first
- * token after that.
- *
- * <p>Depending on the type of scope introduction, the indentation will align
- * (deep indenting) with the reference position (<code>fAlign</code> will be
- * set to the reference position) or <code>fIndent</code> will be set to
- * the number of indentation units.
- * </p>
- *
- * @param bound the bound for the search for the first token after the scope
- * introduction.
- * @param firstToken <code>true</code> if we are dealing with the first token after
- * the opening parenthesis.
- * @return the indent
- */
- private int handleScopeIntroduction(int bound, boolean firstToken) {
- int pos= fPosition; // store
-
- switch (fToken) {
- // scope introduction: special treat who special is
- case STPSymbols.TokenLPAREN:
- // special: method declaration deep indentation
- if (looksLikeMethodDecl()) {
- if (firstToken ? fPrefs.prefMethodDeclFirstParameterDeepIndent : fPrefs.prefMethodDeclDeepIndent) {
- return setFirstElementAlignment(pos, bound);
- } else {
- fIndent= fPrefs.prefMethodDeclIndent;
- return pos;
- }
- } else {
- fPosition= pos;
- if (looksLikeMethodCall()) {
- if (firstToken ? fPrefs.prefMethodCallFirstParameterDeepIndent : fPrefs.prefMethodCallDeepIndent) {
- return setFirstElementAlignment(pos, bound);
- } else {
- fIndent= fPrefs.prefMethodCallIndent;
- return pos;
- }
- } else if (fPrefs.prefParenthesisDeepIndent) {
- return setFirstElementAlignment(pos, bound);
- }
- }
-
- // normal: return the parenthesis as reference
- fIndent= fPrefs.prefParenthesisIndent;
- return pos;
-
- case STPSymbols.TokenLBRACE:
- final boolean looksLikeArrayInitializerIntro= looksLikeArrayInitializerIntro();
- // special: array initializer
- if (looksLikeArrayInitializerIntro) {
- if (fPrefs.prefArrayDeepIndent)
- return setFirstElementAlignment(pos, bound);
- else
- fIndent= fPrefs.prefArrayIndent;
- } else if (isNamespace() || isLinkageSpec()) {
- fIndent= fPrefs.prefNamespaceBodyIndent;
- } else if (looksLikeEnumDeclaration()) {
- fIndent = fPrefs.prefTypeIndent;
- } else {
- int typeDeclPos = matchTypeDeclaration();
- if (typeDeclPos == NOT_FOUND) {
- fIndent= fPrefs.prefBlockIndent;
- } else {
- fIndent= fPrefs.prefAccessSpecifierIndent + fPrefs.prefTypeIndent;
- }
- }
-
- // normal: skip to the statement start before the scope introducer
- // opening braces are often on differently ending indents than e.g. a method definition
- if (!looksLikeArrayInitializerIntro) {
- fPosition= pos; // restore
- return skipToStatementStart(true, true); // set to true to match the first if
- } else {
- return pos;
- }
-
- case STPSymbols.TokenLBRACKET:
- // special: method declaration deep indentation
- if (fPrefs.prefArrayDimensionsDeepIndent) {
- return setFirstElementAlignment(pos, bound);
- }
-
- // normal: return the bracket as reference
- fIndent= fPrefs.prefBracketIndent;
- return pos; // restore
-
- default:
- // programming error
- Assert.isTrue(false);
- return -1; // dummy
- }
- }
-
- /**
- * Sets the deep indent offset (<code>fAlign</code>) to either the offset
- * right after <code>scopeIntroducerOffset</code> or - if available - the
- * first C token after <code>scopeIntroducerOffset</code>, but before
- * <code>bound</code>.
- *
- * @param scopeIntroducerOffset the offset of the scope introducer
- * @param bound the bound for the search for another element
- * @return the reference position
- */
- private int setFirstElementAlignment(int scopeIntroducerOffset, int bound) {
- int firstPossible= scopeIntroducerOffset + 1; // align with the first position after the scope intro
- fAlign= fScanner.findNonWhitespaceForwardInAnyPartition(firstPossible, bound);
- if (fAlign == NOT_FOUND) {
- fAlign= firstPossible;
- } else {
- try {
- IRegion lineRegion = fDocument.getLineInformationOfOffset(scopeIntroducerOffset);
- if (fAlign > lineRegion.getOffset() + lineRegion.getLength()) {
- fAlign= firstPossible;
- }
- } catch (BadLocationException e) {
- // Ignore.
- }
- }
- return fAlign;
- }
-
- /**
- * Returns <code>true</code> if the next token received after calling
- * <code>nextToken</code> is either an equal sign, an opening brace,
- * a comma or an array designator ('[]').
- *
- * @return <code>true</code> if the next elements look like the start of an array definition
- */
- private boolean looksLikeArrayInitializerIntro() {
- int pos= fPosition;
- nextToken();
- switch (fToken) {
- case STPSymbols.TokenEQUAL:
- return true;
- case STPSymbols.TokenRBRACKET:
- return skipBrackets();
- case STPSymbols.TokenLBRACE:
- if (looksLikeArrayInitializerIntro()) {
- fPosition= pos;
- return true;
- }
- return false;
- case STPSymbols.TokenCOMMA:
- fPosition= pos;
- return true;
- }
- fPosition= pos;
- return false;
- }
-
- /**
- * Returns <code>true</code> if the the current token is "namespace", or the current token
- * is an identifier and the previous token is "namespace".
- *
- * @return <code>true</code> if the next elements look like the start of a namespace declaration.
- */
- private boolean isNamespace() {
- int pos = fPosition;
- nextToken();
- if (fToken == STPSymbols.TokenNAMESPACE) {
- fPosition = pos;
- return true; // Anonymous namespace
- } else if (fToken == STPSymbols.TokenIDENT) {
- nextToken(); // Get previous token
- if (fToken == STPSymbols.TokenNAMESPACE) {
- fPosition = pos;
- return true; // Named namespace
- }
- }
- fPosition = pos;
- return false;
- }
-
- /**
- * Returns <code>true</code> if the current token is keyword "extern".
- *
- * @return <code>true</code> if the next elements look like the start of a linkage spec.
- */
- private boolean isLinkageSpec() {
- int pos = fPosition;
- nextToken();
- if (fToken == STPSymbols.TokenEXTERN) {
- fPosition = pos;
- return true;
- }
- fPosition = pos;
- return false;
- }
-
- /**
- * Skips over the next <code>if</code> keyword. The current token when calling
- * this method must be an <code>else</code> keyword. Returns <code>true</code>
- * if a matching <code>if</code> could be found, <code>false</code> otherwise.
- * The cursor (<code>fPosition</code>) is set to the offset of the <code>if</code>
- * token.
- *
- * @return <code>true</code> if a matching <code>if</code> token was found, <code>false</code> otherwise
- */
- private boolean skipNextIF() {
- Assert.isTrue(fToken == STPSymbols.TokenELSE);
-
- while (true) {
- nextToken();
- switch (fToken) {
- // scopes: skip them
- case STPSymbols.TokenRPAREN:
- case STPSymbols.TokenRBRACKET:
- case STPSymbols.TokenRBRACE:
- skipScope();
- break;
-
- case STPSymbols.TokenIF:
- // found it, return
- return true;
- case STPSymbols.TokenELSE:
- // recursively skip else-if blocks
- skipNextIF();
- break;
-
- // shortcut scope starts
- case STPSymbols.TokenLPAREN:
- case STPSymbols.TokenLBRACE:
- case STPSymbols.TokenLBRACKET:
- case STPSymbols.TokenEOF:
- return false;
- }
- }
- }
-
- /**
- * while(condition); is ambiguous when parsed backwardly, as it is a valid
- * statement by its own, so we have to check whether there is a matching
- * do. A <code>do</code> can either be separated from the while by a
- * block, or by a single statement, which limits our search distance.
- *
- * @return <code>true</code> if the <code>while</code> currently in
- * <code>fToken</code> has a matching <code>do</code>.
- */
- private boolean hasMatchingDo() {
- Assert.isTrue(fToken == STPSymbols.TokenWHILE);
- nextToken();
- switch (fToken) {
- case STPSymbols.TokenRBRACE:
- skipScope(); // and fall thru
- skipToStatementStart(false, false);
- return fToken == STPSymbols.TokenDO;
-
- case STPSymbols.TokenSEMICOLON:
- skipToStatementStart(false, false);
- return fToken == STPSymbols.TokenDO;
- }
- return false;
- }
-
- /**
- * Skips pointer operators if the current token is a pointer operator.
- *
- * @return <code>true</code> if a <code>*</code> or <code>&amp;</code> could be scanned, the
- * current token is left at the operator.
- */
- private boolean skipPointerOperators() {
- if (fToken == STPSymbols.TokenOTHER) {
- CharSequence token= getTokenContent().toString().trim();
- if (token.length() == 1 && token.charAt(0) == '*' || token.charAt(0) == '&') {
- return true;
- }
- } else if (fToken == STPSymbols.TokenCONST) {
- return true;
- }
- return false;
- }
-
- /**
- * Skips brackets if the current token is a RBRACKET. There can be nothing
- * but whitespace in between, this is only to be used for <code>[]</code> elements.
- *
- * @return <code>true</code> if a <code>[]</code> could be scanned, the
- * current token is left at the LBRACKET.
- */
- private boolean skipBrackets() {
- if (fToken == STPSymbols.TokenRBRACKET) {
- nextToken();
- if (fToken == STPSymbols.TokenLBRACKET) {
- return true;
- }
- }
- return false;
- }
-
- /**
- * Skips scope qualifiers of identifiers.
- *
- * @return <code>true</code> if a qualifier was encountered, the last token
- * will be an IDENT.
- */
- private boolean skipQualifiers() {
- if (fToken == STPSymbols.TokenDOUBLECOLON) {
- nextToken();
- if (fToken == STPSymbols.TokenIDENT) {
- return true;
- }
- }
- return false;
- }
-
- /**
- * Reads the next token in backward direction from the heuristic scanner
- * and sets the fields <code>fToken, fPreviousPosition</code> and <code>fPosition</code>
- * accordingly.
- */
- private void nextToken() {
- nextToken(fPosition);
- }
-
- /**
- * Reads the next token in backward direction of <code>start</code> from
- * the heuristic scanner and sets the fields <code>fToken, fPreviousPosition</code>
- * and <code>fPosition</code> accordingly.
- *
- * @param start the start offset from which to scan backwards
- */
- private void nextToken(int start) {
- fToken= fScanner.previousToken(start - 1, STPHeuristicScanner.UNBOUND);
- fPreviousPos= start;
- fPosition= fScanner.getPosition() + 1;
- try {
- fLine= fDocument.getLineOfOffset(fPosition);
- } catch (BadLocationException e) {
- fLine= -1;
- }
- }
-
- /**
- * Reads the next token in backward direction from the heuristic scanner
- * and returns that token without changing the current position.
- */
- private int peekToken() {
- return fScanner.previousToken(fPosition - 1, STPHeuristicScanner.UNBOUND);
- }
-
- /**
- * Returns <code>true</code> if the current tokens look like a method
- * declaration header (i.e. only the return type and method name). The
- * heuristic calls <code>nextToken</code> and expects an identifier
- * (method name) and an optional return type declaration.
- *
- * @return <code>true</code> if the current position looks like a method
- * declaration header.
- */
- private boolean looksLikeMethodDecl() {
- nextToken();
- switch (fToken) {
- case STPSymbols.TokenIDENT: // method name
- int pos= fPosition;
- nextToken();
- // check destructor tilde
- if (fToken == STPSymbols.TokenTILDE) {
- return true;
- }
- if (skipQualifiers()) {
- return true;
- }
- // optional brackets for array valued return types
- while (skipBrackets()) {
- nextToken();
- }
- while (skipPointerOperators()) {
- nextToken();
- }
- switch (fToken) {
- case STPSymbols.TokenIDENT:
- return true;
- case STPSymbols.TokenSEMICOLON:
- case STPSymbols.TokenRBRACE:
- fPosition= pos;
- return true;
- case STPSymbols.TokenLBRACE:
- if (fScanner.looksLikeCompositeTypeDefinitionBackward(fPosition, STPHeuristicScanner.UNBOUND)) {
- fPosition= pos;
- return true;
- }
- break;
- case STPSymbols.TokenCOMMA:
- nextToken();
- if (fToken == STPSymbols.TokenRPAREN) {
- // field initializer
- if (skipScope()) {
- return looksLikeMethodDecl();
- }
- }
- break;
- case STPSymbols.TokenCOLON:
- nextToken();
- switch (fToken) {
- case STPSymbols.TokenPUBLIC:
- case STPSymbols.TokenPROTECTED:
- case STPSymbols.TokenPRIVATE:
- fPosition= pos;
- return true;
- case STPSymbols.TokenRPAREN:
- // constructor initializer
- if (skipScope()) {
- pos = fPosition;
- nextToken();
- // optional throw
- if (fToken == STPSymbols.TokenTHROW) {
- nextToken();
- if (fToken != STPSymbols.TokenRPAREN || !skipScope()) {
- return false;
- }
- } else {
- fPosition = pos;
- }
- return looksLikeMethodDecl();
- }
- break;
- }
- }
- break;
- case STPSymbols.TokenARROW:
- case STPSymbols.TokenCOMMA:
- case STPSymbols.TokenEQUAL:
- case STPSymbols.TokenGREATERTHAN:
- case STPSymbols.TokenLESSTHAN:
- case STPSymbols.TokenMINUS:
- case STPSymbols.TokenPLUS:
- case STPSymbols.TokenSHIFTRIGHT:
- case STPSymbols.TokenSHIFTLEFT:
- case STPSymbols.TokenDELETE:
- case STPSymbols.TokenNEW:
- nextToken();
- return fToken == STPSymbols.TokenOPERATOR;
- case STPSymbols.TokenRPAREN:
- nextToken();
- if (fToken != STPSymbols.TokenLPAREN)
- return false;
- nextToken();
- return fToken == STPSymbols.TokenOPERATOR;
- case STPSymbols.TokenRBRACKET:
- nextToken();
- if (fToken != STPSymbols.TokenLBRACKET)
- return false;
- nextToken();
- if (fToken == STPSymbols.TokenNEW || fToken == STPSymbols.TokenDELETE)
- nextToken();
- return fToken == STPSymbols.TokenOPERATOR;
- case STPSymbols.TokenOTHER:
- if (getTokenContent().length() == 1) {
- nextToken();
- if (fToken == STPSymbols.TokenOPERATOR)
- return true;
- }
- if (getTokenContent().length() == 1) {
- nextToken();
- if (fToken == STPSymbols.TokenOPERATOR)
- return true;
- }
- }
- return false;
- }
-
- /**
- * Returns <code>true</code> if the current tokens look like an anonymous type declaration
- * header (i.e. a type name (potentially qualified) and a new keyword). The heuristic calls
- * <code>nextToken</code> and expects a possibly qualified identifier (type name) and a new
- * keyword
- *
- * @return <code>true</code> if the current position looks like a anonymous type declaration
- * header.
- */
- private boolean looksLikeAnonymousTypeDecl() {
- nextToken();
- if (fToken == STPSymbols.TokenIDENT) { // type name
- nextToken();
- while (fToken == STPSymbols.TokenOTHER) { // dot of qualification
- nextToken();
- if (fToken != STPSymbols.TokenIDENT) // qualifying name
- return false;
- nextToken();
- }
- return fToken == STPSymbols.TokenNEW;
- }
- return false;
- }
-
- /**
- * Returns <code>true</code> if the current tokens look like beginning of a method
- * call (i.e. an identifier as opposed to a keyword taking parenthesized parameters
- * such as <code>if</code>).
- * <p>The heuristic calls <code>nextToken</code> and expects an identifier
- * (method name).
- *
- * @return <code>true</code> if the current position looks like a method call
- * header.
- */
- private boolean looksLikeMethodCall() {
- nextToken();
- if (fToken == STPSymbols.TokenGREATERTHAN) {
- if (!skipScope())
- return false;
- nextToken();
- }
- return fToken == STPSymbols.TokenIDENT; // method name
- }
-
- /**
- * Scans tokens for the matching opening peer. The internal cursor
- * (<code>fPosition</code>) is set to the offset of the opening peer if found.
- *
- * @param openToken the opening peer token
- * @param closeToken the closing peer token
- * @return <code>true</code> if a matching token was found, <code>false</code>
- * otherwise
- */
- private boolean skipScope(int openToken, int closeToken) {
- int depth= 1;
-
- while (true) {
- nextToken();
-
- if (fToken == closeToken) {
- depth++;
- } else if (fToken == openToken) {
- depth--;
- if (depth == 0)
- return true;
- } else if (fToken == STPSymbols.TokenEOF) {
- return false;
- }
- }
- }
+ /**
+ * The CDT Core preferences.
+ */
+ private final class CorePrefs {
+ private final boolean prefUseTabs;
+ private final boolean prefArrayDimensionsDeepIndent;
+ private final int prefArrayIndent;
+ private final boolean prefArrayDeepIndent;
+ private final boolean prefTernaryDeepAlign;
+ private final int prefTernaryIndent;
+ private final int prefCaseIndent;
+ private final int prefCaseBlockIndent;
+ private final int prefAssignmentIndent;
+ private final int prefSimpleIndent;
+ private final int prefBracketIndent;
+ private final boolean prefMethodDeclDeepIndent;
+ private final boolean prefMethodDeclFirstParameterDeepIndent;
+ private final int prefMethodDeclIndent;
+ private final boolean prefMethodCallDeepIndent;
+ private final boolean prefMethodCallFirstParameterDeepIndent;
+ private final int prefMethodCallIndent;
+ private final boolean prefParenthesisDeepIndent;
+ private final int prefParenthesisIndent;
+ private final int prefBlockIndent;
+ private final int prefMethodBodyIndent;
+ private final int prefTypeIndent;
+ private final int prefAccessSpecifierIndent;
+ private final int prefAccessSpecifierExtraSpaces;
+ private final int prefNamespaceBodyIndent;
+ private final boolean prefIndentBracesForBlocks;
+ private final boolean prefIndentBracesForArrays;
+ private final boolean prefIndentBracesForMethods;
+ private final boolean prefIndentBracesForTypes;
+ private final int prefContinuationIndent;
+ private final boolean prefHasTemplates;
+ private final String prefTabChar;
+
+ private final IPreferencesService preferenceService;
+ private final IScopeContext[] preferenceContexts;
+
+ /**
+ * Returns the possibly project-specific core preference defined under <code>key</code>.
+ *
+ * @param key the key of the preference
+ * @return the value of the preference
+ */
+ private String getCoreFormatterOption(String key) {
+ return getCoreFormatterOption(key, null);
+ }
+
+ private String getCoreFormatterOption(String key, String defaultValue) {
+ return preferenceService.getString(IDEPlugin.PLUGIN_ID, key, defaultValue, preferenceContexts);
+ }
+
+ private int getCoreFormatterOption(String key, int defaultValue) {
+ return preferenceService.getInt(IDEPlugin.PLUGIN_ID, key, defaultValue, preferenceContexts);
+ }
+
+ CorePrefs(IProject project) {
+ preferenceService = Platform.getPreferencesService();
+ preferenceContexts = project != null ?
+ new IScopeContext[] { new ProjectScope(project.getProject()),
+ InstanceScope.INSTANCE, DefaultScope.INSTANCE } :
+ new IScopeContext[] { InstanceScope.INSTANCE, DefaultScope.INSTANCE };
+ prefUseTabs= prefUseTabs();
+ prefArrayDimensionsDeepIndent= prefArrayDimensionsDeepIndent();
+ prefContinuationIndent= prefContinuationIndent();
+ prefBlockIndent= prefBlockIndent();
+ prefArrayIndent= prefArrayIndent();
+ prefArrayDeepIndent= prefArrayDeepIndent();
+ prefTernaryDeepAlign= false;
+ prefTernaryIndent= prefContinuationIndent();
+ prefCaseIndent= prefCaseIndent();
+ prefCaseBlockIndent= prefCaseBlockIndent();
+ prefAssignmentIndent= prefAssignmentIndent();
+ prefIndentBracesForBlocks= prefIndentBracesForBlocks();
+ prefSimpleIndent= prefSimpleIndent();
+ prefBracketIndent= prefBracketIndent();
+ prefMethodDeclDeepIndent= prefMethodDeclDeepIndent();
+ prefMethodDeclFirstParameterDeepIndent= prefMethodDeclFirstParameterDeepIndent();
+ prefMethodDeclIndent= prefMethodDeclIndent();
+ prefMethodCallDeepIndent= prefMethodCallDeepIndent();
+ prefMethodCallFirstParameterDeepIndent= prefMethodCallFirstParameterDeepIndent();
+ prefMethodCallIndent= prefMethodCallIndent();
+ prefParenthesisDeepIndent= prefParenthesisDeepIndent();
+ prefParenthesisIndent= prefParenthesisIndent();
+ prefMethodBodyIndent= prefMethodBodyIndent();
+ prefTypeIndent= prefTypeIndent();
+ prefAccessSpecifierIndent= prefAccessSpecifierIndent();
+ prefAccessSpecifierExtraSpaces= prefAccessSpecifierExtraSpaces();
+ prefNamespaceBodyIndent= prefNamespaceBodyIndent();
+ prefIndentBracesForArrays= prefIndentBracesForArrays();
+ prefIndentBracesForMethods= prefIndentBracesForMethods();
+ prefIndentBracesForTypes= prefIndentBracesForTypes();
+ prefHasTemplates= hasTemplates();
+ prefTabChar= getCoreFormatterOption(STPDefaultCodeFormatterConstants.FORMATTER_TAB_CHAR);
+ }
+
+ private boolean prefUseTabs() {
+ return !IDEPlugin.SPACE.equals(getCoreFormatterOption(STPDefaultCodeFormatterConstants.FORMATTER_TAB_CHAR));
+ }
+
+ private boolean prefArrayDimensionsDeepIndent() {
+ return true; // sensible default, no formatter setting
+ }
+
+ private int prefArrayIndent() {
+ String option= getCoreFormatterOption(STPDefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_EXPRESSIONS_IN_INITIALIZER_LIST);
+ try {
+ if (STPDefaultCodeFormatterConstants.getIndentStyle(option) == STPDefaultCodeFormatterConstants.INDENT_BY_ONE)
+ return 1;
+ } catch (IllegalArgumentException e) {
+ // ignore and return default
+ }
+
+ return prefContinuationIndent(); // default
+ }
+
+ private boolean prefArrayDeepIndent() {
+ String option= getCoreFormatterOption(STPDefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_EXPRESSIONS_IN_INITIALIZER_LIST);
+ try {
+ return STPDefaultCodeFormatterConstants.getIndentStyle(option) == STPDefaultCodeFormatterConstants.INDENT_ON_COLUMN;
+ } catch (IllegalArgumentException e) {
+ // ignore and return default
+ }
+
+ return true;
+ }
+
+ private int prefCaseIndent() {
+ if (STPDefaultCodeFormatterConstants.TRUE.equals(getCoreFormatterOption(STPDefaultCodeFormatterConstants.FORMATTER_INDENT_SWITCHSTATEMENTS_COMPARE_TO_SWITCH)))
+ return 1;
+ else
+ return 0;
+ }
+
+ private int prefCaseBlockIndent() {
+ if (STPDefaultCodeFormatterConstants.TRUE.equals(getCoreFormatterOption(STPDefaultCodeFormatterConstants.FORMATTER_INDENT_SWITCHSTATEMENTS_COMPARE_TO_CASES)))
+ return 1;
+ else
+ return 0;
+ }
+
+ private int prefAssignmentIndent() {
+ return prefContinuationIndent();
+ }
+
+ private int prefSimpleIndent() {
+ if (prefIndentBracesForBlocks() && prefBlockIndent() == 0)
+ return 1;
+ else
+ return prefBlockIndent();
+ }
+
+ private int prefBracketIndent() {
+ return prefBlockIndent();
+ }
+
+ private boolean prefMethodDeclDeepIndent() {
+ String option= getCoreFormatterOption(STPDefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_PARAMETERS_IN_METHOD_DECLARATION);
+ try {
+ int indentStyle = STPDefaultCodeFormatterConstants.getIndentStyle(option);
+ return indentStyle == STPDefaultCodeFormatterConstants.INDENT_ON_COLUMN;
+ } catch (IllegalArgumentException e) {
+ // ignore and return default
+ }
+
+ return false;
+ }
+
+ private boolean prefMethodDeclFirstParameterDeepIndent() {
+ String option= getCoreFormatterOption(STPDefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_PARAMETERS_IN_METHOD_DECLARATION);
+ try {
+ int indentStyle = STPDefaultCodeFormatterConstants.getIndentStyle(option);
+ int wrappingStyle = STPDefaultCodeFormatterConstants.getWrappingStyle(option);
+ return indentStyle == STPDefaultCodeFormatterConstants.INDENT_ON_COLUMN &&
+ (wrappingStyle == STPDefaultCodeFormatterConstants.WRAP_COMPACT_FIRST_BREAK ||
+ wrappingStyle == STPDefaultCodeFormatterConstants.WRAP_ONE_PER_LINE);
+ } catch (IllegalArgumentException e) {
+ // ignore and return default
+ }
+
+ return false;
+ }
+
+ private int prefMethodDeclIndent() {
+ String option= getCoreFormatterOption(STPDefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_PARAMETERS_IN_METHOD_DECLARATION);
+ try {
+ if (STPDefaultCodeFormatterConstants.getIndentStyle(option) == STPDefaultCodeFormatterConstants.INDENT_BY_ONE)
+ return 1;
+ else
+ return prefContinuationIndent();
+ } catch (IllegalArgumentException e) {
+ // ignore and return default
+ }
+ return 1;
+ }
+
+ private boolean prefMethodCallDeepIndent() {
+ String option= getCoreFormatterOption(STPDefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_ARGUMENTS_IN_METHOD_INVOCATION);
+ try {
+ int indentStyle = STPDefaultCodeFormatterConstants.getIndentStyle(option);
+ return indentStyle == STPDefaultCodeFormatterConstants.INDENT_ON_COLUMN;
+ } catch (IllegalArgumentException e) {
+ // ignore and return default
+ }
+ return false; // sensible default
+ }
+
+ private boolean prefMethodCallFirstParameterDeepIndent() {
+ String option= getCoreFormatterOption(STPDefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_ARGUMENTS_IN_METHOD_INVOCATION);
+ try {
+ int indentStyle = STPDefaultCodeFormatterConstants.getIndentStyle(option);
+ int wrappingStyle = STPDefaultCodeFormatterConstants.getWrappingStyle(option);
+ return indentStyle == STPDefaultCodeFormatterConstants.INDENT_ON_COLUMN &&
+ (wrappingStyle == STPDefaultCodeFormatterConstants.WRAP_COMPACT_FIRST_BREAK ||
+ wrappingStyle == STPDefaultCodeFormatterConstants.WRAP_ONE_PER_LINE);
+ } catch (IllegalArgumentException e) {
+ // ignore and return default
+ }
+ return false; // sensible default
+ }
+
+ private int prefMethodCallIndent() {
+ String option= getCoreFormatterOption(STPDefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_ARGUMENTS_IN_METHOD_INVOCATION);
+ try {
+ if (STPDefaultCodeFormatterConstants.getIndentStyle(option) == STPDefaultCodeFormatterConstants.INDENT_BY_ONE)
+ return 1;
+ else
+ return prefContinuationIndent();
+ } catch (IllegalArgumentException e) {
+ // ignore and return default
+ }
+
+ return 1; // sensible default
+ }
+
+ private boolean prefParenthesisDeepIndent() {
+ return false;
+ }
+
+ private int prefParenthesisIndent() {
+ return prefContinuationIndent();
+ }
+
+ private int prefBlockIndent() {
+ String option= getCoreFormatterOption(STPDefaultCodeFormatterConstants.FORMATTER_INDENT_STATEMENTS_COMPARE_TO_BLOCK);
+ if (STPDefaultCodeFormatterConstants.FALSE.equals(option))
+ return 0;
+
+ return 1; // sensible default
+ }
+
+ private int prefMethodBodyIndent() {
+ if (STPDefaultCodeFormatterConstants.FALSE.equals(getCoreFormatterOption(STPDefaultCodeFormatterConstants.FORMATTER_INDENT_STATEMENTS_COMPARE_TO_BODY)))
+ return 0;
+
+ return 1; // sensible default
+ }
+
+ private int prefTypeIndent() {
+ String option= getCoreFormatterOption(STPDefaultCodeFormatterConstants.FORMATTER_INDENT_BODY_DECLARATIONS_COMPARE_TO_ACCESS_SPECIFIER);
+ if (STPDefaultCodeFormatterConstants.FALSE.equals(option))
+ return 0;
+
+ return 1; // sensible default
+ }
+
+ private int prefAccessSpecifierIndent() {
+ if (STPDefaultCodeFormatterConstants.TRUE.equals(getCoreFormatterOption(STPDefaultCodeFormatterConstants.FORMATTER_INDENT_ACCESS_SPECIFIER_COMPARE_TO_TYPE_HEADER)))
+ return 1;
+ else
+ return 0;
+ }
+
+ private int prefAccessSpecifierExtraSpaces() {
+ return getCoreFormatterOption(STPDefaultCodeFormatterConstants.FORMATTER_INDENT_ACCESS_SPECIFIER_EXTRA_SPACES, 0);
+ }
+
+ private int prefNamespaceBodyIndent() {
+ if (STPDefaultCodeFormatterConstants.TRUE.equals(getCoreFormatterOption(STPDefaultCodeFormatterConstants.FORMATTER_INDENT_BODY_DECLARATIONS_COMPARE_TO_NAMESPACE_HEADER)))
+ return prefBlockIndent();
+ else
+ return 0;
+ }
+
+ private boolean prefIndentBracesForBlocks() {
+ return STPDefaultCodeFormatterConstants.NEXT_LINE_SHIFTED.equals(getCoreFormatterOption(STPDefaultCodeFormatterConstants.FORMATTER_BRACE_POSITION_FOR_BLOCK));
+ }
+
+ private boolean prefIndentBracesForArrays() {
+ return STPDefaultCodeFormatterConstants.NEXT_LINE_SHIFTED.equals(getCoreFormatterOption(STPDefaultCodeFormatterConstants.FORMATTER_BRACE_POSITION_FOR_INITIALIZER_LIST));
+ }
+
+ private boolean prefIndentBracesForMethods() {
+ return STPDefaultCodeFormatterConstants.NEXT_LINE_SHIFTED.equals(getCoreFormatterOption(STPDefaultCodeFormatterConstants.FORMATTER_BRACE_POSITION_FOR_METHOD_DECLARATION));
+ }
+
+ private boolean prefIndentBracesForTypes() {
+ return STPDefaultCodeFormatterConstants.NEXT_LINE_SHIFTED.equals(getCoreFormatterOption(STPDefaultCodeFormatterConstants.FORMATTER_BRACE_POSITION_FOR_TYPE_DECLARATION));
+ }
+
+ private int prefContinuationIndent() {
+ try {
+ return Integer.parseInt(getCoreFormatterOption(STPDefaultCodeFormatterConstants.FORMATTER_CONTINUATION_INDENTATION));
+ } catch (NumberFormatException e) {
+ // ignore and return default
+ }
+
+ return 2; // sensible default
+ }
+
+ private boolean hasTemplates() {
+ return true;
+ }
+ }
+
+ /** The document being scanned. */
+ private final IDocument fDocument;
+ /** The indentation accumulated by <code>findReferencePosition</code>. */
+ private int fIndent;
+ /** Extra spaces to add on top of fIndent */
+ private int fExtraSpaces;
+ /**
+ * The absolute (character-counted) indentation offset for special cases
+ * (method definitions, array initializers)
+ */
+ private int fAlign;
+ /** The stateful scan position for the indentation methods. */
+ private int fPosition;
+ /** The previous position. */
+ private int fPreviousPos;
+ /** The most recent token. */
+ private int fToken;
+ /** The line of <code>fPosition</code>. */
+ private int fLine;
+ /**
+ * The scanner we will use to scan the document. It has to be installed
+ * on the same document as the one we get.
+ */
+ private final STPHeuristicScanner fScanner;
+ /**
+ * The CDT Core preferences.
+ */
+ private final CorePrefs fPrefs;
+
+ /**
+ * Creates a new instance.
+ *
+ * @param document the document to scan
+ * @param scanner the {@link STPHeuristicScanner} to be used for scanning
+ * the document. It must be installed on the same <code>IDocument</code>.
+ */
+ public STPIndenter(IDocument document, STPHeuristicScanner scanner) {
+ this(document, scanner, null);
+ }
+
+ /**
+ * Creates a new instance.
+ *
+ * @param document the document to scan
+ * @param scanner the {@link STPHeuristicScanner} to be used for scanning
+ * the document. It must be installed on the same
+ * <code>IDocument</code>.
+ * @param project the C/C++ project to get the formatter preferences from, or
+ * <code>null</code> to use the workspace settings
+ */
+ public STPIndenter(IDocument document, STPHeuristicScanner scanner, IProject project) {
+ Assert.isNotNull(document);
+ Assert.isNotNull(scanner);
+ fDocument= document;
+ fScanner= scanner;
+ fPrefs= new CorePrefs(project);
+ }
+
+ /**
+ * Computes the indentation at the reference point of <code>position</code>.
+ *
+ * @param offset the offset in the document
+ * @return a String which reflects the indentation at the line in which the
+ * reference position to <code>offset</code> resides, or <code>null</code>
+ * if it cannot be determined
+ */
+ public StringBuilder getReferenceIndentation(int offset) {
+ return getReferenceIndentation(offset, false);
+ }
+
+ /**
+ * Computes the indentation at the reference point of <code>position</code>.
+ *
+ * @param offset the offset in the document
+ * @param assumeOpeningBrace <code>true</code> if an opening brace should be assumed
+ * @return a String which reflects the indentation at the line in which the
+ * reference position to <code>offset</code> resides, or <code>null</code>
+ * if it cannot be determined
+ */
+ private StringBuilder getReferenceIndentation(int offset, boolean assumeOpeningBrace) {
+ int unit= findReferencePosition(offset,
+ assumeOpeningBrace ? STPSymbols.TokenLBRACE : peekToken(offset));
+
+ // if we were unable to find anything, return null
+ if (unit == NOT_FOUND)
+ return null;
+
+ return getLeadingWhitespace(unit);
+ }
+
+ /**
+ * Computes the indentation at <code>offset</code>.
+ *
+ * @param offset the offset in the document
+ * @return a String which reflects the correct indentation for the line in
+ * which offset resides, or <code>null</code> if it cannot be
+ * determined
+ */
+ public StringBuilder computeIndentation(int offset) {
+ return computeIndentation(offset, false);
+ }
+
+ /**
+ * Computes the indentation at <code>offset</code>.
+ *
+ * @param offset the offset in the document
+ * @param assumeOpeningBrace <code>true</code> if an opening brace should be assumed
+ * @return a String which reflects the correct indentation for the line in
+ * which offset resides, or <code>null</code> if it cannot be
+ * determined
+ */
+ public StringBuilder computeIndentation(int offset, boolean assumeOpeningBrace) {
+ StringBuilder reference= getReferenceIndentation(offset, assumeOpeningBrace);
+
+ // handle special alignment
+ if (fAlign != NOT_FOUND) {
+ try {
+ // a special case has been detected.
+ IRegion line= fDocument.getLineInformationOfOffset(fAlign);
+ int lineOffset= line.getOffset();
+ return createIndent(lineOffset, fAlign, false);
+ } catch (BadLocationException e) {
+ return null;
+ }
+ }
+
+ if (reference == null)
+ return null;
+
+ // Add additional indent
+ return createReusingIndent(reference, fIndent, fExtraSpaces);
+ }
+
+ /**
+ * Computes the length of a <code>CharacterSequence</code>, counting
+ * a tab character as the size until the next tab stop and every other
+ * character as one.
+ *
+ * @param indent the string to measure
+ * @return the visual length in characters
+ */
+ private int computeVisualLength(CharSequence indent) {
+ final int tabSize= CodeFormatterUtil.getTabWidth();
+ int length= 0;
+ for (int i= 0; i < indent.length(); i++) {
+ char ch= indent.charAt(i);
+ switch (ch) {
+ case '\t':
+ if (tabSize > 0) {
+ int reminder= length % tabSize;
+ length += tabSize - reminder;
+ }
+ break;
+ case ' ':
+ length++;
+ break;
+ }
+ }
+ return length;
+ }
+
+ /**
+ * Strips any characters off the end of <code>reference</code> that exceed
+ * <code>indentLength</code>.
+ *
+ * @param reference the string to measure
+ * @param indentLength the maximum visual indentation length
+ * @return the stripped <code>reference</code>
+ */
+ private StringBuilder stripExceedingChars(StringBuilder reference, int indentLength) {
+ final int tabSize= CodeFormatterUtil.getTabWidth();
+ int measured= 0;
+ int chars= reference.length();
+ int i= 0;
+ for (; measured < indentLength && i < chars; i++) {
+ char ch= reference.charAt(i);
+ switch (ch) {
+ case '\t':
+ if (tabSize > 0) {
+ int reminder= measured % tabSize;
+ measured += tabSize - reminder;
+ }
+ break;
+ case ' ':
+ measured++;
+ break;
+ }
+ }
+ int deleteFrom= measured > indentLength ? i - 1 : i;
+
+ return reference.delete(deleteFrom, chars);
+ }
+
+ /**
+ * Returns the indentation of the line at <code>offset</code> as a
+ * <code>StringBuilder</code>. If the offset is not valid, the empty string
+ * is returned.
+ *
+ * @param offset the offset in the document
+ * @return the indentation (leading whitespace) of the line in which
+ * <code>offset</code> is located
+ */
+ private StringBuilder getLeadingWhitespace(int offset) {
+ StringBuilder indent= new StringBuilder();
+ try {
+ IRegion line= fDocument.getLineInformationOfOffset(offset);
+ int lineOffset= line.getOffset();
+ int nonWS= fScanner.findNonWhitespaceForwardInAnyPartition(lineOffset, lineOffset + line.getLength());
+ indent.append(fDocument.get(lineOffset, nonWS - lineOffset));
+ return indent;
+ } catch (BadLocationException e) {
+ return indent;
+ }
+ }
+
+ /**
+ * Creates an indentation string of the length indent - start, consisting of
+ * the content in <code>fDocument</code> in the range [start, indent),
+ * with every character replaced by a space except for tabs, which are kept
+ * as such.
+ * <p>
+ * If <code>convertSpaceRunsToTabs</code> is <code>true</code>, every
+ * run of the number of spaces that make up a tab are replaced by a tab
+ * character. If it is not set, no conversion takes place, but tabs in the
+ * original range are still copied verbatim.
+ * </p>
+ *
+ * @param start the start of the document region to copy the indent from
+ * @param indent the exclusive end of the document region to copy the indent
+ * from
+ * @param convertSpaceRunsToTabs whether to convert consecutive runs of
+ * spaces to tabs
+ * @return the indentation corresponding to the document content specified
+ * by <code>start</code> and <code>indent</code>
+ */
+ private StringBuilder createIndent(int start, final int indent, final boolean convertSpaceRunsToTabs) {
+ final boolean convertTabs= fPrefs.prefUseTabs && convertSpaceRunsToTabs;
+ final int tabLen= CodeFormatterUtil.getTabWidth();
+ final StringBuilder ret= new StringBuilder();
+ try {
+ int spaces= 0;
+ while (start < indent) {
+ char ch= fDocument.getChar(start);
+ if (ch == '\t') {
+ ret.append('\t');
+ spaces= 0;
+ } else if (convertTabs) {
+ spaces++;
+ if (spaces == tabLen) {
+ ret.append('\t');
+ spaces= 0;
+ }
+ } else {
+ ret.append(' ');
+ }
+
+ start++;
+ }
+ // remainder
+ while (spaces-- > 0)
+ ret.append(' ');
+ } catch (BadLocationException e) {
+ }
+
+ return ret;
+ }
+
+ /**
+ * Creates a string with a visual length of the given
+ * <code>indentationSize</code>.
+ *
+ * @param buffer the original indent to reuse if possible
+ * @param additional the additional indentation units to add or subtract to
+ * reference
+ * @param extraSpaces additional spaces to add to indentation.
+ * @return the modified <code>buffer</code> reflecting the indentation
+ * adapted to <code>additional</code>
+ */
+ public StringBuilder createReusingIndent(StringBuilder buffer, int additional, int extraSpaces) {
+ int refLength= computeVisualLength(buffer);
+ int addLength= CodeFormatterUtil.getIndentWidth() * additional + extraSpaces; // may be < 0
+ int totalLength= Math.max(0, refLength + addLength);
+
+ // copy the reference indentation for the indent up to the last tab
+ // stop within the maxCopy area
+ int minLength= Math.min(totalLength, refLength);
+ int tabSize= CodeFormatterUtil.getTabWidth();
+ int maxCopyLength= tabSize > 0 ? minLength - minLength % tabSize : minLength; // maximum indent to copy
+ stripExceedingChars(buffer, maxCopyLength);
+
+ // add additional indent
+ int missing= totalLength - maxCopyLength;
+ int tabs, spaces;
+ if (IDEPlugin.SPACE.equals(fPrefs.prefTabChar)) {
+ tabs= 0;
+ spaces= missing;
+ } else {
+ tabs= tabSize > 0 ? missing / tabSize : 0;
+ spaces= tabSize > 0 ? missing % tabSize : missing;
+ }
+ for (int i= 0; i < tabs; i++)
+ buffer.append('\t');
+ for (int i= 0; i < spaces; i++)
+ buffer.append(' ');
+ return buffer;
+ }
+
+ /**
+ * Returns relative indent of continuation lines.
+ * @return a number of indentation units.
+ */
+ public int getContinuationLineIndent() {
+ return fPrefs.prefContinuationIndent;
+ }
+
+ /**
+ * Returns the reference position regarding to indentation for <code>offset</code>,
+ * or {@link STPHeuristicScanner#NOT_FOUND NOT_FOUND}. This method calls
+ * {@link #findReferencePosition(int, int) findReferencePosition(offset, nextChar)} where
+ * <code>nextChar</code> is the next character after <code>offset</code>.
+ *
+ * @param offset the offset for which the reference is computed
+ * @return the reference statement relative to which <code>offset</code>
+ * should be indented, or {@link STPHeuristicScanner#NOT_FOUND NOT_FOUND}
+ */
+ public int findReferencePosition(int offset) {
+ return findReferencePosition(offset, peekToken(offset));
+ }
+
+ /**
+ * Peeks the next token in the document that comes after <code>offset</code>
+ * on the same line as <code>offset</code>.
+ *
+ * @param offset the offset into document
+ * @return the token symbol of the next element, or TokenEOF if there is none
+ */
+ private int peekToken(int offset) {
+ if (offset < fDocument.getLength()) {
+ try {
+ IRegion line= fDocument.getLineInformationOfOffset(offset);
+ int lineEnd= line.getOffset() + line.getLength();
+ int next= fScanner.nextToken(offset, lineEnd);
+ return next;
+ } catch (BadLocationException e) {
+ }
+ }
+ return STPSymbols.TokenEOF;
+ }
+
+ /**
+ * Peeks the second next token in the document that comes after <code>offset</code>
+ * on the same line as <code>offset</code>.
+ *
+ * @param offset the offset into document
+ * @return the token symbol of the second next element, or TokenEOF if there is none
+ */
+ private int peekSecondToken(int offset) {
+ if (offset < fDocument.getLength()) {
+ try {
+ IRegion line= fDocument.getLineInformationOfOffset(offset);
+ int lineEnd= line.getOffset() + line.getLength();
+ fScanner.nextToken(offset, lineEnd);
+ int next = fScanner.nextToken(fScanner.getPosition(), lineEnd);
+ return next;
+ } catch (BadLocationException e) {
+ }
+ }
+ return STPSymbols.TokenEOF;
+ }
+
+ /**
+ * Returns the reference position regarding to indentation for <code>position</code>,
+ * or {@link STPHeuristicScanner#NOT_FOUND NOT_FOUND}.
+ *
+ * <p>If <code>peekNextChar</code> is <code>true</code>, the next token after
+ * <code>offset</code> is read and taken into account when computing the
+ * indentation. Currently, if the next token is the first token on the line
+ * (i.e. only preceded by whitespace), the following tokens are specially
+ * handled:
+ * <ul>
+ * <li><code>switch</code> labels are indented relative to the switch block</li>
+ * <li>opening curly braces are aligned correctly with the introducing code</li>
+ * <li>closing curly braces are aligned properly with the introducing code of
+ * the matching opening brace</li>
+ * <li>closing parenthesis' are aligned with their opening peer</li>
+ * <li>the <code>else</code> keyword is aligned with its <code>if</code>, anything
+ * else is aligned normally (i.e. with the base of any introducing statements).</li>
+ * <li>if there is no token on the same line after <code>offset</code>, the indentation
+ * is the same as for an <code>else</code> keyword</li>
+ * </ul>
+ *
+ * @param offset the offset for which the reference is computed
+ * @param nextToken the next token to assume in the document
+ * @return the reference statement relative to which <code>offset</code>
+ * should be indented, or {@link STPHeuristicScanner#NOT_FOUND NOT_FOUND}
+ */
+ private int findReferencePosition(int offset, int nextToken) {
+ boolean danglingElse= false;
+ boolean cancelIndent= false; // If set to true, fIndent is ignored.
+ int extraIndent= 0; // Can be either positive or negative.
+ MatchMode matchMode = MatchMode.REGULAR;
+
+ // Account for un-indentation characters already typed in, but after position.
+ // If they are on a line by themselves, the indentation gets adjusted accordingly.
+ //
+ // Also account for a dangling else.
+ if (offset < fDocument.getLength()) {
+ try {
+ IRegion line= fDocument.getLineInformationOfOffset(offset);
+ int lineOffset= line.getOffset();
+ int prevPos= Math.max(offset - 1, 0);
+ boolean isFirstTokenOnLine=
+ fDocument.get(lineOffset, prevPos + 1 - lineOffset).trim().length() == 0;
+ int prevToken= fScanner.previousToken(prevPos, STPHeuristicScanner.UNBOUND);
+ boolean bracelessBlockStart= fScanner.isBracelessBlockStart(prevPos, STPHeuristicScanner.UNBOUND);
+
+ switch (nextToken) {
+ case STPSymbols.TokenELSE:
+ danglingElse= true;
+ break;
+
+ case STPSymbols.TokenCASE:
+ case STPSymbols.TokenDEFAULT:
+ if (isFirstTokenOnLine)
+ matchMode = MatchMode.MATCH_CASE;
+ break;
+
+ case STPSymbols.TokenPUBLIC:
+ case STPSymbols.TokenPROTECTED:
+ case STPSymbols.TokenPRIVATE:
+ if (isFirstTokenOnLine && peekSecondToken(offset) != STPSymbols.TokenIDENT)
+ matchMode = MatchMode.MATCH_ACCESS_SPECIFIER;
+ break;
+
+ case STPSymbols.TokenLBRACE: // for opening-brace-on-new-line style
+ if (bracelessBlockStart) {
+ extraIndent= fPrefs.prefIndentBracesForBlocks ? 0 : -1;
+ } else if (prevToken == STPSymbols.TokenCOLON && !fPrefs.prefIndentBracesForBlocks) {
+ extraIndent= -1;
+ } else if ((prevToken == STPSymbols.TokenEQUAL || prevToken == STPSymbols.TokenRBRACKET) &&
+ !fPrefs.prefIndentBracesForArrays) {
+ cancelIndent= true;
+ } else if ((prevToken == STPSymbols.TokenRPAREN || prevToken == STPSymbols.TokenCONST) && fPrefs.prefIndentBracesForMethods) {
+ extraIndent= 1;
+ } else if (prevToken == STPSymbols.TokenIDENT) {
+ if (fPrefs.prefIndentBracesForTypes) {
+ extraIndent= 1;
+ }
+ int pos = fPosition;
+ fPosition = offset;
+ if (matchTypeDeclaration() != NOT_FOUND) {
+ matchMode = MatchMode.MATCH_TYPE_DECLARATION;
+ }
+ fPosition = pos;
+ }
+ break;
+
+ case STPSymbols.TokenRBRACE: // closing braces get unindented
+ if (isFirstTokenOnLine || prevToken != STPSymbols.TokenLBRACE)
+ matchMode = MatchMode.MATCH_BRACE;
+ break;
+
+ case STPSymbols.TokenRPAREN:
+ if (isFirstTokenOnLine)
+ matchMode = MatchMode.MATCH_PAREN;
+ break;
+ }
+ } catch (BadLocationException e) {
+ }
+ } else {
+ // Don't assume an else could come if we are at the end of file.
+ danglingElse= false;
+ }
+
+ int ref= findReferencePosition(offset, danglingElse, matchMode);
+ if (cancelIndent) {
+ fIndent = 0;
+ } else if (extraIndent > 0) {
+ fAlign= NOT_FOUND;
+ fIndent += extraIndent;
+ } else {
+ fIndent += extraIndent;
+ }
+ return ref;
+ }
+
+ /**
+ * Enumeration used by {@link #findReferencePosition(int, boolean, MatchMode)} method.
+ */
+ public enum MatchMode {
+ /**
+ * The reference position should be returned based on the regular code analysis.
+ */
+ REGULAR,
+ /**
+ * The position of the matching brace should be returned instead of doing code analysis.
+ */
+ MATCH_BRACE,
+ /**
+ * The position of the matching parenthesis should be returned instead of doing code
+ * analysis.
+ */
+ MATCH_PAREN,
+ /**
+ * The position of a switch statement reference should be returned (either an earlier case
+ * statement or the switch block brace).
+ */
+ MATCH_CASE,
+ /**
+ * The position of a class body reference should be returned (either an earlier
+ * public/protected/private or the class body brace).
+ */
+ MATCH_ACCESS_SPECIFIER,
+ /**
+ * The position of a class declaration should be returned.
+ */
+ MATCH_TYPE_DECLARATION
+ }
+
+ /**
+ * Returns the reference position regarding to indentation for <code>position</code>,
+ * or {@link STPHeuristicScanner#NOT_FOUND NOT_FOUND}. <code>fIndent</code> will contain
+ * the relative indentation (in indentation units, not characters) after the call. If there is
+ * a special alignment (e.g. for a method declaration where parameters should be aligned),
+ * <code>fAlign</code> will contain the absolute position of the alignment reference
+ * in <code>fDocument</code>, otherwise <code>fAlign</code> is set to
+ * {@link STPHeuristicScanner#NOT_FOUND}.
+ *
+ * @param offset the offset for which the reference is computed
+ * @param danglingElse whether a dangling else should be assumed at <code>position</code>
+ * @param matchMode determines what kind of reference position should be returned.
+ * See {@link MatchMode}.
+ * @return the reference statement relative to which <code>position</code>
+ * should be indented, or {@link STPHeuristicScanner#NOT_FOUND}
+ */
+ public int findReferencePosition(int offset, boolean danglingElse, MatchMode matchMode) {
+ fIndent= 0; // The indentation modification
+ fExtraSpaces= 0;
+ fAlign= NOT_FOUND;
+ fPosition= offset;
+
+ // Forward cases.
+ // An unindentation happens sometimes if the next token is special, namely on braces,
+ // parens and case labels align braces, but handle the case where we align with the method
+ // declaration start instead of the opening brace.
+ switch (matchMode) {
+ case MATCH_BRACE:
+ if (skipScope(STPSymbols.TokenLBRACE, STPSymbols.TokenRBRACE)) {
+ try {
+ // Align with the opening brace that is on a line by its own
+ int lineOffset= fDocument.getLineOffset(fLine);
+ if (lineOffset <= fPosition &&
+ fDocument.get(lineOffset, fPosition - lineOffset).trim().isEmpty()) {
+ return fPosition;
+ }
+ } catch (BadLocationException e) {
+ // Concurrent modification - walk default path
+ }
+ // If the opening brace is not on the start of the line, skip to the start.
+ int pos= skipToStatementStart(true, true);
+ fIndent= 0; // indent is aligned with reference position
+ return pos;
+ } else {
+ // If we can't find the matching brace, the heuristic is to unindent
+ // by one against the normal position
+ int pos= findReferencePosition(offset, danglingElse, MatchMode.REGULAR);
+ fIndent--;
+ return pos;
+ }
+
+ case MATCH_PAREN:
+ // Align parentheses.
+ if (skipScope(STPSymbols.TokenLPAREN, STPSymbols.TokenRPAREN)) {
+ return fPosition;
+ } else {
+ // If we can't find the matching paren, the heuristic is to unindent by one
+ // against the normal position.
+ int pos= findReferencePosition(offset, danglingElse, MatchMode.REGULAR);
+ fIndent--;
+ return pos;
+ }
+
+ case MATCH_CASE:
+ // The only reliable way to get case labels aligned (due to many different styles of
+ // using braces in a block) is to go for another case statement, or the scope opening
+ // brace.
+ return matchCaseAlignment();
+
+ case MATCH_ACCESS_SPECIFIER:
+ // The only reliable way to get access specifiers aligned (due to many different styles
+ // of using braces in a block) is to go for another access specifier, or the scope
+ // opening brace.
+ return matchAccessSpecifierAlignment();
+
+ case MATCH_TYPE_DECLARATION:
+ return matchTypeDeclaration();
+
+ case REGULAR:
+ break;
+ }
+
+ if (peekToken(offset) == STPSymbols.TokenCOLON) {
+ int pos= fPosition;
+ if (looksLikeTypeInheritanceDecl()) {
+ fIndent = fPrefs.prefContinuationIndent;
+ return fPosition;
+ }
+ fPosition = pos;
+ }
+
+ nextToken();
+ // Skip access specifiers
+ while (fToken == STPSymbols.TokenCOLON && isAccessSpecifier()) {
+ nextToken();
+ }
+
+ int line= fLine;
+ switch (fToken) {
+ case STPSymbols.TokenGREATERTHAN:
+ case STPSymbols.TokenRBRACE:
+ // Skip the block and fall through.
+ // If we can't complete the scope, reset the scan position
+ int pos= fPosition;
+ if (!skipScope())
+ fPosition= pos;
+ return skipToStatementStart(danglingElse, false);
+
+ case STPSymbols.TokenSEMICOLON:
+ // This is the 90% case: after a statement block
+ // the end of the previous statement / block previous.end
+ // search to the end of the statement / block before the previous;
+ // the token just after that is previous.start
+ return skipToStatementStart(danglingElse, false);
+
+ // Scope introduction: special treat who special is
+ case STPSymbols.TokenLPAREN:
+ case STPSymbols.TokenLBRACE:
+ case STPSymbols.TokenLBRACKET:
+ return handleScopeIntroduction(Math.min(offset + 1, fDocument.getLength()), true);
+
+ case STPSymbols.TokenEOF:
+ // trap when hitting start of document
+ return NOT_FOUND;
+
+ case STPSymbols.TokenEQUAL:
+ // indent assignments, but don't do so if there is a String
+ // after the assignment because SystemTap doesn't require
+ // semi-colons to end lines and so this should be treated as
+ // a complete assignment.
+ pos = fPosition;
+ while (pos < offset) {
+ try {
+ ITypedRegion partition = ((IDocumentExtension3)fDocument).getPartition(STPPartitionScanner.STP_PARTITIONING, pos, danglingElse);
+ if (STPPartitionScanner.STP_STRING.equals(partition.getType()))
+ return skipToStatementStart(danglingElse, false);
+ pos = partition.getOffset() + partition.getLength();
+ } catch (BadLocationException e) {
+ break;
+ } catch (BadPartitioningException e) {
+ break;
+ }
+ }
+ fIndent= fPrefs.prefAssignmentIndent;
+ return fPosition;
+ case STPSymbols.TokenCOLON:
+ pos= fPosition;
+ if (looksLikeCaseStatement()) {
+ fIndent= fPrefs.prefCaseBlockIndent;
+ return pos;
+ }
+ fPosition= pos;
+ if (looksLikeTypeInheritanceDecl()) {
+ fIndent= fPrefs.prefContinuationIndent;
+ return pos;
+ }
+ fPosition= pos;
+ if (looksLikeConstructorInitializer()) {
+ fIndent= fPrefs.prefBlockIndent;
+ return pos;
+ }
+ fPosition= pos;
+ if (isConditional()) {
+ fPosition= offset;
+ fLine= line;
+ return skipToPreviousListItemOrListStart();
+ }
+ fPosition= pos;
+ return skipToPreviousListItemOrListStart();
+
+ case STPSymbols.TokenQUESTIONMARK:
+ if (fPrefs.prefTernaryDeepAlign) {
+ setFirstElementAlignment(fPosition, offset + 1);
+ } else {
+ fIndent= fPrefs.prefTernaryIndent;
+ }
+ return fPosition;
+
+ // Indentation for blockless introducers:
+ case STPSymbols.TokenDO:
+ case STPSymbols.TokenWHILE:
+ case STPSymbols.TokenELSE:
+ fIndent= fPrefs.prefSimpleIndent;
+ return fPosition;
+
+ case STPSymbols.TokenTRY:
+ return skipToStatementStart(danglingElse, false);
+
+ case STPSymbols.TokenRETURN:
+ case STPSymbols.TokenTYPEDEF:
+ case STPSymbols.TokenUSING:
+ fIndent = fPrefs.prefContinuationIndent;
+ return fPosition;
+
+ case STPSymbols.TokenCONST:
+ nextToken();
+ if (fToken != STPSymbols.TokenRPAREN) {
+ return skipToPreviousListItemOrListStart();
+ }
+ // could be const method decl
+ //$FALL-THROUGH$
+ case STPSymbols.TokenRPAREN:
+ if (skipScope(STPSymbols.TokenLPAREN, STPSymbols.TokenRPAREN)) {
+ int scope= fPosition;
+ nextToken();
+ if (fToken == STPSymbols.TokenIF || fToken == STPSymbols.TokenWHILE || fToken == STPSymbols.TokenFOR
+ || fToken == STPSymbols.TokenFOREACH) {
+ fIndent= fPrefs.prefSimpleIndent;
+ return fPosition;
+ }
+ if (fToken == STPSymbols.TokenSWITCH) {
+ return fPosition;
+ }
+ fPosition= scope;
+ if (looksLikeMethodDecl()) {
+ return skipToStatementStart(danglingElse, false);
+ }
+ if (fToken == STPSymbols.TokenCATCH) {
+ return skipToStatementStart(danglingElse, false);
+ }
+ fPosition= scope;
+ if (looksLikeAnonymousTypeDecl()) {
+ return skipToStatementStart(danglingElse, false);
+ }
+ }
+ // restore
+ fPosition= offset;
+ fLine= line;
+ // else: fall through to default
+ return skipToPreviousListItemOrListStart();
+
+ case STPSymbols.TokenCOMMA:
+ // Inside a list of some type.
+ // Easy if there is already a list item before with its own indentation - we just align.
+ // If not: take the start of the list (LPAREN, LBRACE, LBRACKET) and either align or
+ // indent by list-indent.
+ return skipToPreviousListItemOrListStart();
+
+ case STPSymbols.TokenPLUS:
+ case STPSymbols.TokenMINUS:
+ case STPSymbols.TokenLESSTHAN:
+ case STPSymbols.TokenAGGREGATE:
+ case STPSymbols.TokenSHIFTRIGHT:
+ case STPSymbols.TokenSHIFTLEFT:
+ case STPSymbols.TokenOTHER:
+ // Math symbol, use skipToPreviousListItemOrListStart.
+ return skipToPreviousListItemOrListStart();
+ // Otherwise, fall-through
+ default:
+ // Inside whatever we don't know about:
+ // C would treat this as a list, but in SystemTap we might just have a line that doesn't
+ // end in a semi-colon. We want to indent to the same level as the statement.
+ return skipToStatementStart(danglingElse, false);
+ }
+ }
+
+ /**
+ * Test whether an identifier encountered during scanning is part of
+ * a type declaration, by scanning backward and ignoring any identifiers, commas,
+ * and colons until we hit <code>class</code>, <code>struct</code>, <code>union</code>,
+ * or <code>enum</code>. If any braces, semicolons, or parentheses are encountered,
+ * this is not a type declaration.
+ * @return the reference offset of the start of the statement
+ */
+ private int matchTypeDeclaration() {
+ while (true) {
+ nextToken();
+ if (fToken == STPSymbols.TokenIDENT
+ || fToken == STPSymbols.TokenCOMMA
+ || fToken == STPSymbols.TokenCOLON
+ || fToken == STPSymbols.TokenPUBLIC
+ || fToken == STPSymbols.TokenPROTECTED
+ || fToken == STPSymbols.TokenPRIVATE) {
+ continue;
+ }
+ if (fToken == STPSymbols.TokenCLASS
+ || fToken == STPSymbols.TokenSTRUCT
+ || fToken == STPSymbols.TokenUNION) {
+ // inside a type declaration? Only so if not preceded by '(' or ',' as in
+ // a parameter list. To be safe, only accept ';' or EOF
+ int pos= fPosition;
+ nextToken();
+ if (fToken == STPSymbols.TokenSEMICOLON || fToken == STPSymbols.TokenEOF) {
+ return pos;
+ } else {
+ return NOT_FOUND;
+ }
+ } else {
+ return NOT_FOUND;
+ }
+ }
+ }
+
+ /**
+ * Test whether the colon at the current position marks a case statement
+ *
+ * @return <code>true</code> if this looks like a case statement
+ */
+ private boolean looksLikeCaseStatement() {
+ nextToken();
+ switch (fToken) {
+ case STPSymbols.TokenCASE:
+ // char literal got skipped
+ return true;
+ case STPSymbols.TokenIDENT:
+ nextToken();
+ while (skipQualifiers()) {
+ nextToken();
+ }
+ while (fToken == STPSymbols.TokenMINUS || fToken == STPSymbols.TokenPLUS) {
+ nextToken();
+ }
+ if (fToken == STPSymbols.TokenCASE) {
+ return true;
+ }
+ break;
+ case STPSymbols.TokenOTHER:
+ nextToken();
+ if (fToken == STPSymbols.TokenCASE) {
+ return true;
+ }
+ break;
+ case STPSymbols.TokenDEFAULT:
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Test whether the colon at the current position marks a type inheritance decl.
+ *
+ * @return <code>true</code> if this looks like a type inheritance decl.
+ */
+ private boolean looksLikeTypeInheritanceDecl() {
+ nextToken();
+ switch (fToken) {
+ case STPSymbols.TokenIDENT:
+ nextToken();
+ while (skipQualifiers()) {
+ nextToken();
+ }
+ switch (fToken) {
+ case STPSymbols.TokenCLASS:
+ case STPSymbols.TokenSTRUCT:
+ case STPSymbols.TokenUNION:
+ return true;
+ }
+ break;
+ }
+ return false;
+ }
+
+ /**
+ * Test whether the colon at the current position marks a constructor initializer list.
+ *
+ * @return <code>true</code> if this looks like a constructor initializer list.
+ */
+ private boolean looksLikeConstructorInitializer() {
+ nextToken();
+ if (fToken != STPSymbols.TokenRPAREN) {
+ return false;
+ }
+ if (!skipScope()) {
+ return false;
+ }
+ nextToken();
+ if (fToken == STPSymbols.TokenTHROW) {
+ nextToken();
+ if (fToken != STPSymbols.TokenRPAREN) {
+ return false;
+ }
+ if (!skipScope()) {
+ return false;
+ }
+ nextToken();
+ }
+ if (fToken != STPSymbols.TokenIDENT) {
+ return false;
+ }
+ nextToken();
+ switch (fToken) {
+ case STPSymbols.TokenCOLON:
+ nextToken();
+ switch (fToken) {
+ case STPSymbols.TokenCOLON: // A::A() :
+ case STPSymbols.TokenPUBLIC: // public: A() :
+ case STPSymbols.TokenPROTECTED:
+ case STPSymbols.TokenPRIVATE:
+ return true;
+ }
+ return false;
+
+ case STPSymbols.TokenLBRACE: // class A { A() :
+ case STPSymbols.TokenRBRACE:
+ case STPSymbols.TokenSEMICOLON:
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Test whether the left brace at the current position marks an enum decl.
+ *
+ * @return <code>true</code> if this looks like an enum decl.
+ */
+ private boolean looksLikeEnumDeclaration() {
+ int pos = fPosition;
+ nextToken();
+ if (fToken == STPSymbols.TokenIDENT) {
+ nextToken();
+ while (skipQualifiers()) {
+ nextToken();
+ }
+ }
+ if (fToken == STPSymbols.TokenENUM) {
+ fPosition = pos;
+ return true;
+ }
+ fPosition = pos;
+ return false;
+ }
+
+
+ /**
+ * Test whether the colon at the current position marks an access specifier.
+ *
+ * @return <code>true</code> if current position marks an access specifier
+ */
+ private boolean isAccessSpecifier() {
+ int pos= fPosition;
+ int token = fToken;
+ nextToken();
+ switch (fToken) {
+ case STPSymbols.TokenPUBLIC:
+ case STPSymbols.TokenPROTECTED:
+ case STPSymbols.TokenPRIVATE:
+ return true;
+ }
+ fToken = token;
+ fPosition= pos;
+ return false;
+ }
+
+ /**
+ * Skips to the start of a statement that ends at the current position.
+ *
+ * @param danglingElse whether to indent aligned with the last <code>if</code>
+ * @param isInBlock whether the current position is inside a block, which limits the search scope to
+ * the next scope introducer
+ * @return the reference offset of the start of the statement
+ */
+ private int skipToStatementStart(boolean danglingElse, boolean isInBlock) {
+ final int NOTHING= 0;
+ final int READ_PARENS= 1;
+ final int READ_IDENT= 2;
+ int mayBeMethodBody= NOTHING;
+ boolean isTypeBody= false;
+ int startLine = fLine;
+ while (true) {
+ int prevToken= fToken;
+ nextToken();
+
+ if (isInBlock) {
+ switch (fToken) {
+ // exit on all block introducers
+ case STPSymbols.TokenIF:
+ case STPSymbols.TokenELSE:
+ case STPSymbols.TokenCATCH:
+ case STPSymbols.TokenDO:
+ case STPSymbols.TokenWHILE:
+ case STPSymbols.TokenFOR:
+ case STPSymbols.TokenFOREACH:
+ case STPSymbols.TokenTRY:
+ fIndent += fPrefs.prefIndentBracesForBlocks ? 1 : 0;
+ return fPosition;
+ case STPSymbols.TokenCLASS:
+ case STPSymbols.TokenSTRUCT:
+ case STPSymbols.TokenUNION:
+ isTypeBody= true;
+ break;
+
+ case STPSymbols.TokenSWITCH:
+ fIndent= fPrefs.prefCaseIndent;
+ return fPosition;
+ }
+ }
+
+ if (fToken == STPSymbols.TokenSEMICOLON && fLine == startLine) {
+ // Skip semicolons on the same line. Otherwise we may never reach beginning of a 'for'
+ // statement.
+ continue;
+ }
+
+ switch (fToken) {
+ // scope introduction through: LPAREN, LBRACE, LBRACKET
+ // search stop on SEMICOLON, RBRACE, COLON, EOF
+ // -> the next token is the start of the statement (i.e. previousPos when backward scanning)
+ case STPSymbols.TokenLPAREN:
+ if (peekToken() == STPSymbols.TokenFOR) {
+ nextToken(); // Consume 'for'
+ fIndent = fPrefs.prefContinuationIndent;
+ return fPosition;
+ }
+ break;
+
+ case STPSymbols.TokenLBRACE:
+ case STPSymbols.TokenSEMICOLON:
+ case STPSymbols.TokenEOF:
+ if (isInBlock)
+ fIndent= getBlockIndent(mayBeMethodBody == READ_IDENT, isTypeBody);
+ return fPreviousPos;
+
+ case STPSymbols.TokenCOLON:
+ switch (prevToken) {
+ case STPSymbols.TokenPRIVATE:
+ case STPSymbols.TokenPROTECTED:
+ case STPSymbols.TokenPUBLIC:
+ continue; // Don't stop at colon in a class declaration
+
+ case STPSymbols.TokenVIRTUAL:
+ switch (peekToken()) {
+ case STPSymbols.TokenPRIVATE:
+ case STPSymbols.TokenPROTECTED:
+ case STPSymbols.TokenPUBLIC:
+ break;
+ default:
+ continue;
+ }
+ }
+ int pos= fPreviousPos;
+ if (!isConditional())
+ return pos;
+ break;
+
+ case STPSymbols.TokenRBRACE:
+ // RBRACE is a little tricky: it can be the end of an array definition, but
+ // usually it is the end of a previous block
+ pos= fPreviousPos; // store state
+ if (skipScope()) {
+ if (looksLikeArrayInitializerIntro()) {
+ continue; // it's an array
+ }
+ if (prevToken == STPSymbols.TokenSEMICOLON) {
+ // end of type def
+ continue;
+ }
+ }
+ if (isInBlock)
+ fIndent= getBlockIndent(mayBeMethodBody == READ_IDENT, isTypeBody);
+ return pos; // it's not - do as with all the above
+
+ // scopes: skip them
+ case STPSymbols.TokenRPAREN:
+ if (isInBlock)
+ mayBeMethodBody= READ_PARENS;
+ // fall thru
+ pos= fPreviousPos;
+ if (skipScope())
+ break;
+ else
+ return pos;
+ case STPSymbols.TokenRBRACKET:
+ pos= fPreviousPos;
+ if (skipScope())
+ break;
+ else
+ return pos;
+
+ // IF / ELSE: align the position after the conditional block with the if
+ // so we are ready for an else, except if danglingElse is false
+ // in order for this to work, we must skip an else to its if
+ case STPSymbols.TokenIF:
+ if (danglingElse)
+ return fPosition;
+ else
+ break;
+ case STPSymbols.TokenELSE:
+ // skip behind the next if, as we have that one covered
+ pos= fPosition;
+ if (skipNextIF())
+ break;
+ else
+ return pos;
+
+ case STPSymbols.TokenDO:
+ // align the WHILE position with its do
+ return fPosition;
+
+ case STPSymbols.TokenWHILE:
+ // this one is tricky: while can be the start of a while loop
+ // or the end of a do - while
+ pos= fPosition;
+ if (hasMatchingDo()) {
+ // continue searching from the DO on
+ break;
+ } else {
+ // continue searching from the WHILE on
+ fPosition= pos;
+ break;
+ }
+ case STPSymbols.TokenIDENT:
+ if (mayBeMethodBody == READ_PARENS)
+ mayBeMethodBody= READ_IDENT;
+ break;
+
+ default:
+ // keep searching
+ }
+ }
+ }
+
+ private int getBlockIndent(boolean isMethodBody, boolean isTypeBody) {
+ if (isTypeBody) {
+ return fPrefs.prefTypeIndent + fPrefs.prefAccessSpecifierIndent;
+ } else if (isMethodBody) {
+ return fPrefs.prefMethodBodyIndent + (fPrefs.prefIndentBracesForMethods ? 1 : 0);
+ } else {
+ return fIndent;
+ }
+ }
+
+ /**
+ * Returns <code>true</code> if the colon at the current position is part of a conditional
+ * (ternary) expression, <code>false</code> otherwise.
+ *
+ * @return <code>true</code> if the colon at the current position is part of a conditional
+ */
+ private boolean isConditional() {
+ while (true) {
+ int previous= fToken;
+ nextToken();
+ switch (fToken) {
+ // search for case labels, which consist of (possibly qualified) identifiers or numbers
+ case STPSymbols.TokenIDENT:
+ if (previous == STPSymbols.TokenIDENT) {
+ return false;
+ }
+ // fall thru
+ continue;
+ case STPSymbols.TokenDOUBLECOLON:
+ case STPSymbols.TokenOTHER:
+ case STPSymbols.TokenMINUS:
+ case STPSymbols.TokenPLUS:
+ continue;
+
+ case STPSymbols.TokenQUESTIONMARK:
+ return true;
+
+ case STPSymbols.TokenSEMICOLON:
+ case STPSymbols.TokenLBRACE:
+ case STPSymbols.TokenRBRACE:
+ case STPSymbols.TokenCASE:
+ case STPSymbols.TokenDEFAULT:
+ case STPSymbols.TokenPUBLIC:
+ case STPSymbols.TokenPROTECTED:
+ case STPSymbols.TokenPRIVATE:
+ case STPSymbols.TokenCLASS:
+ case STPSymbols.TokenSTRUCT:
+ case STPSymbols.TokenUNION:
+ return false;
+
+ default:
+ return true;
+ }
+ }
+ }
+
+ /**
+ * Returns as a reference any previous <code>switch</code> labels (<code>case</code>
+ * or <code>default</code>) or the offset of the brace that scopes the switch
+ * statement. Sets <code>fIndent</code> to <code>prefCaseIndent</code> upon
+ * a match.
+ *
+ * @return the reference offset for a <code>switch</code> label
+ */
+ private int matchCaseAlignment() {
+ while (true) {
+ nextToken();
+ switch (fToken) {
+ // invalid cases: another case label or an LBRACE must come before a case
+ // -> bail out with the current position
+ case STPSymbols.TokenLPAREN:
+ case STPSymbols.TokenLBRACKET:
+ case STPSymbols.TokenEOF:
+ return fPosition;
+
+ case STPSymbols.TokenSWITCH:
+ // start of switch statement
+ fIndent= fPrefs.prefCaseIndent;
+ return fPosition;
+
+ case STPSymbols.TokenCASE:
+ case STPSymbols.TokenDEFAULT:
+ // align with previous label
+ fIndent= 0;
+ return fPosition;
+
+ // scopes: skip them
+ case STPSymbols.TokenRPAREN:
+ case STPSymbols.TokenRBRACKET:
+ case STPSymbols.TokenRBRACE:
+ skipScope();
+ break;
+
+ default:
+ // keep searching
+ continue;
+ }
+ }
+ }
+
+ /**
+ * Returns as a reference any previous access specifiers (<code>public</code>,
+ * <code>protected</code> or <code>default</code>) or the offset of the brace that
+ * scopes the class body.
+ * Sets <code>fIndent</code> to <code>prefAccessSpecifierIndent</code> upon
+ * a match.
+ *
+ * @return the reference offset for an access specifier (public/protected/private)
+ */
+ private int matchAccessSpecifierAlignment() {
+ while (true) {
+ nextToken();
+ switch (fToken) {
+ // invalid cases: another access specifier or an LBRACE must come before an access specifier
+ // -> bail out with the current position
+ case STPSymbols.TokenLPAREN:
+ case STPSymbols.TokenLBRACKET:
+ case STPSymbols.TokenEOF:
+ return fPosition;
+
+ case STPSymbols.TokenLBRACE:
+ // opening brace of class body
+ int pos= fPosition;
+ int typeDeclPos= matchTypeDeclaration();
+ fIndent= fPrefs.prefAccessSpecifierIndent;
+ fExtraSpaces = fPrefs.prefAccessSpecifierExtraSpaces;
+ if (typeDeclPos != NOT_FOUND) {
+ return typeDeclPos;
+ }
+ return pos;
+ case STPSymbols.TokenPUBLIC:
+ case STPSymbols.TokenPROTECTED:
+ case STPSymbols.TokenPRIVATE:
+ // align with previous access specifier
+ fIndent= 0;
+ return fPosition;
+
+ // scopes: skip them
+ case STPSymbols.TokenRPAREN:
+ case STPSymbols.TokenRBRACKET:
+ case STPSymbols.TokenRBRACE:
+ skipScope();
+ break;
+
+ default:
+ // keep searching
+ continue;
+ }
+ }
+ }
+
+ /**
+ * Returns the reference position for a list element. The algorithm
+ * tries to match any previous indentation on the same list. If there is none,
+ * the reference position returned is determined depending on the type of list:
+ * The indentation will either match the list scope introducer (e.g. for
+ * method declarations), so called deep indents, or simply increase the
+ * indentation by a number of standard indents. See also {@link #handleScopeIntroduction(int, boolean)}.
+ * @return the reference position for a list item: either a previous list item
+ * that has its own indentation, or the list introduction start.
+ */
+ private int skipToPreviousListItemOrListStart() {
+ int startLine= fLine;
+ int startPosition= fPosition;
+ int linesSkippedInsideScopes = 0;
+ boolean continuationLineCandidate =
+ fToken == STPSymbols.TokenEQUAL || fToken == STPSymbols.TokenSHIFTLEFT ||
+ fToken == STPSymbols.TokenRPAREN;
+ while (true) {
+ int previous = fToken;
+ nextToken();
+
+ // If any line item comes with its own indentation, adapt to it
+ if (fLine < startLine - linesSkippedInsideScopes) {
+ try {
+ int lineOffset= fDocument.getLineOffset(startLine);
+ int bound= Math.min(fDocument.getLength(), startPosition + 1);
+ if ((fToken == STPSymbols.TokenSEMICOLON || fToken == STPSymbols.TokenRBRACE || fToken == STPSymbols.TokenIDENT ||
+ fToken == STPSymbols.TokenLBRACE && !looksLikeArrayInitializerIntro() && !looksLikeEnumDeclaration()) &&
+ continuationLineCandidate) {
+ fIndent = fPrefs.prefContinuationIndent;
+ } else {
+ fAlign= fScanner.findNonWhitespaceForwardInAnyPartition(lineOffset, bound);
+ // If the reference line starts with a colon, skip the colon.
+ if (peekToken(fAlign) == STPSymbols.TokenCOLON) {
+ fAlign= fScanner.findNonWhitespaceForwardInAnyPartition(fAlign + 1, bound);
+ }
+ }
+ } catch (BadLocationException e) {
+ // Ignore and return just the position
+ }
+ return startPosition;
+ }
+
+ int line = fLine;
+ switch (fToken) {
+ // scopes: skip them
+ case STPSymbols.TokenRPAREN:
+ continuationLineCandidate = true;
+ //$FALL-THROUGH$
+ case STPSymbols.TokenRBRACKET:
+ case STPSymbols.TokenRBRACE:
+ skipScope();
+ linesSkippedInsideScopes = line - fLine;
+ break;
+
+ // scope introduction: special treat who special is
+ case STPSymbols.TokenLPAREN:
+ case STPSymbols.TokenLBRACE:
+ case STPSymbols.TokenLBRACKET:
+ return handleScopeIntroduction(startPosition + 1, false);
+
+ case STPSymbols.TokenSEMICOLON:
+ return fPosition;
+
+ case STPSymbols.TokenQUESTIONMARK:
+ if (fPrefs.prefTernaryDeepAlign) {
+ setFirstElementAlignment(fPosition - 1, fPosition + 1);
+ } else {
+ fIndent= fPrefs.prefTernaryIndent;
+ }
+ return fPosition;
+
+ case STPSymbols.TokenEQUAL:
+ case STPSymbols.TokenSHIFTLEFT:
+ continuationLineCandidate = true;
+ break;
+
+ case STPSymbols.TokenRETURN:
+ case STPSymbols.TokenUSING:
+ fIndent = fPrefs.prefContinuationIndent;
+ return fPosition;
+
+ case STPSymbols.TokenTYPEDEF:
+ switch (previous) {
+ case STPSymbols.TokenSTRUCT:
+ case STPSymbols.TokenUNION:
+ case STPSymbols.TokenCLASS:
+ case STPSymbols.TokenENUM:
+ break;
+ default:
+ fIndent = fPrefs.prefContinuationIndent;
+ }
+ return fPosition;
+
+ case STPSymbols.TokenEOF:
+ if (continuationLineCandidate) {
+ fIndent = fPrefs.prefContinuationIndent;
+ }
+ return 0;
+ }
+ }
+ }
+
+ /**
+ * Skips a scope and positions the cursor (<code>fPosition</code>) on the
+ * token that opens the scope. Returns <code>true</code> if a matching peer
+ * could be found, <code>false</code> otherwise. The current token when calling
+ * must be one out of <code>STPSymbols.TokenRPAREN</code>, <code>STPSymbols.TokenRBRACE</code>,
+ * and <code>STPSymbols.TokenRBRACKET</code>.
+ *
+ * @return <code>true</code> if a matching peer was found, <code>false</code> otherwise
+ */
+ private boolean skipScope() {
+ switch (fToken) {
+ case STPSymbols.TokenRPAREN:
+ return skipScope(STPSymbols.TokenLPAREN, STPSymbols.TokenRPAREN);
+ case STPSymbols.TokenRBRACKET:
+ return skipScope(STPSymbols.TokenLBRACKET, STPSymbols.TokenRBRACKET);
+ case STPSymbols.TokenRBRACE:
+ return skipScope(STPSymbols.TokenLBRACE, STPSymbols.TokenRBRACE);
+ case STPSymbols.TokenGREATERTHAN:
+ if (!fPrefs.prefHasTemplates)
+ return false;
+ int storedPosition= fPosition;
+ int storedToken= fToken;
+ nextToken();
+ switch (fToken) {
+ case STPSymbols.TokenIDENT:
+ fPosition = storedPosition;
+ if (skipScope(STPSymbols.TokenLESSTHAN, STPSymbols.TokenGREATERTHAN))
+ return true;
+ break;
+ case STPSymbols.TokenQUESTIONMARK:
+ case STPSymbols.TokenGREATERTHAN:
+ fPosition = storedPosition;
+ if (skipScope(STPSymbols.TokenLESSTHAN, STPSymbols.TokenGREATERTHAN))
+ return true;
+ break;
+ }
+ // <> are harder to detect - restore the position if we fail
+ fPosition= storedPosition;
+ fToken= storedToken;
+ return false;
+
+ default:
+ // programming error
+ Assert.isTrue(false);
+ return false;
+ }
+ }
+
+ /**
+ * Returns the contents of the current token.
+ *
+ * @return the contents of the current token
+ */
+ private CharSequence getTokenContent() {
+ return new DocumentCharacterIterator(fDocument, fPosition, fPreviousPos);
+ }
+
+ /**
+ * Handles the introduction of a new scope. The current token must be one out
+ * of <code>STPSymbols.TokenLPAREN</code>, <code>STPSymbols.TokenLBRACE</code>,
+ * and <code>STPSymbols.TokenLBRACKET</code>. Returns as the reference position
+ * either the token introducing the scope or - if available - the first
+ * token after that.
+ *
+ * <p>Depending on the type of scope introduction, the indentation will align
+ * (deep indenting) with the reference position (<code>fAlign</code> will be
+ * set to the reference position) or <code>fIndent</code> will be set to
+ * the number of indentation units.
+ * </p>
+ *
+ * @param bound the bound for the search for the first token after the scope
+ * introduction.
+ * @param firstToken <code>true</code> if we are dealing with the first token after
+ * the opening parenthesis.
+ * @return the indent
+ */
+ private int handleScopeIntroduction(int bound, boolean firstToken) {
+ int pos= fPosition; // store
+
+ switch (fToken) {
+ // scope introduction: special treat who special is
+ case STPSymbols.TokenLPAREN:
+ // special: method declaration deep indentation
+ if (looksLikeMethodDecl()) {
+ if (firstToken ? fPrefs.prefMethodDeclFirstParameterDeepIndent : fPrefs.prefMethodDeclDeepIndent) {
+ return setFirstElementAlignment(pos, bound);
+ } else {
+ fIndent= fPrefs.prefMethodDeclIndent;
+ return pos;
+ }
+ } else {
+ fPosition= pos;
+ if (looksLikeMethodCall()) {
+ if (firstToken ? fPrefs.prefMethodCallFirstParameterDeepIndent : fPrefs.prefMethodCallDeepIndent) {
+ return setFirstElementAlignment(pos, bound);
+ } else {
+ fIndent= fPrefs.prefMethodCallIndent;
+ return pos;
+ }
+ } else if (fPrefs.prefParenthesisDeepIndent) {
+ return setFirstElementAlignment(pos, bound);
+ }
+ }
+
+ // normal: return the parenthesis as reference
+ fIndent= fPrefs.prefParenthesisIndent;
+ return pos;
+
+ case STPSymbols.TokenLBRACE:
+ final boolean looksLikeArrayInitializerIntro= looksLikeArrayInitializerIntro();
+ // special: array initializer
+ if (looksLikeArrayInitializerIntro) {
+ if (fPrefs.prefArrayDeepIndent)
+ return setFirstElementAlignment(pos, bound);
+ else
+ fIndent= fPrefs.prefArrayIndent;
+ } else if (isNamespace() || isLinkageSpec()) {
+ fIndent= fPrefs.prefNamespaceBodyIndent;
+ } else if (looksLikeEnumDeclaration()) {
+ fIndent = fPrefs.prefTypeIndent;
+ } else {
+ int typeDeclPos = matchTypeDeclaration();
+ if (typeDeclPos == NOT_FOUND) {
+ fIndent= fPrefs.prefBlockIndent;
+ } else {
+ fIndent= fPrefs.prefAccessSpecifierIndent + fPrefs.prefTypeIndent;
+ }
+ }
+
+ // normal: skip to the statement start before the scope introducer
+ // opening braces are often on differently ending indents than e.g. a method definition
+ if (!looksLikeArrayInitializerIntro) {
+ fPosition= pos; // restore
+ return skipToStatementStart(true, true); // set to true to match the first if
+ } else {
+ return pos;
+ }
+
+ case STPSymbols.TokenLBRACKET:
+ // special: method declaration deep indentation
+ if (fPrefs.prefArrayDimensionsDeepIndent) {
+ return setFirstElementAlignment(pos, bound);
+ }
+
+ // normal: return the bracket as reference
+ fIndent= fPrefs.prefBracketIndent;
+ return pos; // restore
+
+ default:
+ // programming error
+ Assert.isTrue(false);
+ return -1; // dummy
+ }
+ }
+
+ /**
+ * Sets the deep indent offset (<code>fAlign</code>) to either the offset
+ * right after <code>scopeIntroducerOffset</code> or - if available - the
+ * first C token after <code>scopeIntroducerOffset</code>, but before
+ * <code>bound</code>.
+ *
+ * @param scopeIntroducerOffset the offset of the scope introducer
+ * @param bound the bound for the search for another element
+ * @return the reference position
+ */
+ private int setFirstElementAlignment(int scopeIntroducerOffset, int bound) {
+ int firstPossible= scopeIntroducerOffset + 1; // align with the first position after the scope intro
+ fAlign= fScanner.findNonWhitespaceForwardInAnyPartition(firstPossible, bound);
+ if (fAlign == NOT_FOUND) {
+ fAlign= firstPossible;
+ } else {
+ try {
+ IRegion lineRegion = fDocument.getLineInformationOfOffset(scopeIntroducerOffset);
+ if (fAlign > lineRegion.getOffset() + lineRegion.getLength()) {
+ fAlign= firstPossible;
+ }
+ } catch (BadLocationException e) {
+ // Ignore.
+ }
+ }
+ return fAlign;
+ }
+
+ /**
+ * Returns <code>true</code> if the next token received after calling
+ * <code>nextToken</code> is either an equal sign, an opening brace,
+ * a comma or an array designator ('[]').
+ *
+ * @return <code>true</code> if the next elements look like the start of an array definition
+ */
+ private boolean looksLikeArrayInitializerIntro() {
+ int pos= fPosition;
+ nextToken();
+ switch (fToken) {
+ case STPSymbols.TokenEQUAL:
+ return true;
+ case STPSymbols.TokenRBRACKET:
+ return skipBrackets();
+ case STPSymbols.TokenLBRACE:
+ if (looksLikeArrayInitializerIntro()) {
+ fPosition= pos;
+ return true;
+ }
+ return false;
+ case STPSymbols.TokenCOMMA:
+ fPosition= pos;
+ return true;
+ }
+ fPosition= pos;
+ return false;
+ }
+
+ /**
+ * Returns <code>true</code> if the the current token is "namespace", or the current token
+ * is an identifier and the previous token is "namespace".
+ *
+ * @return <code>true</code> if the next elements look like the start of a namespace declaration.
+ */
+ private boolean isNamespace() {
+ int pos = fPosition;
+ nextToken();
+ if (fToken == STPSymbols.TokenNAMESPACE) {
+ fPosition = pos;
+ return true; // Anonymous namespace
+ } else if (fToken == STPSymbols.TokenIDENT) {
+ nextToken(); // Get previous token
+ if (fToken == STPSymbols.TokenNAMESPACE) {
+ fPosition = pos;
+ return true; // Named namespace
+ }
+ }
+ fPosition = pos;
+ return false;
+ }
+
+ /**
+ * Returns <code>true</code> if the current token is keyword "extern".
+ *
+ * @return <code>true</code> if the next elements look like the start of a linkage spec.
+ */
+ private boolean isLinkageSpec() {
+ int pos = fPosition;
+ nextToken();
+ if (fToken == STPSymbols.TokenEXTERN) {
+ fPosition = pos;
+ return true;
+ }
+ fPosition = pos;
+ return false;
+ }
+
+ /**
+ * Skips over the next <code>if</code> keyword. The current token when calling
+ * this method must be an <code>else</code> keyword. Returns <code>true</code>
+ * if a matching <code>if</code> could be found, <code>false</code> otherwise.
+ * The cursor (<code>fPosition</code>) is set to the offset of the <code>if</code>
+ * token.
+ *
+ * @return <code>true</code> if a matching <code>if</code> token was found, <code>false</code> otherwise
+ */
+ private boolean skipNextIF() {
+ Assert.isTrue(fToken == STPSymbols.TokenELSE);
+
+ while (true) {
+ nextToken();
+ switch (fToken) {
+ // scopes: skip them
+ case STPSymbols.TokenRPAREN:
+ case STPSymbols.TokenRBRACKET:
+ case STPSymbols.TokenRBRACE:
+ skipScope();
+ break;
+
+ case STPSymbols.TokenIF:
+ // found it, return
+ return true;
+ case STPSymbols.TokenELSE:
+ // recursively skip else-if blocks
+ skipNextIF();
+ break;
+
+ // shortcut scope starts
+ case STPSymbols.TokenLPAREN:
+ case STPSymbols.TokenLBRACE:
+ case STPSymbols.TokenLBRACKET:
+ case STPSymbols.TokenEOF:
+ return false;
+ }
+ }
+ }
+
+ /**
+ * while(condition); is ambiguous when parsed backwardly, as it is a valid
+ * statement by its own, so we have to check whether there is a matching
+ * do. A <code>do</code> can either be separated from the while by a
+ * block, or by a single statement, which limits our search distance.
+ *
+ * @return <code>true</code> if the <code>while</code> currently in
+ * <code>fToken</code> has a matching <code>do</code>.
+ */
+ private boolean hasMatchingDo() {
+ Assert.isTrue(fToken == STPSymbols.TokenWHILE);
+ nextToken();
+ switch (fToken) {
+ case STPSymbols.TokenRBRACE:
+ skipScope(); // and fall thru
+ skipToStatementStart(false, false);
+ return fToken == STPSymbols.TokenDO;
+
+ case STPSymbols.TokenSEMICOLON:
+ skipToStatementStart(false, false);
+ return fToken == STPSymbols.TokenDO;
+ }
+ return false;
+ }
+
+ /**
+ * Skips pointer operators if the current token is a pointer operator.
+ *
+ * @return <code>true</code> if a <code>*</code> or <code>&amp;</code> could be scanned, the
+ * current token is left at the operator.
+ */
+ private boolean skipPointerOperators() {
+ if (fToken == STPSymbols.TokenOTHER) {
+ CharSequence token= getTokenContent().toString().trim();
+ if (token.length() == 1 && token.charAt(0) == '*' || token.charAt(0) == '&') {
+ return true;
+ }
+ } else if (fToken == STPSymbols.TokenCONST) {
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Skips brackets if the current token is a RBRACKET. There can be nothing
+ * but whitespace in between, this is only to be used for <code>[]</code> elements.
+ *
+ * @return <code>true</code> if a <code>[]</code> could be scanned, the
+ * current token is left at the LBRACKET.
+ */
+ private boolean skipBrackets() {
+ if (fToken == STPSymbols.TokenRBRACKET) {
+ nextToken();
+ if (fToken == STPSymbols.TokenLBRACKET) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Skips scope qualifiers of identifiers.
+ *
+ * @return <code>true</code> if a qualifier was encountered, the last token
+ * will be an IDENT.
+ */
+ private boolean skipQualifiers() {
+ if (fToken == STPSymbols.TokenDOUBLECOLON) {
+ nextToken();
+ if (fToken == STPSymbols.TokenIDENT) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Reads the next token in backward direction from the heuristic scanner
+ * and sets the fields <code>fToken, fPreviousPosition</code> and <code>fPosition</code>
+ * accordingly.
+ */
+ private void nextToken() {
+ nextToken(fPosition);
+ }
+
+ /**
+ * Reads the next token in backward direction of <code>start</code> from
+ * the heuristic scanner and sets the fields <code>fToken, fPreviousPosition</code>
+ * and <code>fPosition</code> accordingly.
+ *
+ * @param start the start offset from which to scan backwards
+ */
+ private void nextToken(int start) {
+ fToken= fScanner.previousToken(start - 1, STPHeuristicScanner.UNBOUND);
+ fPreviousPos= start;
+ fPosition= fScanner.getPosition() + 1;
+ try {
+ fLine= fDocument.getLineOfOffset(fPosition);
+ } catch (BadLocationException e) {
+ fLine= -1;
+ }
+ }
+
+ /**
+ * Reads the next token in backward direction from the heuristic scanner
+ * and returns that token without changing the current position.
+ */
+ private int peekToken() {
+ return fScanner.previousToken(fPosition - 1, STPHeuristicScanner.UNBOUND);
+ }
+
+ /**
+ * Returns <code>true</code> if the current tokens look like a method
+ * declaration header (i.e. only the return type and method name). The
+ * heuristic calls <code>nextToken</code> and expects an identifier
+ * (method name) and an optional return type declaration.
+ *
+ * @return <code>true</code> if the current position looks like a method
+ * declaration header.
+ */
+ private boolean looksLikeMethodDecl() {
+ nextToken();
+ switch (fToken) {
+ case STPSymbols.TokenIDENT: // method name
+ int pos= fPosition;
+ nextToken();
+ // check destructor tilde
+ if (fToken == STPSymbols.TokenTILDE) {
+ return true;
+ }
+ if (skipQualifiers()) {
+ return true;
+ }
+ // optional brackets for array valued return types
+ while (skipBrackets()) {
+ nextToken();
+ }
+ while (skipPointerOperators()) {
+ nextToken();
+ }
+ switch (fToken) {
+ case STPSymbols.TokenIDENT:
+ return true;
+ case STPSymbols.TokenSEMICOLON:
+ case STPSymbols.TokenRBRACE:
+ fPosition= pos;
+ return true;
+ case STPSymbols.TokenLBRACE:
+ if (fScanner.looksLikeCompositeTypeDefinitionBackward(fPosition, STPHeuristicScanner.UNBOUND)) {
+ fPosition= pos;
+ return true;
+ }
+ break;
+ case STPSymbols.TokenCOMMA:
+ nextToken();
+ if (fToken == STPSymbols.TokenRPAREN) {
+ // field initializer
+ if (skipScope()) {
+ return looksLikeMethodDecl();
+ }
+ }
+ break;
+ case STPSymbols.TokenCOLON:
+ nextToken();
+ switch (fToken) {
+ case STPSymbols.TokenPUBLIC:
+ case STPSymbols.TokenPROTECTED:
+ case STPSymbols.TokenPRIVATE:
+ fPosition= pos;
+ return true;
+ case STPSymbols.TokenRPAREN:
+ // constructor initializer
+ if (skipScope()) {
+ pos = fPosition;
+ nextToken();
+ // optional throw
+ if (fToken == STPSymbols.TokenTHROW) {
+ nextToken();
+ if (fToken != STPSymbols.TokenRPAREN || !skipScope()) {
+ return false;
+ }
+ } else {
+ fPosition = pos;
+ }
+ return looksLikeMethodDecl();
+ }
+ break;
+ }
+ }
+ break;
+ case STPSymbols.TokenARROW:
+ case STPSymbols.TokenCOMMA:
+ case STPSymbols.TokenEQUAL:
+ case STPSymbols.TokenGREATERTHAN:
+ case STPSymbols.TokenLESSTHAN:
+ case STPSymbols.TokenMINUS:
+ case STPSymbols.TokenPLUS:
+ case STPSymbols.TokenSHIFTRIGHT:
+ case STPSymbols.TokenSHIFTLEFT:
+ case STPSymbols.TokenDELETE:
+ case STPSymbols.TokenNEW:
+ nextToken();
+ return fToken == STPSymbols.TokenOPERATOR;
+ case STPSymbols.TokenRPAREN:
+ nextToken();
+ if (fToken != STPSymbols.TokenLPAREN)
+ return false;
+ nextToken();
+ return fToken == STPSymbols.TokenOPERATOR;
+ case STPSymbols.TokenRBRACKET:
+ nextToken();
+ if (fToken != STPSymbols.TokenLBRACKET)
+ return false;
+ nextToken();
+ if (fToken == STPSymbols.TokenNEW || fToken == STPSymbols.TokenDELETE)
+ nextToken();
+ return fToken == STPSymbols.TokenOPERATOR;
+ case STPSymbols.TokenOTHER:
+ if (getTokenContent().length() == 1) {
+ nextToken();
+ if (fToken == STPSymbols.TokenOPERATOR)
+ return true;
+ }
+ if (getTokenContent().length() == 1) {
+ nextToken();
+ if (fToken == STPSymbols.TokenOPERATOR)
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Returns <code>true</code> if the current tokens look like an anonymous type declaration
+ * header (i.e. a type name (potentially qualified) and a new keyword). The heuristic calls
+ * <code>nextToken</code> and expects a possibly qualified identifier (type name) and a new
+ * keyword
+ *
+ * @return <code>true</code> if the current position looks like a anonymous type declaration
+ * header.
+ */
+ private boolean looksLikeAnonymousTypeDecl() {
+ nextToken();
+ if (fToken == STPSymbols.TokenIDENT) { // type name
+ nextToken();
+ while (fToken == STPSymbols.TokenOTHER) { // dot of qualification
+ nextToken();
+ if (fToken != STPSymbols.TokenIDENT) // qualifying name
+ return false;
+ nextToken();
+ }
+ return fToken == STPSymbols.TokenNEW;
+ }
+ return false;
+ }
+
+ /**
+ * Returns <code>true</code> if the current tokens look like beginning of a method
+ * call (i.e. an identifier as opposed to a keyword taking parenthesized parameters
+ * such as <code>if</code>).
+ * <p>The heuristic calls <code>nextToken</code> and expects an identifier
+ * (method name).
+ *
+ * @return <code>true</code> if the current position looks like a method call
+ * header.
+ */
+ private boolean looksLikeMethodCall() {
+ nextToken();
+ if (fToken == STPSymbols.TokenGREATERTHAN) {
+ if (!skipScope())
+ return false;
+ nextToken();
+ }
+ return fToken == STPSymbols.TokenIDENT; // method name
+ }
+
+ /**
+ * Scans tokens for the matching opening peer. The internal cursor
+ * (<code>fPosition</code>) is set to the offset of the opening peer if found.
+ *
+ * @param openToken the opening peer token
+ * @param closeToken the closing peer token
+ * @return <code>true</code> if a matching token was found, <code>false</code>
+ * otherwise
+ */
+ private boolean skipScope(int openToken, int closeToken) {
+ int depth= 1;
+
+ while (true) {
+ nextToken();
+
+ if (fToken == closeToken) {
+ depth++;
+ } else if (fToken == openToken) {
+ depth--;
+ if (depth == 0)
+ return true;
+ } else if (fToken == STPSymbols.TokenEOF) {
+ return false;
+ }
+ }
+ }
}
diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/STPMetadataSingleton.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/STPMetadataSingleton.java
index c91f2d3226..347521bcb6 100644
--- a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/STPMetadataSingleton.java
+++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/STPMetadataSingleton.java
@@ -29,106 +29,106 @@ import org.eclipse.linuxtools.systemtap.structures.TreeNode;
*/
public final class STPMetadataSingleton {
- public static String[] NO_MATCHES = new String[0];
-
- private static STPMetadataSingleton instance = null;
-
- private STPMetadataSingleton() {
- TapsetLibrary.init();
- }
-
- public static STPMetadataSingleton getInstance() {
- if (instance == null) {
- instance = new STPMetadataSingleton();
- }
- return instance;
- }
-
- public void waitForInitialization() {
- TapsetLibrary.waitForInitialization();
- }
-
- public String[] getFunctionCompletions(String prefix) {
- TreeNode node = TapsetLibrary.getFunctions();
- return getMatchingChildren(node, prefix);
- }
-
- public String[] getProbeCompletions(String prefix) {
- List<String> matches = new LinkedList<>();
- String groupName = extractProbeGroupName(prefix);
-
- for (TreeNode node : getEachProbeCategoryNode()) {
- if (node == null) {
- continue;
- }
-
- TreeNode groupNode = node.getChildByName(groupName);
- if (groupNode != null) {
- node = groupNode;
- }
-
- matches.addAll(Arrays.asList(getMatchingChildren(node, prefix)));
- }
-
- return !matches.isEmpty() ? matches.toArray(new String[matches.size()]) : NO_MATCHES;
- }
-
- /**
- * Returns a list of variables available in the given probe.
- * @param probe The probe for which to find variables
- * @param prefix The prefix to complete.
- * @return a list of variables matching the prefix.
- */
- public String[] getProbeVariableCompletions(String probe, String prefix) {
- // The only probes that may have avilable variables are non-static ones.
- TreeNode node = TapsetLibrary.getProbeAliases();
- if (node == null) {
- return NO_MATCHES;
- }
-
- node = node.getChildByName(extractProbeGroupName(probe));
- if (node == null) {
- return NO_MATCHES;
- }
-
- node = node.getChildByName(probe);
- if (node == null) {
- return NO_MATCHES;
- }
-
- return getMatchingChildren(node, prefix);
- }
-
- private TreeNode[] getEachProbeCategoryNode() {
- return new TreeNode[]{TapsetLibrary.getStaticProbes(), TapsetLibrary.getProbeAliases()};
- }
-
- private String[] getMatchingChildren(TreeNode node, String prefix) {
- ArrayList<String> matches = new ArrayList<>();
-
- int n = node.getChildCount();
- for (int i = 0; i < n; i++) {
- if (node.getChildAt(i).toString().startsWith(prefix)) {
- matches.add(node.getChildAt(i).toString());
- }
- }
-
- return matches.toArray(new String[0]);
- }
-
- 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;
- }
+ public static String[] NO_MATCHES = new String[0];
+
+ private static STPMetadataSingleton instance = null;
+
+ private STPMetadataSingleton() {
+ TapsetLibrary.init();
+ }
+
+ public static STPMetadataSingleton getInstance() {
+ if (instance == null) {
+ instance = new STPMetadataSingleton();
+ }
+ return instance;
+ }
+
+ public void waitForInitialization() {
+ TapsetLibrary.waitForInitialization();
+ }
+
+ public String[] getFunctionCompletions(String prefix) {
+ TreeNode node = TapsetLibrary.getFunctions();
+ return getMatchingChildren(node, prefix);
+ }
+
+ public String[] getProbeCompletions(String prefix) {
+ List<String> matches = new LinkedList<>();
+ String groupName = extractProbeGroupName(prefix);
+
+ for (TreeNode node : getEachProbeCategoryNode()) {
+ if (node == null) {
+ continue;
+ }
+
+ TreeNode groupNode = node.getChildByName(groupName);
+ if (groupNode != null) {
+ node = groupNode;
+ }
+
+ matches.addAll(Arrays.asList(getMatchingChildren(node, prefix)));
+ }
+
+ return !matches.isEmpty() ? matches.toArray(new String[matches.size()]) : NO_MATCHES;
+ }
+
+ /**
+ * Returns a list of variables available in the given probe.
+ * @param probe The probe for which to find variables
+ * @param prefix The prefix to complete.
+ * @return a list of variables matching the prefix.
+ */
+ public String[] getProbeVariableCompletions(String probe, String prefix) {
+ // The only probes that may have avilable variables are non-static ones.
+ TreeNode node = TapsetLibrary.getProbeAliases();
+ if (node == null) {
+ return NO_MATCHES;
+ }
+
+ node = node.getChildByName(extractProbeGroupName(probe));
+ if (node == null) {
+ return NO_MATCHES;
+ }
+
+ node = node.getChildByName(probe);
+ if (node == null) {
+ return NO_MATCHES;
+ }
+
+ return getMatchingChildren(node, prefix);
+ }
+
+ private TreeNode[] getEachProbeCategoryNode() {
+ return new TreeNode[]{TapsetLibrary.getStaticProbes(), TapsetLibrary.getProbeAliases()};
+ }
+
+ private String[] getMatchingChildren(TreeNode node, String prefix) {
+ ArrayList<String> matches = new ArrayList<>();
+
+ int n = node.getChildCount();
+ for (int i = 0; i < n; i++) {
+ if (node.getChildAt(i).toString().startsWith(prefix)) {
+ matches.add(node.getChildAt(i).toString());
+ }
+ }
+
+ return matches.toArray(new String[0]);
+ }
+
+ 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;
+ }
}
diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/STPPartitionScanner.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/STPPartitionScanner.java
index dec239de04..de959ce0e8 100644
--- a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/STPPartitionScanner.java
+++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/STPPartitionScanner.java
@@ -1,13 +1,13 @@
/*******************************************************************************
* Copyright (c) 2008 Phil Muldoon <pkmuldoon@picobot.org>.
- *
+ *
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
- * Phil Muldoon <pkmuldoon@picobot.org> - initial API and implementation.
+ * Phil Muldoon <pkmuldoon@picobot.org> - initial API and implementation.
*******************************************************************************/
package org.eclipse.linuxtools.internal.systemtap.ui.ide.editors.stp;
@@ -24,73 +24,73 @@ import org.eclipse.jface.text.rules.Token;
import org.eclipse.jface.text.rules.WordRule;
public class STPPartitionScanner extends RuleBasedPartitionScanner {
- public final static String STP_PARTITIONING = "__stp_partitioning"; //$NON-NLS-1$
-
- public final static String STP_STRING = "__stp_string"; //$NON-NLS-1$
- public final static String STP_COMMENT = "__stp_comment"; //$NON-NLS-1$
- public final static String STP_CONDITIONAL = "__stp_conditional"; //$NON-NLS-1$
- public final static String STP_MULTILINE_COMMENT = "__stp_multiline_comment"; //$NON-NLS-1$
-
- public static String[] STP_PARTITION_TYPES = { IDocument.DEFAULT_CONTENT_TYPE,
- STP_COMMENT, STP_MULTILINE_COMMENT, STP_STRING, STP_CONDITIONAL};
-
- /**
- * Detect empty comments
- */
- private static class EmptyCommentDetector implements IWordDetector {
- @Override
- public boolean isWordStart(char c) {
- return (c == '/');
- }
-
- @Override
- public boolean isWordPart(char c) {
- return (c == '*' || c == '/');
- }
- }
-
- /**
- * Cope with the empty comment issue.
- */
- private static class EmptyCommentRule extends WordRule implements IPredicateRule {
-
- private IToken fSuccessToken;
-
- public EmptyCommentRule(IToken successToken) {
- super(new EmptyCommentDetector());
- fSuccessToken= successToken;
- addWord("/**/", fSuccessToken); //$NON-NLS-1$
- }
-
- @Override
- public IToken evaluate(ICharacterScanner scanner, boolean resume) {
- return evaluate(scanner);
- }
-
- @Override
- public IToken getSuccessToken() {
- return fSuccessToken;
- }
- }
-
- public STPPartitionScanner() {
-
- IToken stpComment = new Token(STP_COMMENT);
- IToken stpMultilineComment = new Token(STP_MULTILINE_COMMENT);
- IToken stpConditional = new Token(STP_CONDITIONAL);
- IToken stpString = new Token(STP_STRING);
-
- // Add special case word rule.
- EmptyCommentRule emptyCommentRule= new EmptyCommentRule(stpComment);
+ public final static String STP_PARTITIONING = "__stp_partitioning"; //$NON-NLS-1$
+
+ public final static String STP_STRING = "__stp_string"; //$NON-NLS-1$
+ public final static String STP_COMMENT = "__stp_comment"; //$NON-NLS-1$
+ public final static String STP_CONDITIONAL = "__stp_conditional"; //$NON-NLS-1$
+ public final static String STP_MULTILINE_COMMENT = "__stp_multiline_comment"; //$NON-NLS-1$
+
+ public static String[] STP_PARTITION_TYPES = { IDocument.DEFAULT_CONTENT_TYPE,
+ STP_COMMENT, STP_MULTILINE_COMMENT, STP_STRING, STP_CONDITIONAL};
+
+ /**
+ * Detect empty comments
+ */
+ private static class EmptyCommentDetector implements IWordDetector {
+ @Override
+ public boolean isWordStart(char c) {
+ return (c == '/');
+ }
+
+ @Override
+ public boolean isWordPart(char c) {
+ return (c == '*' || c == '/');
+ }
+ }
+
+ /**
+ * Cope with the empty comment issue.
+ */
+ private static class EmptyCommentRule extends WordRule implements IPredicateRule {
+
+ private IToken fSuccessToken;
+
+ public EmptyCommentRule(IToken successToken) {
+ super(new EmptyCommentDetector());
+ fSuccessToken= successToken;
+ addWord("/**/", fSuccessToken); //$NON-NLS-1$
+ }
+
+ @Override
+ public IToken evaluate(ICharacterScanner scanner, boolean resume) {
+ return evaluate(scanner);
+ }
+
+ @Override
+ public IToken getSuccessToken() {
+ return fSuccessToken;
+ }
+ }
+
+ public STPPartitionScanner() {
+
+ IToken stpComment = new Token(STP_COMMENT);
+ IToken stpMultilineComment = new Token(STP_MULTILINE_COMMENT);
+ IToken stpConditional = new Token(STP_CONDITIONAL);
+ IToken stpString = new Token(STP_STRING);
+
+ // Add special case word rule.
+ EmptyCommentRule emptyCommentRule= new EmptyCommentRule(stpComment);
setPredicateRules(new IPredicateRule[] {
- new EndOfLineRule("//", stpComment), //$NON-NLS-1$
- new MultiLineRule("/*", "*/", stpMultilineComment), //$NON-NLS-1$//$NON-NLS-2$
+ new EndOfLineRule("//", stpComment), //$NON-NLS-1$
+ new MultiLineRule("/*", "*/", stpMultilineComment), //$NON-NLS-1$//$NON-NLS-2$
new EndOfLineRule("#", stpComment), //$NON-NLS-1$
- emptyCommentRule,
- new SingleLineRule("\"", "\"", stpString, '\\', false, true), //$NON-NLS-1$ //$NON-NLS-2$
+ emptyCommentRule,
+ new SingleLineRule("\"", "\"", stpString, '\\', false, true), //$NON-NLS-1$ //$NON-NLS-2$
new MultiLineRule("%(", "%)", stpConditional), //$NON-NLS-1$ //$NON-NLS-2$
});
- }
+ }
}
diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/STPPartitioner.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/STPPartitioner.java
index 5ed8a3344b..41643489f6 100644
--- a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/STPPartitioner.java
+++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/STPPartitioner.java
@@ -15,17 +15,17 @@ import org.eclipse.jface.text.rules.IPartitionTokenScanner;
public class STPPartitioner extends FastPartitioner {
- /**
- * Straight forward FastPartitioner, with debug output.
- *
- * Taken directly from org.eclipse.linuxtools.rpm.ui.editor.SpecFilePartitioner.
- * No noteworthy alterations so Copyright header and license text untouched.
- *
- * @param scanner
- * @param legalContentTypes
- */
- public STPPartitioner(IPartitionTokenScanner scanner, String[] legalContentTypes) {
- super(scanner, legalContentTypes);
- }
+ /**
+ * Straight forward FastPartitioner, with debug output.
+ *
+ * Taken directly from org.eclipse.linuxtools.rpm.ui.editor.SpecFilePartitioner.
+ * No noteworthy alterations so Copyright header and license text untouched.
+ *
+ * @param scanner
+ * @param legalContentTypes
+ */
+ public STPPartitioner(IPartitionTokenScanner scanner, String[] legalContentTypes) {
+ super(scanner, legalContentTypes);
+ }
}
diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/STPProbeScanner.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/STPProbeScanner.java
index fcd4358843..7e96af4e25 100644
--- a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/STPProbeScanner.java
+++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/STPProbeScanner.java
@@ -1,13 +1,13 @@
/*******************************************************************************
* Copyright (c) 2008, 2013 Phil Muldoon <pkmuldoon@picobot.org>.
- *
+ *
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
- * Phil Muldoon <pkmuldoon@picobot.org> - initial API and implementation.
+ * Phil Muldoon <pkmuldoon@picobot.org> - initial API and implementation.
* Red Hat Inc. - modification for use in probe scanning
*******************************************************************************/
package org.eclipse.linuxtools.internal.systemtap.ui.ide.editors.stp;
@@ -22,35 +22,35 @@ import org.eclipse.jface.text.rules.SingleLineRule;
import org.eclipse.jface.text.rules.Token;
public class STPProbeScanner extends RuleBasedPartitionScanner {
- public final static String STP_STRING = "__stp_string"; //$NON-NLS-1$
- public final static String STP_PROBE = "__stp_probe"; //$NON-NLS-1$
- public final static String STP_CONDITIONAL = "__stp_conditional"; //$NON-NLS-1$
- public final static String STP_COMMENT = "__stp_comment"; //$NON-NLS-1$
-
- public final static String STP_PROBE_PARTITIONING = "__stp_probe_partitioning"; //$NON-NLS-1$
-
- public static String[] STP_PROBE_PARTITION_TYPES = { IDocument.DEFAULT_CONTENT_TYPE,
- STP_COMMENT, STP_STRING, STP_PROBE, STP_CONDITIONAL};
-
- public STPProbeScanner() {
-
- IToken stpString = new Token(STP_STRING);
- IToken stpProbe = new Token(STP_PROBE);
- IToken stpComment = new Token(STP_COMMENT);
- IToken stpConditional = new Token(STP_CONDITIONAL);
+ public final static String STP_STRING = "__stp_string"; //$NON-NLS-1$
+ public final static String STP_PROBE = "__stp_probe"; //$NON-NLS-1$
+ public final static String STP_CONDITIONAL = "__stp_conditional"; //$NON-NLS-1$
+ public final static String STP_COMMENT = "__stp_comment"; //$NON-NLS-1$
+
+ public final static String STP_PROBE_PARTITIONING = "__stp_probe_partitioning"; //$NON-NLS-1$
+
+ public static String[] STP_PROBE_PARTITION_TYPES = { IDocument.DEFAULT_CONTENT_TYPE,
+ STP_COMMENT, STP_STRING, STP_PROBE, STP_CONDITIONAL};
+
+ public STPProbeScanner() {
+
+ IToken stpString = new Token(STP_STRING);
+ IToken stpProbe = new Token(STP_PROBE);
+ IToken stpComment = new Token(STP_COMMENT);
+ IToken stpConditional = new Token(STP_CONDITIONAL);
setPredicateRules(new IPredicateRule[] {
- new EndOfLineRule("//", stpComment), //$NON-NLS-1$
- new MultiLineRule("/*", "*/", stpComment), //$NON-NLS-1$//$NON-NLS-2$
- new EndOfLineRule("#", stpComment), //$NON-NLS-1$
+ new EndOfLineRule("//", stpComment), //$NON-NLS-1$
+ new MultiLineRule("/*", "*/", stpComment), //$NON-NLS-1$//$NON-NLS-2$
+ new EndOfLineRule("#", stpComment), //$NON-NLS-1$
new EndOfLineRule("#if", stpConditional), //$NON-NLS-1$
new EndOfLineRule("#else", stpConditional), //$NON-NLS-1$
new EndOfLineRule("#endif", stpConditional), //$NON-NLS-1$
new EndOfLineRule("#define", stpConditional), //$NON-NLS-1$
- new SingleLineRule("\"", "\"", stpString, '\\', false, true), //$NON-NLS-1$ //$NON-NLS-2$
- new SingleLineRule("'", "'", stpString, '\\'), //$NON-NLS-1$ //$NON-NLS-2$
+ new SingleLineRule("\"", "\"", stpString, '\\', false, true), //$NON-NLS-1$ //$NON-NLS-2$
+ new SingleLineRule("'", "'", stpString, '\\'), //$NON-NLS-1$ //$NON-NLS-2$
new MultiLineRule("probe", "}", stpProbe), //$NON-NLS-1$ //$NON-NLS-2$
});
- }
+ }
}
diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/STPReconcilingStrategy.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/STPReconcilingStrategy.java
index f4a536f826..f3b3383a3b 100644
--- a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/STPReconcilingStrategy.java
+++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/STPReconcilingStrategy.java
@@ -33,7 +33,7 @@ import org.eclipse.swt.widgets.Display;
public class STPReconcilingStrategy implements IReconcilingStrategy,
IReconcilingStrategyExtension {
- // Constants
+ // Constants
protected static final int STP_NO_TAG = 0;
protected static final int STP_MULTILINE_COMMENT_TAG = 1;
protected static final int STP_PROBE = 2;
@@ -48,8 +48,8 @@ public class STPReconcilingStrategy implements IReconcilingStrategy,
// Current tag end
protected int currentTagEnd = 0;
- // List of positions
- protected final ArrayList<Position> documentPositionList = new ArrayList<>();
+ // List of positions
+ protected final ArrayList<Position> documentPositionList = new ArrayList<>();
// The end offset of the range to be scanned *//*
protected int endOfDocumentPostion;
@@ -61,67 +61,67 @@ public class STPReconcilingStrategy implements IReconcilingStrategy,
* Sets the current editor.
*/
public void setEditor(STPEditor editor) {
- this.currentEditor = editor;
+ this.currentEditor = editor;
}
/**
* Sets the current (ie working) document.
*/
@Override
- public void setDocument(IDocument document) {
- this.currentDocument = document;
+ public void setDocument(IDocument document) {
+ this.currentDocument = document;
}
- /* (non-Javadoc)
- * @see org.eclipse.jface.text.reconciler.IReconcilingStrategy#reconcile(org.eclipse.jface.text.IRegion)
- */
- @Override
- public void reconcile(IRegion partition) {
- // Just rebuild the whole document
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.text.reconciler.IReconcilingStrategy#reconcile(org.eclipse.jface.text.IRegion)
+ */
+ @Override
+ public void reconcile(IRegion partition) {
+ // Just rebuild the whole document
initialReconcile();
- }
+ }
- /* (non-Javadoc)
- * @see org.eclipse.jface.text.reconciler.IReconcilingStrategy#reconcile(org.eclipse.jface.text.reconciler.DirtyRegion, org.eclipse.jface.text.IRegion)
- */
- @Override
- public void reconcile(DirtyRegion dirtyRegion, IRegion subRegion) {
- //Just rebuild the whole document
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.text.reconciler.IReconcilingStrategy#reconcile(org.eclipse.jface.text.reconciler.DirtyRegion, org.eclipse.jface.text.IRegion)
+ */
+ @Override
+ public void reconcile(DirtyRegion dirtyRegion, IRegion subRegion) {
+ //Just rebuild the whole document
initialReconcile();
- }
+ }
- /* (non-Javadoc)
- * @see org.eclipse.jface.text.reconciler.IReconcilingStrategyExtension#initialReconcile()
- */
- @Override
- public void initialReconcile() {
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.text.reconciler.IReconcilingStrategyExtension#initialReconcile()
+ */
+ @Override
+ public void initialReconcile() {
endOfDocumentPostion = currentDocument.getLength();
try {
- calculatePositions();
- } catch (BadLocationException e) {
- // Cannot reconcile, return
- return;
- }
- }
+ calculatePositions();
+ } catch (BadLocationException e) {
+ // Cannot reconcile, return
+ return;
+ }
+ }
- /* (non-Javadoc)
- * @see org.eclipse.jface.text.reconciler.IReconcilingStrategyExtension#setProgressMonitor(org.eclipse.core.runtime.IProgressMonitor)
- */
- @Override
- public void setProgressMonitor(IProgressMonitor monitor) {
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.text.reconciler.IReconcilingStrategyExtension#setProgressMonitor(org.eclipse.core.runtime.IProgressMonitor)
+ */
+ @Override
+ public void setProgressMonitor(IProgressMonitor monitor) {
- }
+ }
- /**
- *
- * From currentDocument, calculate beginning of document
- * to endOfDocumentPostion to build positions for code folding.
- *
- * @throws BadLocationException
- */
- private void calculatePositions() throws BadLocationException {
- // Clear old positions and reset to beginning of document
- documentPositionList.clear();
+ /**
+ *
+ * From currentDocument, calculate beginning of document
+ * to endOfDocumentPostion to build positions for code folding.
+ *
+ * @throws BadLocationException
+ */
+ private void calculatePositions() throws BadLocationException {
+ // Clear old positions and reset to beginning of document
+ documentPositionList.clear();
nextCharPosition = 0;
// Build the actual document positions
@@ -130,87 +130,87 @@ public class STPReconcilingStrategy implements IReconcilingStrategy,
// Paint the folding annotations in the background.
Display.getDefault().asyncExec(new Runnable() {
@Override
- public void run() {
- currentEditor.updateFoldingStructure(documentPositionList);
+ public void run() {
+ currentEditor.updateFoldingStructure(documentPositionList);
}
});
- }
+ }
- /**
- *
- * Start trying to guess if given char z, what - if any - tag this
- * begins.
- *
- * @param location - location of current position
- * @return - tag type, if any
- *
- * @throws BadLocationException
- */
- private int classifyComponent(int location) throws BadLocationException {
+ /**
+ *
+ * Start trying to guess if given char z, what - if any - tag this
+ * begins.
+ *
+ * @param location - location of current position
+ * @return - tag type, if any
+ *
+ * @throws BadLocationException
+ */
+ private int classifyComponent(int location) throws BadLocationException {
int deltaLocation = location;
- char ch = currentDocument.getChar(deltaLocation);
+ char ch = currentDocument.getChar(deltaLocation);
switch (ch) {
- // The 'comment' case.
- case '/':
- deltaLocation++;
- ch = currentDocument.getChar(deltaLocation);
- if (ch == '*') {
- currentTagStart = location;
- deltaLocation++;
- nextCharPosition = deltaLocation;
- return STP_MULTILINE_COMMENT_TAG;
- }
- break;
- // The 'probe' case.
- case 'p':
- if (isProbe()) {
- currentTagStart = location;
- return STP_PROBE;
- }
+ // The 'comment' case.
+ case '/':
+ deltaLocation++;
+ ch = currentDocument.getChar(deltaLocation);
+ if (ch == '*') {
+ currentTagStart = location;
+ deltaLocation++;
+ nextCharPosition = deltaLocation;
+ return STP_MULTILINE_COMMENT_TAG;
+ }
+ break;
+ // The 'probe' case.
+ case 'p':
+ if (isProbe()) {
+ currentTagStart = location;
+ return STP_PROBE;
+ }
- // The 'function' case.
- case 'f':
- if (isFunction()) {
- currentTagStart = location;
- return STP_FUNCTION;
- }
- // No tag, don't fold region.
- default:
- break;
+ // The 'function' case.
+ case 'f':
+ if (isFunction()) {
+ currentTagStart = location;
+ return STP_FUNCTION;
+ }
+ // No tag, don't fold region.
+ default:
+ break;
}
return STP_NO_TAG;
- }
+ }
- /**
- *
- * Build a list of locations to mark beginning and end of folding regions.
- *
- * @throws BadLocationException
- */
- private void buildPositions() throws BadLocationException {
+ /**
+ *
+ * Build a list of locations to mark beginning and end of folding regions.
+ *
+ * @throws BadLocationException
+ */
+ private void buildPositions() throws BadLocationException {
while (nextCharPosition < endOfDocumentPostion) {
- switch (classifyComponent(nextCharPosition))
- {
- // All of these cases have found the beginning of a tag
- // to start folding. Each element must now be find
- // the end of the region it represents.
- case STP_MULTILINE_COMMENT_TAG:
- currentTagEnd = findEndOfComment();
- writePosition(currentTagStart,currentTagEnd);
- nextCharPosition = currentTagStart + currentTagEnd;
- break;
- case STP_PROBE:
- case STP_FUNCTION:
- currentTagEnd = findEndOfProbeOrFunction();
- writePosition(currentTagStart,currentTagEnd);
- nextCharPosition = currentTagStart + currentTagEnd;
- break;
- default:
- nextCharPosition++;
- break;
+ switch (classifyComponent(nextCharPosition))
+ {
+ // All of these cases have found the beginning of a tag
+ // to start folding. Each element must now be find
+ // the end of the region it represents.
+ case STP_MULTILINE_COMMENT_TAG:
+ currentTagEnd = findEndOfComment();
+ writePosition(currentTagStart,currentTagEnd);
+ nextCharPosition = currentTagStart + currentTagEnd;
+ break;
+ case STP_PROBE:
+ case STP_FUNCTION:
+ currentTagEnd = findEndOfProbeOrFunction();
+ writePosition(currentTagStart,currentTagEnd);
+ nextCharPosition = currentTagStart + currentTagEnd;
+ break;
+ default:
+ nextCharPosition++;
+ break;
}
}
- }
+ }
/**
*
@@ -221,65 +221,65 @@ public class STPReconcilingStrategy implements IReconcilingStrategy,
*
*/
private void writePosition(int startOffset, int length) {
- if (length > 0)
- documentPositionList.add(new Position(startOffset, length));
+ if (length > 0)
+ documentPositionList.add(new Position(startOffset, length));
}
private boolean isProbe() throws BadLocationException {
- return matchKeyWord("probe"); //$NON-NLS-1$
+ return matchKeyWord("probe"); //$NON-NLS-1$
}
private boolean isFunction() throws BadLocationException {
- return matchKeyWord("function"); //$NON-NLS-1$
+ return matchKeyWord("function"); //$NON-NLS-1$
}
private boolean matchKeyWord(String word) throws BadLocationException {
- StringBuffer keyWord = new StringBuffer();
- int location = nextCharPosition;
- while (location < endOfDocumentPostion) {
- char ch = currentDocument.getChar(location);
- if ((ch == ' ') || (!Character.isLetter(ch)))
- break;
- else
- keyWord.append(ch);
- location++;
- }
- if (keyWord.toString().compareTo(word) == 0)
- return true;
- return false;
+ StringBuffer keyWord = new StringBuffer();
+ int location = nextCharPosition;
+ while (location < endOfDocumentPostion) {
+ char ch = currentDocument.getChar(location);
+ if ((ch == ' ') || (!Character.isLetter(ch)))
+ break;
+ else
+ keyWord.append(ch);
+ location++;
+ }
+ if (keyWord.toString().compareTo(word) == 0)
+ return true;
+ return false;
}
private int findEndOfProbeOrFunction() throws BadLocationException {
- int bracketCount = 0;
- boolean firstBracket = false;
- char ch;
+ int bracketCount = 0;
+ boolean firstBracket = false;
+ char ch;
- while (nextCharPosition < endOfDocumentPostion) {
- ch = currentDocument.getChar(nextCharPosition);
- if (ch == '{') {
- firstBracket = true;
- bracketCount++;
- }
- if (ch == '}')
- bracketCount--;
- if ((bracketCount == 0) && (firstBracket))
- return (nextCharPosition-currentTagStart)+2;
- nextCharPosition++;
- }
- return -1;
+ while (nextCharPosition < endOfDocumentPostion) {
+ ch = currentDocument.getChar(nextCharPosition);
+ if (ch == '{') {
+ firstBracket = true;
+ bracketCount++;
+ }
+ if (ch == '}')
+ bracketCount--;
+ if ((bracketCount == 0) && (firstBracket))
+ return (nextCharPosition-currentTagStart)+2;
+ nextCharPosition++;
+ }
+ return -1;
}
private int findEndOfComment() throws BadLocationException {
- while (nextCharPosition < endOfDocumentPostion) {
- char ch = currentDocument.getChar(nextCharPosition);
- if (ch == '*') {
- nextCharPosition++;
- ch = currentDocument.getChar(nextCharPosition);
- if (ch == '/')
- return (nextCharPosition-currentTagStart)+2;
- }
- nextCharPosition++;
- }
- return -1;
+ while (nextCharPosition < endOfDocumentPostion) {
+ char ch = currentDocument.getChar(nextCharPosition);
+ if (ch == '*') {
+ nextCharPosition++;
+ ch = currentDocument.getChar(nextCharPosition);
+ if (ch == '/')
+ return (nextCharPosition-currentTagStart)+2;
+ }
+ nextCharPosition++;
+ }
+ return -1;
}
} \ No newline at end of file
diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/STPSymbols.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/STPSymbols.java
index a506cef9a3..2113ba3e4a 100644
--- a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/STPSymbols.java
+++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/STPSymbols.java
@@ -17,63 +17,63 @@ package org.eclipse.linuxtools.internal.systemtap.ui.ide.editors.stp;
* Symbols for the heuristic STP scanner.
*/
public interface STPSymbols {
- int TokenEOF= -1;
- int TokenLBRACE= 1;
- int TokenRBRACE= 2;
- int TokenLBRACKET= 3;
- int TokenRBRACKET= 4;
- int TokenLPAREN= 5;
- int TokenRPAREN= 6;
- int TokenSEMICOLON= 7;
- int TokenOTHER= 8;
- int TokenCOLON= 9;
- int TokenQUESTIONMARK= 10;
- int TokenCOMMA= 11;
- int TokenEQUAL= 12;
- int TokenLESSTHAN= 13;
- int TokenGREATERTHAN= 14;
- int TokenDOT= 15;
- int TokenMINUS= 16;
- int TokenTILDE= 17;
- int TokenSHIFTRIGHT= 18;
- int TokenARROW= 19;
- int TokenDOUBLECOLON= 20;
- int TokenSHIFTLEFT= 21;
- int TokenPLUS= 22;
- int TokenAGGREGATE= 23;
- int TokenIF= 109;
- int TokenDO= 1010;
- int TokenFOR= 1011;
- int TokenTRY= 1012;
- int TokenCASE= 1013;
- int TokenELSE= 1014;
- int TokenBREAK= 1015;
- int TokenCATCH= 1016;
- int TokenWHILE= 1017;
- int TokenRETURN= 1018;
- int TokenSTATIC= 1019;
- int TokenSWITCH= 1020;
- int TokenGOTO= 1021;
- int TokenDEFAULT= 1022;
- int TokenPRIVATE= 1023;
- int TokenPROTECTED= 1024;
- int TokenPUBLIC= 1025;
- int TokenNEW= 1026;
- int TokenDELETE= 1027;
- int TokenCLASS= 1028;
- int TokenSTRUCT= 1029;
- int TokenUNION= 1030;
- int TokenENUM= 1031;
- int TokenVIRTUAL= 1032;
- int TokenNAMESPACE= 1033;
- int TokenOPERATOR= 1034;
- int TokenTHROW= 1035;
- int TokenCONST= 1036;
- int TokenEXTERN= 1037;
- int TokenTYPEDEF= 1038;
- int TokenUSING= 1039;
- int TokenTEMPLATE= 1040;
- int TokenTYPENAME= 1041;
- int TokenFOREACH= 1042;
- int TokenIDENT= 2000;
+ int TokenEOF= -1;
+ int TokenLBRACE= 1;
+ int TokenRBRACE= 2;
+ int TokenLBRACKET= 3;
+ int TokenRBRACKET= 4;
+ int TokenLPAREN= 5;
+ int TokenRPAREN= 6;
+ int TokenSEMICOLON= 7;
+ int TokenOTHER= 8;
+ int TokenCOLON= 9;
+ int TokenQUESTIONMARK= 10;
+ int TokenCOMMA= 11;
+ int TokenEQUAL= 12;
+ int TokenLESSTHAN= 13;
+ int TokenGREATERTHAN= 14;
+ int TokenDOT= 15;
+ int TokenMINUS= 16;
+ int TokenTILDE= 17;
+ int TokenSHIFTRIGHT= 18;
+ int TokenARROW= 19;
+ int TokenDOUBLECOLON= 20;
+ int TokenSHIFTLEFT= 21;
+ int TokenPLUS= 22;
+ int TokenAGGREGATE= 23;
+ int TokenIF= 109;
+ int TokenDO= 1010;
+ int TokenFOR= 1011;
+ int TokenTRY= 1012;
+ int TokenCASE= 1013;
+ int TokenELSE= 1014;
+ int TokenBREAK= 1015;
+ int TokenCATCH= 1016;
+ int TokenWHILE= 1017;
+ int TokenRETURN= 1018;
+ int TokenSTATIC= 1019;
+ int TokenSWITCH= 1020;
+ int TokenGOTO= 1021;
+ int TokenDEFAULT= 1022;
+ int TokenPRIVATE= 1023;
+ int TokenPROTECTED= 1024;
+ int TokenPUBLIC= 1025;
+ int TokenNEW= 1026;
+ int TokenDELETE= 1027;
+ int TokenCLASS= 1028;
+ int TokenSTRUCT= 1029;
+ int TokenUNION= 1030;
+ int TokenENUM= 1031;
+ int TokenVIRTUAL= 1032;
+ int TokenNAMESPACE= 1033;
+ int TokenOPERATOR= 1034;
+ int TokenTHROW= 1035;
+ int TokenCONST= 1036;
+ int TokenEXTERN= 1037;
+ int TokenTYPEDEF= 1038;
+ int TokenUSING= 1039;
+ int TokenTEMPLATE= 1040;
+ int TokenTYPENAME= 1041;
+ int TokenFOREACH= 1042;
+ int TokenIDENT= 2000;
}
diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/handlers/AddStapProbeHandler.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/handlers/AddStapProbeHandler.java
index d4af4ae9fd..1f92e17abd 100644
--- a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/handlers/AddStapProbeHandler.java
+++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/handlers/AddStapProbeHandler.java
@@ -25,107 +25,107 @@ import org.eclipse.ui.texteditor.ITextEditor;
public class AddStapProbeHandler extends AbstractHandler {
- @Override
- public Object execute(ExecutionEvent event) throws ExecutionException {
- ITextEditor editor;
- try {
- editor = (ITextEditor) HandlerUtil.getActiveEditor(event);
- } catch (ClassCastException e) {
- throw new ExecutionException(Messages.AddStapProbe_editorError, e);
- }
- IVerticalRulerInfo rulerInfo = (IVerticalRulerInfo) editor.getAdapter(IVerticalRulerInfo.class);
-
- Shell shell = editor.getSite().getShell();
- shell.setCursor(shell.getDisplay().getSystemCursor(
- SWT.CURSOR_WAIT));
- int lineno = rulerInfo.getLineOfLastMouseButtonActivity();
- IDocument document = editor.getDocumentProvider().getDocument(
- editor.getEditorInput());
+ @Override
+ public Object execute(ExecutionEvent event) throws ExecutionException {
+ ITextEditor editor;
+ try {
+ editor = (ITextEditor) HandlerUtil.getActiveEditor(event);
+ } catch (ClassCastException e) {
+ throw new ExecutionException(Messages.AddStapProbe_editorError, e);
+ }
+ IVerticalRulerInfo rulerInfo = (IVerticalRulerInfo) editor.getAdapter(IVerticalRulerInfo.class);
- String s = document.get();
- String[] lines = s.split("\n"); //$NON-NLS-1$
- String line = lines[lineno].trim();
- boolean die = false;
- if (line.isEmpty()) {//eat blank lines
- die = true;
- }
- if (line.startsWith("#")) {//eat preprocessor directives //$NON-NLS-1$
- die = true;
- }
- if (line.startsWith("//")) {//eat C99 comments //$NON-NLS-1$
- die = true;
- }
- if (line.startsWith("/*") && !line.contains("*/") && !line.endsWith("*/")) {//try to eat single-line C comments //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
- die = true;
- }
+ Shell shell = editor.getSite().getShell();
+ shell.setCursor(shell.getDisplay().getSystemCursor(
+ SWT.CURSOR_WAIT));
+ int lineno = rulerInfo.getLineOfLastMouseButtonActivity();
+ IDocument document = editor.getDocumentProvider().getDocument(
+ editor.getEditorInput());
- // gogo find comment segments
- try {
- ArrayList<Integer> commentChunks = new ArrayList<>();
- char[] chars = s.toCharArray();
- int needle = 1;
- int offset = document.getLineOffset(lineno);
- while (needle < chars.length) {
- if (chars[needle - 1] == '/' && chars[needle] == '*') {
- commentChunks.add(needle);
- while (needle < chars.length) {
- if (chars[needle - 1] == '*'
- && chars[needle] == '/') {
- commentChunks.add(needle);
- needle++;
- break;
- }
- needle++;
- }
- }
- needle++;
- }
- for (int i = 0, pair, start, end; i < commentChunks.size(); i++) {
- if (!(commentChunks.get(i).intValue() < offset)) {
- pair = i - i % 2;
- start = commentChunks.get(pair).intValue();
- end = commentChunks.get(pair + 1).intValue();
- if (offset >= start && offset <= end) {
- die = true;
- }
- }
- }
- } catch (BadLocationException excp) {
- ExceptionErrorDialog.openError(Messages.AddStapProbe_unableToInsertProbe, excp);
- }
- if (die) {
- MessageDialog
- .openError(
- PlatformUI.getWorkbench()
- .getActiveWorkbenchWindow()
- .getShell(),
- Messages.CEditor_probeInsertFailed, Messages.CEditor_canNotProbeLine);
- } else {
- IEditorInput in = editor.getEditorInput();
- if (in instanceof FileStoreEditorInput) {
- FileStoreEditorInput input = (FileStoreEditorInput) in;
+ String s = document.get();
+ String[] lines = s.split("\n"); //$NON-NLS-1$
+ String line = lines[lineno].trim();
+ boolean die = false;
+ if (line.isEmpty()) {//eat blank lines
+ die = true;
+ }
+ if (line.startsWith("#")) {//eat preprocessor directives //$NON-NLS-1$
+ die = true;
+ }
+ if (line.startsWith("//")) {//eat C99 comments //$NON-NLS-1$
+ die = true;
+ }
+ if (line.startsWith("/*") && !line.contains("*/") && !line.endsWith("*/")) {//try to eat single-line C comments //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ die = true;
+ }
- IPreferenceStore p = IDEPlugin.getDefault()
- .getPreferenceStore();
- String kernroot = p
- .getString(IDEPreferenceConstants.P_KERNEL_SOURCE);
+ // gogo find comment segments
+ try {
+ ArrayList<Integer> commentChunks = new ArrayList<>();
+ char[] chars = s.toCharArray();
+ int needle = 1;
+ int offset = document.getLineOffset(lineno);
+ while (needle < chars.length) {
+ if (chars[needle - 1] == '/' && chars[needle] == '*') {
+ commentChunks.add(needle);
+ while (needle < chars.length) {
+ if (chars[needle - 1] == '*'
+ && chars[needle] == '/') {
+ commentChunks.add(needle);
+ needle++;
+ break;
+ }
+ needle++;
+ }
+ }
+ needle++;
+ }
+ for (int i = 0, pair, start, end; i < commentChunks.size(); i++) {
+ if (!(commentChunks.get(i).intValue() < offset)) {
+ pair = i - i % 2;
+ start = commentChunks.get(pair).intValue();
+ end = commentChunks.get(pair + 1).intValue();
+ if (offset >= start && offset <= end) {
+ die = true;
+ }
+ }
+ }
+ } catch (BadLocationException excp) {
+ ExceptionErrorDialog.openError(Messages.AddStapProbe_unableToInsertProbe, excp);
+ }
+ if (die) {
+ MessageDialog
+ .openError(
+ PlatformUI.getWorkbench()
+ .getActiveWorkbenchWindow()
+ .getShell(),
+ Messages.CEditor_probeInsertFailed, Messages.CEditor_canNotProbeLine);
+ } else {
+ IEditorInput in = editor.getEditorInput();
+ if (in instanceof FileStoreEditorInput) {
+ FileStoreEditorInput input = (FileStoreEditorInput) in;
- String filepath = input.getURI().getPath();
- String kernrelative = filepath.substring(
- kernroot.length() + 1, filepath.length());
- StringBuffer sb = new StringBuffer();
+ IPreferenceStore p = IDEPlugin.getDefault()
+ .getPreferenceStore();
+ String kernroot = p
+ .getString(IDEPreferenceConstants.P_KERNEL_SOURCE);
- sb.append("probe kernel.statement(\"*@" + kernrelative + ":" + (lineno + 1) + "\")"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ String filepath = input.getURI().getPath();
+ String kernrelative = filepath.substring(
+ kernroot.length() + 1, filepath.length());
+ StringBuffer sb = new StringBuffer();
- sb.append("\n{\n\t\n}\n"); //$NON-NLS-1$
- STPEditor activeSTPEditor = IDESessionSettings.getOrAskForActiveSTPEditor(false);
- if (null != activeSTPEditor) {
- activeSTPEditor.insertText(sb.toString());
- }
- }
- }
- shell.setCursor(null); // Return the cursor to normal
- return null;
- }
+ sb.append("probe kernel.statement(\"*@" + kernrelative + ":" + (lineno + 1) + "\")"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+
+ sb.append("\n{\n\t\n}\n"); //$NON-NLS-1$
+ STPEditor activeSTPEditor = IDESessionSettings.getOrAskForActiveSTPEditor(false);
+ if (null != activeSTPEditor) {
+ activeSTPEditor.insertText(sb.toString());
+ }
+ }
+ }
+ shell.setCursor(null); // Return the cursor to normal
+ return null;
+ }
}
diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/handlers/DefinitionHandler.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/handlers/DefinitionHandler.java
index bf1a52d35c..c279ea24e4 100644
--- a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/handlers/DefinitionHandler.java
+++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/handlers/DefinitionHandler.java
@@ -30,54 +30,54 @@ import org.eclipse.ui.handlers.HandlerUtil;
public class DefinitionHandler extends AbstractHandler {
- @Override
- public Object execute(ExecutionEvent event) {
- TreeDefinitionNode t = getSelection(event);
- if(t == null) {
- return null;
- }
- String filename = t.getDefinition();
- if (filename == null) {
- return null;
- }
- File file = new File(filename);
- OpenFileAction open = new OpenFileAction();
- open.run(file);
- if (open.isSuccessful() && t.getData() instanceof ISearchableNode) {
- IEditorPart editorPart = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().getActiveEditor();
- STPEditor editor = (STPEditor)editorPart;
- editor.jumpToLocation(findDefinitionLine((ISearchableNode) t.getData(), editor) + 1, 0);
- }
- return null;
- }
+ @Override
+ public Object execute(ExecutionEvent event) {
+ TreeDefinitionNode t = getSelection(event);
+ if(t == null) {
+ return null;
+ }
+ String filename = t.getDefinition();
+ if (filename == null) {
+ return null;
+ }
+ File file = new File(filename);
+ OpenFileAction open = new OpenFileAction();
+ open.run(file);
+ if (open.isSuccessful() && t.getData() instanceof ISearchableNode) {
+ IEditorPart editorPart = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().getActiveEditor();
+ STPEditor editor = (STPEditor)editorPart;
+ editor.jumpToLocation(findDefinitionLine((ISearchableNode) t.getData(), editor) + 1, 0);
+ }
+ return null;
+ }
- private TreeDefinitionNode getSelection(ExecutionEvent event) {
- ISelection selection = HandlerUtil.getCurrentSelection(event);
- if (selection instanceof StructuredSelection) {
- Object[] selections = ((StructuredSelection) selection).toArray();
- return (selections.length == 1 && selections[0] instanceof TreeDefinitionNode)
- ? (TreeDefinitionNode) selections[0] : null;
- }
- return null;
- }
+ private TreeDefinitionNode getSelection(ExecutionEvent event) {
+ ISelection selection = HandlerUtil.getCurrentSelection(event);
+ if (selection instanceof StructuredSelection) {
+ Object[] selections = ((StructuredSelection) selection).toArray();
+ return (selections.length == 1 && selections[0] instanceof TreeDefinitionNode)
+ ? (TreeDefinitionNode) selections[0] : null;
+ }
+ return null;
+ }
- private int findDefinitionLine(ISearchableNode data, STPEditor editor) {
- int locationIndex;
- String contents = CommentRemover.exec(editor.getDocumentProvider().getDocument(editor.getEditorInput()).get());
- if (data.isRegexSearch()) {
- Pattern pattern = Pattern.compile(data.getSearchToken());
- Matcher matcher = pattern.matcher(contents);
- locationIndex = matcher.find() ? matcher.start() : -1;
- } else {
- locationIndex = contents.indexOf(data.getSearchToken());
- }
- if (locationIndex != -1) {
- // Get the line of the match by counting newlines.
- contents = contents.substring(0, locationIndex);
- return contents.length() - contents.replaceAll("\n", "").length(); //$NON-NLS-1$ //$NON-NLS-2$
- } else {
- return 0;
- }
- }
+ private int findDefinitionLine(ISearchableNode data, STPEditor editor) {
+ int locationIndex;
+ String contents = CommentRemover.exec(editor.getDocumentProvider().getDocument(editor.getEditorInput()).get());
+ if (data.isRegexSearch()) {
+ Pattern pattern = Pattern.compile(data.getSearchToken());
+ Matcher matcher = pattern.matcher(contents);
+ locationIndex = matcher.find() ? matcher.start() : -1;
+ } else {
+ locationIndex = contents.indexOf(data.getSearchToken());
+ }
+ if (locationIndex != -1) {
+ // Get the line of the match by counting newlines.
+ contents = contents.substring(0, locationIndex);
+ return contents.length() - contents.replaceAll("\n", "").length(); //$NON-NLS-1$ //$NON-NLS-2$
+ } else {
+ return 0;
+ }
+ }
}
diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/handlers/DefinitionMenuTester.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/handlers/DefinitionMenuTester.java
index 904a982fd0..35ea8c98a5 100644
--- a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/handlers/DefinitionMenuTester.java
+++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/handlers/DefinitionMenuTester.java
@@ -16,12 +16,12 @@ import org.eclipse.linuxtools.systemtap.structures.TreeDefinitionNode;
public class DefinitionMenuTester extends PropertyTester {
- @Override
- public boolean test(Object receiver, String property, Object[] args,
- Object expectedValue) {
- return receiver instanceof TreeDefinitionNode
- ? ((TreeDefinitionNode) receiver).getDefinition() != null
- : false;
- }
+ @Override
+ public boolean test(Object receiver, String property, Object[] args,
+ Object expectedValue) {
+ return receiver instanceof TreeDefinitionNode
+ ? ((TreeDefinitionNode) receiver).getDefinition() != null
+ : false;
+ }
}
diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/handlers/Messages.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/handlers/Messages.java
index 92c22977ec..e8a4c102ed 100644
--- a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/handlers/Messages.java
+++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/handlers/Messages.java
@@ -16,16 +16,16 @@ import org.eclipse.osgi.util.NLS;
* @since 2.0
*/
public class Messages extends NLS {
- private static final String BUNDLE_NAME = "org.eclipse.linuxtools.internal.systemtap.ui.ide.handlers.messages"; //$NON-NLS-1$
- public static String AddStapProbe_editorError;
- public static String AddStapProbe_unableToInsertProbe;
- public static String CEditor_probeInsertFailed;
- public static String CEditor_canNotProbeLine;
- static {
- // initialize resource bundle
- NLS.initializeMessages(BUNDLE_NAME, Messages.class);
- }
+ private static final String BUNDLE_NAME = "org.eclipse.linuxtools.internal.systemtap.ui.ide.handlers.messages"; //$NON-NLS-1$
+ public static String AddStapProbe_editorError;
+ public static String AddStapProbe_unableToInsertProbe;
+ public static String CEditor_probeInsertFailed;
+ public static String CEditor_canNotProbeLine;
+ static {
+ // initialize resource bundle
+ NLS.initializeMessages(BUNDLE_NAME, Messages.class);
+ }
- private Messages() {
- }
+ private Messages() {
+ }
}
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 0f98eec25e..ca6b379793 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
@@ -15,98 +15,98 @@ import org.eclipse.osgi.util.NLS;
public class Messages extends NLS {
- private static final String BUNDLE_NAME = "org.eclipse.linuxtools.internal.systemtap.ui.ide.launcher.messages"; //$NON-NLS-1$
-
- public static String SystemTapScriptGraphOptionsTab_cantInitializeTab;
- public static String SystemTapScriptGraphOptionsTab_graphOutputRun;
- public static String SystemTapScriptGraphOptionsTab_graphOutput;
- public static String SystemTapScriptGraphOptionsTab_outputLabel;
- public static String SystemTapScriptGraphOptionsTab_emptyGroup;
- public static String SystemTapScriptGraphOptionsTab_graphingTitle;
- public static String SystemTapScriptGraphOptionsTab_deletedGraphData;
- public static String SystemTapScriptGraphOptionsTab_noGroups;
- public static String SystemTapScriptGraphOptionsTab_badGraphID;
-
- public static String SystemTapScriptGraphOptionsTab_AddGraphButton;
- public static String SystemTapScriptGraphOptionsTab_AddGraphButtonToolTip;
- public static String SystemTapScriptGraphOptionsTab_DuplicateGraphButton;
- public static String SystemTapScriptGraphOptionsTab_DuplicateGraphButtonToolTip;
- public static String SystemTapScriptGraphOptionsTab_EditGraphButton;
- public static String SystemTapScriptGraphOptionsTab_EditGraphButtonToolTip;
-
- public static String SystemTapScriptGraphOptionsTab_columnTitle;
- public static String SystemTapScriptGraphOptionsTab_extractedValueLabel;
- public static String SystemTapScriptGraphOptionsTab_columnShiftUp;
- public static String SystemTapScriptGraphOptionsTab_columnShiftDown;
- public static String SystemTapScriptGraphOptionsTab_defaultColumnTitleBase;
- public static String SystemTapScriptGraphOptionsTab_RemoveGraphButton;
- public static String SystemTapScriptGraphOptionsTab_RemoveGraphButtonToolTip;
- public static String SystemTapScriptGraphOptionsTab_invalidGraph;
- public static String SystemTapScriptGraphOptionsTab_invalidGraphID;
-
- public static String SystemTapScriptGraphOptionsTab_regexErrorMsgFormat;
- public static String SystemTapScriptGraphOptionsTab_regexLabel;
- public static String SystemTapScriptGraphOptionsTab_regexTooltip;
- public static String SystemTapScriptGraphOptionsTab_regexAddNew;
- public static String SystemTapScriptGraphOptionsTab_regexRemove;
- public static String SystemTapScriptGraphOptionsTab_graphSetTitleBase;
-
- public static String SystemTapScriptGraphOptionsTab_removeRegexTitle;
- public static String SystemTapScriptGraphOptionsTab_removeRegexAsk;
-
- public static String SystemTapScriptGraphOptionsTab_sampleOutputLabel;
- public static String SystemTapScriptGraphOptionsTab_sampleOutputTooltip;
- 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_script;
- public static String SystemTapScriptLaunchConfigurationTab_browse;
- public static String SystemTapScriptLaunchConfigurationTab_currentUser;
- public static String SystemTapScriptLaunchConfigurationTab_username;
- public static String SystemTapScriptLaunchConfigurationTab_password;
- public static String SystemTapScriptLaunchConfigurationTab_user;
- public static String SystemTapScriptLaunchConfigurationTab_host;
- public static String SystemTapScriptLaunchConfigurationTab_runLocally;
- public static String SystemTapScriptLaunchConfigurationTab_hostname;
- public static String SystemTapScriptLaunchConfigurationTab_general;
- public static String SystemTapScriptLaunchConfigurationTab_tabName;
- public static String SystemTapScriptLaunchConfigurationTab_selectScript;
-
- public static String SystemTapScriptLaunchConfigurationTab_errorInitializingTab;
- public static String SystemTapScriptLaunchConfigurationTab_options;
- public static String SystemTapScriptLaunchConfigurationTab_runWithChart;
- public static String SystemTapScriptLaunchShortcut_couldNotFindConfig;
- public static String SystemTapScriptLaunchShortcut_couldNotLaunchScript;
- public static String SystemTapScriptLaunchConfigurationTab_fileNotFound;
- public static String SystemTapScriptLaunchConfigurationTab_fileNotStp;
-
- public static String SystemTapScriptOptionsTab_selectExec;
- public static String SystemTapScriptOptionsTab_targetExec;
- public static String SystemTapScriptOptionsTab_otherOptions;
- public static String SystemTapScriptOptionsTab_dyninst;
- public static String SystemTapScriptOptionsTab_dyninstError;
- public static String SystemTapScriptOptionsTab_pidError;
- public static String SystemTapScriptOptionsTab_initializeConfigurationFailed;
- public static String SystemTapScriptOptionsTab_targetToolTip;
-
- public static String SystemTapScriptLaunchError_graph;
- public static String SystemTapScriptLaunchError_fileNotFound;
- public static String SystemTapScriptLaunchError_fileNotStp;
- public static String SystemTapScriptLaunchError_waitForConsoles;
-
- static {
- // initialize resource bundle
- NLS.initializeMessages(BUNDLE_NAME, Messages.class);
- }
-
- private Messages() {
- }
+ private static final String BUNDLE_NAME = "org.eclipse.linuxtools.internal.systemtap.ui.ide.launcher.messages"; //$NON-NLS-1$
+
+ public static String SystemTapScriptGraphOptionsTab_cantInitializeTab;
+ public static String SystemTapScriptGraphOptionsTab_graphOutputRun;
+ public static String SystemTapScriptGraphOptionsTab_graphOutput;
+ public static String SystemTapScriptGraphOptionsTab_outputLabel;
+ public static String SystemTapScriptGraphOptionsTab_emptyGroup;
+ public static String SystemTapScriptGraphOptionsTab_graphingTitle;
+ public static String SystemTapScriptGraphOptionsTab_deletedGraphData;
+ public static String SystemTapScriptGraphOptionsTab_noGroups;
+ public static String SystemTapScriptGraphOptionsTab_badGraphID;
+
+ public static String SystemTapScriptGraphOptionsTab_AddGraphButton;
+ public static String SystemTapScriptGraphOptionsTab_AddGraphButtonToolTip;
+ public static String SystemTapScriptGraphOptionsTab_DuplicateGraphButton;
+ public static String SystemTapScriptGraphOptionsTab_DuplicateGraphButtonToolTip;
+ public static String SystemTapScriptGraphOptionsTab_EditGraphButton;
+ public static String SystemTapScriptGraphOptionsTab_EditGraphButtonToolTip;
+
+ public static String SystemTapScriptGraphOptionsTab_columnTitle;
+ public static String SystemTapScriptGraphOptionsTab_extractedValueLabel;
+ public static String SystemTapScriptGraphOptionsTab_columnShiftUp;
+ public static String SystemTapScriptGraphOptionsTab_columnShiftDown;
+ public static String SystemTapScriptGraphOptionsTab_defaultColumnTitleBase;
+ public static String SystemTapScriptGraphOptionsTab_RemoveGraphButton;
+ public static String SystemTapScriptGraphOptionsTab_RemoveGraphButtonToolTip;
+ public static String SystemTapScriptGraphOptionsTab_invalidGraph;
+ public static String SystemTapScriptGraphOptionsTab_invalidGraphID;
+
+ public static String SystemTapScriptGraphOptionsTab_regexErrorMsgFormat;
+ public static String SystemTapScriptGraphOptionsTab_regexLabel;
+ public static String SystemTapScriptGraphOptionsTab_regexTooltip;
+ public static String SystemTapScriptGraphOptionsTab_regexAddNew;
+ public static String SystemTapScriptGraphOptionsTab_regexRemove;
+ public static String SystemTapScriptGraphOptionsTab_graphSetTitleBase;
+
+ public static String SystemTapScriptGraphOptionsTab_removeRegexTitle;
+ public static String SystemTapScriptGraphOptionsTab_removeRegexAsk;
+
+ public static String SystemTapScriptGraphOptionsTab_sampleOutputLabel;
+ public static String SystemTapScriptGraphOptionsTab_sampleOutputTooltip;
+ 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_script;
+ public static String SystemTapScriptLaunchConfigurationTab_browse;
+ public static String SystemTapScriptLaunchConfigurationTab_currentUser;
+ public static String SystemTapScriptLaunchConfigurationTab_username;
+ public static String SystemTapScriptLaunchConfigurationTab_password;
+ public static String SystemTapScriptLaunchConfigurationTab_user;
+ public static String SystemTapScriptLaunchConfigurationTab_host;
+ public static String SystemTapScriptLaunchConfigurationTab_runLocally;
+ public static String SystemTapScriptLaunchConfigurationTab_hostname;
+ public static String SystemTapScriptLaunchConfigurationTab_general;
+ public static String SystemTapScriptLaunchConfigurationTab_tabName;
+ public static String SystemTapScriptLaunchConfigurationTab_selectScript;
+
+ public static String SystemTapScriptLaunchConfigurationTab_errorInitializingTab;
+ public static String SystemTapScriptLaunchConfigurationTab_options;
+ public static String SystemTapScriptLaunchConfigurationTab_runWithChart;
+ public static String SystemTapScriptLaunchShortcut_couldNotFindConfig;
+ public static String SystemTapScriptLaunchShortcut_couldNotLaunchScript;
+ public static String SystemTapScriptLaunchConfigurationTab_fileNotFound;
+ public static String SystemTapScriptLaunchConfigurationTab_fileNotStp;
+
+ public static String SystemTapScriptOptionsTab_selectExec;
+ public static String SystemTapScriptOptionsTab_targetExec;
+ public static String SystemTapScriptOptionsTab_otherOptions;
+ public static String SystemTapScriptOptionsTab_dyninst;
+ public static String SystemTapScriptOptionsTab_dyninstError;
+ public static String SystemTapScriptOptionsTab_pidError;
+ public static String SystemTapScriptOptionsTab_initializeConfigurationFailed;
+ public static String SystemTapScriptOptionsTab_targetToolTip;
+
+ public static String SystemTapScriptLaunchError_graph;
+ public static String SystemTapScriptLaunchError_fileNotFound;
+ public static String SystemTapScriptLaunchError_fileNotStp;
+ public static String SystemTapScriptLaunchError_waitForConsoles;
+
+ static {
+ // initialize resource bundle
+ NLS.initializeMessages(BUNDLE_NAME, Messages.class);
+ }
+
+ private Messages() {
+ }
}
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 80d66f9ae4..05321a2374 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
@@ -76,1571 +76,1571 @@ import org.eclipse.ui.texteditor.IDocumentProvider;
import org.eclipse.ui.texteditor.ITextEditor;
public class SystemTapScriptGraphOptionsTab extends
- AbstractLaunchConfigurationTab {
-
- /**
- * The maximum number of regular expressions that can be stored in a configuration.
- */
- static final int MAX_NUMBER_OF_REGEXS = 20;
-
- /**
- * The maximum length of an output-parsing regular expression.
- */
- static final int MAX_REGEX_LENGTH = 200;
-
- // Note: any non-private String key with a trailing underscore is to be appended with an integer when looking up values.
- static final String RUN_WITH_CHART = "runWithChart"; //$NON-NLS-1$
- static final String NUMBER_OF_REGEXS = "numberOfRegexs"; //$NON-NLS-1$
- static final String NUMBER_OF_COLUMNS = "numberOfColumns_"; //$NON-NLS-1$
- static final String REGEX_BOX = "regexBox_"; //$NON-NLS-1$
- static final String NUMBER_OF_EXTRAS = "numberOfExtras_"; //$NON-NLS-1$
- static final String EXTRA_BOX = "extraBox_"; //$NON-NLS-1$
- static final String REGULAR_EXPRESSION = "regularExpression_"; //$NON-NLS-1$
- static final String SAMPLE_OUTPUT = "sampleOutput_"; //$NON-NLS-1$
-
- // Note: all graph-related keys point to 2D lists (regular expression & graph number),
- // except for GRAPH_Y_SERIES (which is a 3D list).
- private static final String NUMBER_OF_GRAPHS = "numberOfGraphs"; //$NON-NLS-1$
- private static final String GRAPH_TITLE = "graphTitle"; //$NON-NLS-1$
- private static final String GRAPH_KEY = "graphKey"; //$NON-NLS-1$
- private static final String GRAPH_X_SERIES = "graphXSeries"; //$NON-NLS-1$
- private static final String GRAPH_ID = "graphID"; //$NON-NLS-1$
- private static final String GRAPH_Y_SERIES_LENGTH = "graphYSeriesLength"; //$NON-NLS-1$
- private static final String GRAPH_Y_SERIES = "graphYSeries"; //$NON-NLS-1$
- protected Pattern pattern;
- protected Matcher matcher;
-
- private Combo regularExpressionCombo;
- private Button removeRegexButton;
- private Button generateExpsButton;
-
- private Text sampleOutputText;
- private Composite textFieldsComposite;
-
- /**
- * This value controls whether or not the ModifyListeners associated with
- * the Texts will perform when dispatched. Sometimes the listeners should
- * be disabled to prevent needless/unsafe operations.
- */
- private boolean textListenersEnabled = true;
-
- private ScrolledComposite regexTextScrolledComposite;
- private Group outputParsingGroup;
- private Button runWithChartCheckButton;
-
- private Table graphsTable;
- private Button addGraphButton, duplicateGraphButton, editGraphButton, removeGraphButton;
- private TableItem selectedTableItem;
- private Group graphsGroup;
- private int numberOfVisibleColumns = 0;
- private boolean graphingEnabled = true;
-
- /**
- * A list of error messages, each entry corresponding to an entered regular expression.
- */
- private List<String> regexErrorMessages = new ArrayList<>();
-
- /**
- * The index of the selected regular expression.
- */
- private int selectedRegex = -1;
-
- /**
- * A list containing the user-defined sample outputs associated with the regex of every index.
- */
- private List<String> outputList = new ArrayList<>();
-
- /**
- * A name is given to each group captured by a regular expression. This stack contains
- * the names of all of a regex's groups that have been deleted, so each name may be
- * restored (without having to retype it) when a group is added again.
- */
- private Stack<String> cachedNames;
-
- /**
- * A list of cachedNames stacks, containing one entry for each regular expression stored.
- */
- private List<Stack<String>> cachedNamesList = new ArrayList<>();
-
- /**
- * A two-dimensional list that holds references to the names given to each regular expression's captured groups.
- */
- private List<ArrayList<String>> columnNamesList = new ArrayList<>();
-
- /**
- * A list holding the data of every graph for the selected regular expression.
- */
- private List<GraphData> graphsData = new LinkedList<>();
-
- /**
- * A list of graphsData lists. This is needed because each regular expression has its own set of graphs.
- */
- private List<LinkedList<GraphData>> graphsDataList = new ArrayList<>();
-
- /**
- * A list of GraphDatas that rely on series information that has been deleted from their relying regex.
- */
- private List<GraphData> 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<String> columnNames = new ArrayList<>();
- Control[] children = textFieldsComposite.getChildren();
- for (int i = 0; i < numberOfVisibleColumns; i++) {
- columnNames.add(((Text)children[i*4 + 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 tEditor = (ITextEditor) editor.getAdapter(ITextEditor.class);
- if (tEditor != null) {
- IDocumentProvider provider = tEditor.getDocumentProvider();
- IDocument document = provider.getDocument(tEditor.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) {
- File scriptFile = scriptPath.toFile();
- try (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("(?<=[^\\w])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<>();
- 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
- * @return
- */
- public static List<String> createDatasetNames(ILaunchConfiguration configuration) {
- try {
- int numberOfRegexs = configuration.getAttribute(NUMBER_OF_REGEXS, 0);
- ArrayList<String> names = new ArrayList<>(numberOfRegexs);
- for (int r = 0; r < numberOfRegexs; r++) {
- names.add(MessageFormat.format(Messages.SystemTapScriptGraphOptionsTab_graphSetTitleBase, r + 1));
- }
- return names;
- } catch (CoreException e) {
- ExceptionErrorDialog.openError(Messages.SystemTapScriptGraphOptionsTab_cantInitializeTab, e);
- }
- return null;
- }
-
- /**
- * Creates a list of parsers, one for each regular expression created, that will be used
- * to parse the output of a running script.
- * @param configuration The desired run configuration.
- * @return A list of parsers.
- */
- public static List<IDataSetParser> createDatasetParsers(ILaunchConfiguration configuration) {
- try {
- int numberOfRegexs = configuration.getAttribute(NUMBER_OF_REGEXS, 0);
- ArrayList<IDataSetParser> parsers = new ArrayList<>(numberOfRegexs);
- for (int r = 0; r < numberOfRegexs; r++) {
- parsers.add(new LineParser("^" + configuration.getAttribute(REGULAR_EXPRESSION + r, "") + "$")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
- }
- return parsers;
- } catch (CoreException e) {
- ExceptionErrorDialog.openError(Messages.SystemTapScriptGraphOptionsTab_cantInitializeTab, e);
- }
- return null;
- }
-
- /**
- * Creates a data set corresponding to the titles given to each output column
- * from each of a run configuration's regular expressions.
- * @param configuration
- * @return
- */
- public static List<IFilteredDataSet> createDataset(ILaunchConfiguration configuration) {
- try {
- int numberOfRegexs = configuration.getAttribute(NUMBER_OF_REGEXS, 0);
- ArrayList<IFilteredDataSet> datasets = new ArrayList<>(numberOfRegexs);
-
- for (int r = 0; r < numberOfRegexs; r++) {
- int numberOfColumns = configuration.getAttribute(NUMBER_OF_COLUMNS + r, 0);
- ArrayList<String> labels = new ArrayList<>(numberOfColumns);
-
- for (int c = 0; c < numberOfColumns; c++) {
- labels.add(configuration.getAttribute(get2DConfigData(REGEX_BOX, r, c), "")); //$NON-NLS-1$
- }
- datasets.add(DataSetFactory.createFilteredDataSet(RowDataSet.ID, labels.toArray(new String[] {})));
- }
-
- return datasets;
- } catch (CoreException e) {
- ExceptionErrorDialog.openError(Messages.SystemTapScriptGraphOptionsTab_cantInitializeTab, e);
- }
- return null;
- }
-
- /**
- * Creates graph data corresponding to the graphs that will plot a script's parsed output data.
- * @param configuration The desired run configuration.
- * @return A data set.
- */
- public static List<LinkedList<GraphData>> createGraphsFromConfiguration (ILaunchConfiguration configuration)
- throws CoreException {
- // Restrict number of regexs to at least one, so at least
- // one inner list will exist in the return value.
- int numberOfRegexs = Math.max(configuration.getAttribute(NUMBER_OF_REGEXS, 1), 1);
- ArrayList<LinkedList<GraphData>> graphsList = new ArrayList<>(numberOfRegexs);
-
- for (int r = 0; r < numberOfRegexs; r++) {
- int numberOfGraphs = configuration.getAttribute(NUMBER_OF_GRAPHS + r, 0);
- LinkedList<GraphData> graphs = new LinkedList<>();
- for (int i = 0; i < numberOfGraphs; i++) {
- GraphData graphData = new GraphData();
- graphData.title = configuration.getAttribute(get2DConfigData(GRAPH_TITLE, r, i), (String) null);
-
- graphData.key = configuration.getAttribute(get2DConfigData(GRAPH_KEY, r, i), (String) null);
- graphData.xSeries = configuration.getAttribute(get2DConfigData(GRAPH_X_SERIES, r, i), 0);
- graphData.graphID = configuration.getAttribute(get2DConfigData(GRAPH_ID, r, i), (String) null);
-
- int ySeriesLength = configuration.getAttribute(get2DConfigData(GRAPH_Y_SERIES_LENGTH, r, i), 0);
- if (ySeriesLength == 0) {
- graphData.ySeries = null;
- } else {
- int[] ySeries = new int[ySeriesLength];
- for (int j = 0; j < ySeriesLength; j++) {
- ySeries[j] = configuration.getAttribute(get2DConfigData(GRAPH_Y_SERIES, r, i + "_" + j), 0); //$NON-NLS-1$
- }
- graphData.ySeries = ySeries;
- }
-
- graphs.add(graphData);
- }
- graphsList.add(graphs);
- }
-
- return graphsList;
- }
-
- /**
- * Returns the key associated with the i'th data item of the r'th regular expression.
- * @param configDataName The type of data to access from the configuration.
- * @param r The index of the regular expression.
- * @param i The index of the data item to access.
- */
- private static String get2DConfigData(String configDataName, int r, int i) {
- return configDataName + r + "_" + i; //$NON-NLS-1$
- }
-
- /**
- * Returns the key associated with the data item of the r'th regular expression, tagged by string s.
- * @param configDataName The type of data to access from the configuration.
- * @param r The index of the regular expression.
- * @param s The string to put at the end of the key.
- */
- private static String get2DConfigData(String configDataName, int r, String s) {
- return configDataName + r + "_" + s; //$NON-NLS-1$
- }
-
- /**
- * Returns the total number of regular expressions of the current configuration.
- */
- private int getNumberOfRegexs() {
- return outputList.size();
- }
-
- @Override
- public void createControl(Composite parent) {
- GridLayout layout = new GridLayout();
- Composite top = new Composite(parent, SWT.NONE);
- setControl(top);
- top.setLayout(layout);
- top.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
-
- this.runWithChartCheckButton = new Button(top, SWT.CHECK);
- runWithChartCheckButton.setText(Messages.SystemTapScriptGraphOptionsTab_graphOutputRun);
- runWithChartCheckButton.addSelectionListener(new SelectionListener() {
- @Override
- public void widgetSelected(SelectionEvent e) {
- setGraphingEnabled(runWithChartCheckButton.getSelection());
- }
-
- @Override
- public void widgetDefaultSelected(SelectionEvent e) {
- setGraphingEnabled(runWithChartCheckButton.getSelection());
- }
- });
-
- runWithChartCheckButton.setToolTipText(Messages.SystemTapScriptGraphOptionsTab_graphOutput);
-
- this.outputParsingGroup = new Group(top, SWT.SHADOW_ETCHED_IN);
- outputParsingGroup.setText(Messages.SystemTapScriptGraphOptionsTab_outputLabel);
- outputParsingGroup.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
- this.createColumnSelector(outputParsingGroup);
-
- this.graphsGroup = new Group(top, SWT.SHADOW_ETCHED_IN);
- // Set the text here just to allow proper sizing.
- graphsGroup.setText(MessageFormat.format(Messages.SystemTapScriptGraphOptionsTab_graphSetTitleBase, 1));
- graphsGroup.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
- createGraphCreateArea(graphsGroup);
-
- setGraphingEnabled(false);
- runWithChartCheckButton.setSelection(false);
- }
-
- private void createColumnSelector(Composite parent) {
-
- GridLayout layout = new GridLayout();
- parent.setLayout(layout);
-
- Composite topLayout = new Composite(parent, SWT.NONE);
- topLayout.setLayout(new GridLayout(1, false));
- 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(new GridLayout(3, false));
- regexButtonLayout.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
-
- Label selectedRegexLabel = new Label(regexButtonLayout, SWT.NONE);
- selectedRegexLabel.setText(Messages.SystemTapScriptGraphOptionsTab_regexLabel);
- selectedRegexLabel.setToolTipText(Messages.SystemTapScriptGraphOptionsTab_regexTooltip);
- regularExpressionCombo = new Combo(regexButtonLayout, SWT.DROP_DOWN);
- regularExpressionCombo.setTextLimit(MAX_REGEX_LENGTH);
- regularExpressionCombo.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
- regularExpressionCombo.addSelectionListener(new SelectionAdapter() {
- @Override
- public void widgetSelected(SelectionEvent e) {
- int selected = regularExpressionCombo.getSelectionIndex();
- if (selected == selectedRegex) {
- return;
- }
-
- // If deselecting an empty regular expression, delete it automatically.
- if (regularExpressionCombo.getItem(selectedRegex).isEmpty()
- && graphsDataList.get(selectedRegex).size() == 0
- && outputList.get(selectedRegex).isEmpty()) {
-
- // If the deselected regex is the last one in the combo, just quit.
- // Otherwise, the deleted blank entry would be replaced by another blank entry.
- if (selected == regularExpressionCombo.getItemCount() - 1) {
- regularExpressionCombo.select(selectedRegex); // To keep the text blank.
- return;
- }
- removeRegex(false);
- if (selected > selectedRegex) {
- selected--;
- }
- }
-
- // When selecting the "Add New Regex" item in the combo (which is always the last item),
- // update all appropriate values to make room for a new regular expression.
- if (selected == regularExpressionCombo.getItemCount() - 1 && getNumberOfRegexs() < MAX_NUMBER_OF_REGEXS) {
- outputList.add(""); //$NON-NLS-1$
- regexErrorMessages.add(null);
- columnNamesList.add(new ArrayList<String>());
- cachedNamesList.add(new Stack<String>());
- graphsDataList.add(new LinkedList<GraphData>());
-
- // Remove "Add New Regex" from the selected combo item; make it blank.
- regularExpressionCombo.setItem(selected, ""); //$NON-NLS-1$
- regularExpressionCombo.select(selected);
- updateRegexSelection(selected, false);
- updateLaunchConfigurationDialog();
-
- // Enable the "remove" button if only one item was present before.
- // (Don't do this _every_ time something is added.)
- if (getNumberOfRegexs() == 2) {
- removeRegexButton.setEnabled(true);
- }
- if (getNumberOfRegexs() < MAX_NUMBER_OF_REGEXS) {
- regularExpressionCombo.add(Messages.SystemTapScriptGraphOptionsTab_regexAddNew);
- }
- } else {
- updateRegexSelection(selected, false);
- }
- }
- });
- regularExpressionCombo.addModifyListener(regexListener);
-
- removeRegexButton = new Button(regexButtonLayout, SWT.PUSH);
- removeRegexButton.setLayoutData(new GridData(SWT.BEGINNING, SWT.BEGINNING, false, false));
- removeRegexButton.setText(Messages.SystemTapScriptGraphOptionsTab_regexRemove);
- removeRegexButton.addSelectionListener(new SelectionAdapter() {
- @Override
- public void widgetSelected(SelectionEvent e) {
- IWorkbench workbench = PlatformUI.getWorkbench();
- MessageDialog dialog = new MessageDialog(workbench
- .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$
- int result = dialog.open();
- if (result == 0) { //Yes
- removeRegex(true);
- }
- }
- });
-
- GridLayout twoColumns = new GridLayout(2, false);
-
- Composite regexSummaryComposite = new Composite(parent, SWT.NONE);
- regexSummaryComposite.setLayout(twoColumns);
- regexSummaryComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
-
- Label sampleOutputLabel = new Label(regexSummaryComposite, SWT.NONE);
- sampleOutputLabel.setText(Messages.SystemTapScriptGraphOptionsTab_sampleOutputLabel);
- sampleOutputLabel.setToolTipText(Messages.SystemTapScriptGraphOptionsTab_sampleOutputTooltip);
- this.sampleOutputText = new Text(regexSummaryComposite, SWT.BORDER);
- this.sampleOutputText.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
- this.sampleOutputText.addModifyListener(sampleOutputListener);
- sampleOutputText.setToolTipText(Messages.SystemTapScriptGraphOptionsTab_sampleOutputTooltip);
-
-
- Composite expressionTableLabels = new Composite(parent, SWT.NONE);
- expressionTableLabels.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false));
- expressionTableLabels.setLayout(twoColumns);
-
- Label label = new Label(expressionTableLabels, SWT.NONE);
- label.setText(Messages.SystemTapScriptGraphOptionsTab_columnTitle);
- label.setAlignment(SWT.LEFT);
-
- Label label2 = new Label(expressionTableLabels, SWT.NONE);
- label2.setAlignment(SWT.LEFT);
- label2.setText(Messages.SystemTapScriptGraphOptionsTab_extractedValueLabel);
-
- this.regexTextScrolledComposite = new ScrolledComposite(parent, SWT.V_SCROLL | SWT.BORDER);
- GridData data = new GridData(SWT.FILL, SWT.FILL, true, false);
- data.heightHint = 200;
- regexTextScrolledComposite.setLayoutData(data);
-
- textFieldsComposite = new Composite(regexTextScrolledComposite, SWT.NONE);
- textFieldsComposite.setLayout(new GridLayout(4, false));
- regexTextScrolledComposite.setContent(textFieldsComposite);
- regexTextScrolledComposite.setExpandHorizontal(true);
-
- // To position the column labels properly, add a dummy column and use its children's sizes for reference.
- // This is necessary since expressionTableLabels can't share a layout with textFieldsComposite.
- textListenersEnabled = false;
- addColumn(""); //$NON-NLS-1$
- data = new GridData(SWT.FILL, SWT.FILL, false, false);
- data.horizontalIndent = textFieldsComposite.getChildren()[2].getLocation().x;
- data.widthHint = textFieldsComposite.getChildren()[2].getSize().x;
- label.setLayoutData(data);
- label2.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false));
- removeColumn(false);
- textListenersEnabled = true;
- }
-
- private IDataSet getCurrentDataset() {
- return DataSetFactory.createDataSet(RowDataSet.ID, columnNamesList.get(selectedRegex).toArray(new String[] {}));
- }
-
- private void createGraphCreateArea(Composite comp) {
- comp.setLayout(new GridLayout(2, false));
-
- graphsTable = new Table(comp, SWT.SINGLE | SWT.BORDER);
- GridData layoutData = new GridData(SWT.FILL, SWT.FILL, true, true);
- graphsTable.setLayoutData(layoutData);
-
- // Button to add another graph
- Composite buttonComposite = new Composite(comp, SWT.NONE);
- buttonComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false));
-
- GridLayout gridLayout = new GridLayout();
- gridLayout.numColumns = 1;
-
- buttonComposite.setLayout(gridLayout);
- // Button to add a new graph
- addGraphButton = new Button(buttonComposite, SWT.PUSH);
- addGraphButton.setText(Messages.SystemTapScriptGraphOptionsTab_AddGraphButton);
- addGraphButton.setToolTipText(Messages.SystemTapScriptGraphOptionsTab_AddGraphButtonToolTip);
- addGraphButton.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
-
- // Button to copy an existing graph
- duplicateGraphButton = new Button(buttonComposite, SWT.PUSH);
- duplicateGraphButton.setText(Messages.SystemTapScriptGraphOptionsTab_DuplicateGraphButton);
- duplicateGraphButton.setToolTipText(Messages.SystemTapScriptGraphOptionsTab_DuplicateGraphButtonToolTip);
- duplicateGraphButton.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
-
- // Button to edit an existing graph
- editGraphButton = new Button(buttonComposite, SWT.PUSH);
- editGraphButton.setText(Messages.SystemTapScriptGraphOptionsTab_EditGraphButton);
- editGraphButton.setToolTipText(Messages.SystemTapScriptGraphOptionsTab_EditGraphButtonToolTip);
- editGraphButton.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
-
- // Button to remove the selected graph/filter
- removeGraphButton = new Button(buttonComposite, SWT.PUSH);
- removeGraphButton.setText(Messages.SystemTapScriptGraphOptionsTab_RemoveGraphButton);
- removeGraphButton.setToolTipText(Messages.SystemTapScriptGraphOptionsTab_RemoveGraphButtonToolTip);
- removeGraphButton.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
-
- // Action to notify the buttons when to enable/disable themselves based
- // on list selection
- graphsTable.addSelectionListener(new SelectionAdapter() {
- @Override
- public void widgetSelected(SelectionEvent e) {
- selectedTableItem = (TableItem) e.item;
- setSelectionControlsEnabled(true);
- }
- });
-
- // Brings up a new dialog box when user clicks the add button. Allows
- // selecting a new graph to display.
- addGraphButton.addSelectionListener(new SelectionAdapter() {
- @Override
- public void widgetSelected(SelectionEvent e) {
- SelectGraphAndSeriesWizard wizard = new SelectGraphAndSeriesWizard(getCurrentDataset(), null);
- IWorkbench workbench = PlatformUI.getWorkbench();
- wizard.init(workbench, null);
- WizardDialog dialog = new WizardDialog(workbench
- .getActiveWorkbenchWindow().getShell(), wizard);
- dialog.create();
- dialog.open();
-
- GraphData gd = wizard.getGraphData();
-
- if (null != gd) {
- TableItem item = new TableItem(graphsTable, SWT.NONE);
- graphsData.add(gd);
- setUpGraphTableItem(item, gd, false);
- updateLaunchConfigurationDialog();
- }
- }
- });
-
- // Adds a new entry to the list of graphs that is a copy of the one selected.
- duplicateGraphButton.addSelectionListener(new SelectionAdapter() {
- @Override
- public void widgetSelected(SelectionEvent e) {
- GraphData gd = ((GraphData) selectedTableItem.getData()).getCopy();
-
- TableItem item = new TableItem(graphsTable, SWT.NONE);
- graphsData.add(gd);
- if (badGraphs.contains(selectedTableItem.getData())) {
- badGraphs.add(gd);
- setUpGraphTableItem(item, gd, true);
- } else {
- setUpGraphTableItem(item, gd, false);
- }
- updateLaunchConfigurationDialog();
- }
- });
-
- // When button is clicked, brings up same wizard as the one for adding
- // a graph. Data in the wizard is filled out to match the properties
- // of the selected graph.
- editGraphButton.addSelectionListener(new SelectionAdapter() {
- @Override
- public void widgetSelected(SelectionEvent e) {
- SelectGraphAndSeriesWizard wizard = new SelectGraphAndSeriesWizard(getCurrentDataset(),
- (GraphData) selectedTableItem.getData());
- IWorkbench workbench = PlatformUI.getWorkbench();
- wizard.init(workbench, null);
- WizardDialog dialog = new WizardDialog(workbench
- .getActiveWorkbenchWindow().getShell(), wizard);
- dialog.create();
- dialog.open();
-
- GraphData gd = wizard.getGraphData();
- if (null == gd) {
- return;
- }
- GraphData old_gd = (GraphData) selectedTableItem.getData();
- if (!gd.equals(old_gd)) {
- badGraphs.remove(old_gd);
- setUpGraphTableItem(selectedTableItem, gd, false);
- graphsData.set(graphsTable.indexOf(selectedTableItem), gd);
- checkErrors(selectedRegex);
- updateLaunchConfigurationDialog();
- }
- }
- });
-
- // Removes the selected graph/filter from the table
- removeGraphButton.addSelectionListener(new SelectionAdapter() {
- @Override
- public void widgetSelected(SelectionEvent e) {
- GraphData gd = (GraphData) selectedTableItem.getData();
- graphsData.remove(gd);
- badGraphs.remove(gd);
- selectedTableItem.dispose();
- setSelectionControlsEnabled(false);
- checkErrors(selectedRegex);
- updateLaunchConfigurationDialog();
- }
- });
- }
-
- private void removeRegex(boolean autoSelect) {
- int removedRegex = selectedRegex;
- if (autoSelect) {
- // The current selection is to be removed, so select something else that will be available.
- regularExpressionCombo.select(selectedRegex != 0 ? selectedRegex - 1 : 1);
- updateRegexSelection(regularExpressionCombo.getSelectionIndex(), false);
- }
-
- regularExpressionCombo.remove(removedRegex);
- outputList.remove(removedRegex);
- regexErrorMessages.remove(removedRegex);
- columnNamesList.remove(removedRegex);
- cachedNamesList.remove(removedRegex);
- graphsDataList.remove(removedRegex);
-
- if (autoSelect) {
- // Make sure the index of the selection is accurate.
- selectedRegex = regularExpressionCombo.getSelectionIndex();
- }
-
- // Re-add the "Add New Regex" entry if it is missing.
- if (getNumberOfRegexs() == MAX_NUMBER_OF_REGEXS - 1) {
- regularExpressionCombo.add(Messages.SystemTapScriptGraphOptionsTab_regexAddNew);
- }
-
- // Disable the "remove" button if only one selection is left; never want zero items.
- if (getNumberOfRegexs() == 1) {
- removeRegexButton.setEnabled(false);
- }
- updateLaunchConfigurationDialog();
- }
-
- /**
- * This handles UI & list updating whenever a different regular expression is selected.
- * @param newSelection The index of the regex to be selected.
- * @param force If true, the UI will update even if the index of the selected regex did not change.
- */
- private void updateRegexSelection(int newSelection, boolean force) {
- // Quit if the selection didn't change anything, or if the selection is invalid (-1).
- if (newSelection == -1 || (!force && selectedRegex == newSelection)) {
- return;
- }
- selectedRegex = newSelection;
-
- boolean textListenersDisabled = !textListenersEnabled;
- if (!textListenersDisabled) {
- textListenersEnabled = false;
- }
-
- sampleOutputText.setText(outputList.get(selectedRegex));
- cachedNames = cachedNamesList.get(selectedRegex);
-
- // Update the number of columns and their titles here, and not in refreshRegexRows,
- // using the list of saved active names instead of a cachedNames stack.
- ArrayList<String> columnNames = columnNamesList.get(selectedRegex);
- int desiredNumberOfColumns = columnNames.size();
- // Remove all columns to easily update them all immediately afterwards.
- while (numberOfVisibleColumns > 0) {
- removeColumn(false);
- }
- while (numberOfVisibleColumns < desiredNumberOfColumns) {
- addColumn(columnNames.get(numberOfVisibleColumns));
- }
-
- refreshRegexRows();
-
- // Now, only display graphs that are associated with the selected regex.
- graphsData = graphsDataList.get(selectedRegex);
- graphsTable.removeAll();
- selectedTableItem = null;
- setSelectionControlsEnabled(false);
-
- for (GraphData gd : graphsData) {
- TableItem item = new TableItem(graphsTable, SWT.NONE);
- setUpGraphTableItem(item, gd, badGraphs.contains(gd));
- }
- graphsGroup.setText(MessageFormat.format(Messages.SystemTapScriptGraphOptionsTab_graphSetTitleBase,
- selectedRegex + 1));
-
- if (!textListenersDisabled) {
- textListenersEnabled = true;
- }
- }
-
- private void refreshRegexRows() {
- try {
- pattern = Pattern.compile(regularExpressionCombo.getText());
- matcher = pattern.matcher(sampleOutputText.getText());
- regexErrorMessages.set(selectedRegex, null);
- } catch (PatternSyntaxException e) {
- regexErrorMessages.set(selectedRegex, e.getMessage());
- return;
- }
- regexErrorMessages.set(selectedRegex, checkRegex(regularExpressionCombo.getText()));
- if (regexErrorMessages.get(selectedRegex) != null) {
- return;
- }
-
- int desiredNumberOfColumns = matcher.groupCount();
-
- while (numberOfVisibleColumns < desiredNumberOfColumns) {
- addColumn(null);
- }
-
- while (numberOfVisibleColumns > desiredNumberOfColumns) {
- removeColumn(true);
- }
-
- // Set values
- Control[] children = textFieldsComposite.getChildren();
- for (int i = 0; i < numberOfVisibleColumns; i++) {
- String sampleOutputResults;
- if (matcher.matches()) {
- sampleOutputResults = matcher.group(i+1);
- }
- else if (sampleOutputText.getText().length() == 0) {
- sampleOutputResults = Messages.SystemTapScriptGraphOptionsTab_sampleOutputIsEmpty;
- } else {
- sampleOutputResults = Messages.SystemTapScriptGraphOptionsTab_sampleOutputNoMatch;
- }
- ((Label)children[i*4+3]).setText(" " + sampleOutputResults); //$NON-NLS-1$
- }
-
- // May only add/edit graphs if there is output data being captured.
- addGraphButton.setEnabled(numberOfVisibleColumns > 0);
- if (selectedTableItem != null) {
- editGraphButton.setEnabled(numberOfVisibleColumns > 0);
- }
-
- regexErrorMessages.set(selectedRegex, findBadGraphs(selectedRegex));
- }
-
- /**
- * Checks if a provided regular expression is valid.
- * @param regex The regular expression to check for validity.
- * @return <code>null</code> if the regular expression is valid, or an error message.
- */
- private static String checkRegex(String regex) {
- //TODO may add more invalid regexs here, each with its own error message.
- if (regex.contains("()")) { //$NON-NLS-1$
- return Messages.SystemTapScriptGraphOptionsTab_emptyGroup;
- }
- return null;
- }
-
- /**
- * Adds one column to the list of the currently-selected regex's columns.
- * This creates an extra Text in which the name of the column may be entered,
- * and a corresponding Label containing sample expected output.
- * @param nameToAdd If non-null, the name of the newly-created column will
- * match this String. If null, the column will be given a name recovered from
- * the active stack of cached names, or a default name if one doesn't exist.
- */
- private void addColumn(String nameToAdd) {
- // Show the "shift" buttons of the previous column, if it exists.
- if (this.numberOfVisibleColumns > 0) {
- textFieldsComposite.getChildren()[(this.numberOfVisibleColumns - 1) * 4].setVisible(true);
- textFieldsComposite.getChildren()[(this.numberOfVisibleColumns - 1) * 4 + 1].setVisible(true);
- }
-
- // Add buttons for shifting column names up/down in the list.
- Button buttonUp = new Button(textFieldsComposite, SWT.PUSH);
- buttonUp.setText(Messages.SystemTapScriptGraphOptionsTab_columnShiftUp);
- buttonUp.setVisible(false);
- Button buttonDown = new Button(textFieldsComposite, SWT.PUSH);
- buttonDown.setText(Messages.SystemTapScriptGraphOptionsTab_columnShiftDown);
- buttonDown.setVisible(false);
-
- Text text = new Text(textFieldsComposite, SWT.BORDER);
- GridData data = new GridData(SWT.FILL, SWT.FILL, false, false);
- data.minimumWidth = 200;
- data.widthHint = 200;
- text.setLayoutData(data);
-
- numberOfVisibleColumns++;
- text.addModifyListener(columnNameListener);
- if (nameToAdd == null) {
- // Restore a deleted name by popping from the stack.
- if (cachedNames.size() > 0) {
- text.setText(cachedNames.pop());
- } else {
- text.setText(MessageFormat.format(Messages.SystemTapScriptGraphOptionsTab_defaultColumnTitleBase,
- numberOfVisibleColumns));
- }
- } else {
- text.setText(nameToAdd);
- }
-
- Label label = new Label(textFieldsComposite, SWT.BORDER);
- label.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
-
- textFieldsComposite.layout();
- textFieldsComposite.pack();
-
- // Special value: if an empty string is given, don't add button listeners.
- if (nameToAdd == "") { //$NON-NLS-1$
- return;
- }
-
- // Add button listeners for shifting column names.
- buttonUp.addSelectionListener(new SelectionAdapter() {
- @Override
- public void widgetSelected(SelectionEvent e) {
- Control clickedButton = (Control) e.widget;
- Control[] children = textFieldsComposite.getChildren();
- int currentColumn = 0;
- for (; currentColumn < numberOfVisibleColumns - 1; currentColumn++) {
- if (children[currentColumn*4].equals(clickedButton)) {
- break;
- }
- }
- String edgeName = ((Text)children[currentColumn*4 + 2]).getText();
- for (int i = currentColumn; i < numberOfVisibleColumns - 1; i++) {
- ((Text)children[i*4 + 2]).setText(((Text)children[(i + 1)*4 + 2]).getText());
- }
- ((Text)children[(numberOfVisibleColumns - 1)*4 + 2]).setText(edgeName);
- }
- });
-
- buttonDown.addSelectionListener(new SelectionAdapter() {
- @Override
- public void widgetSelected(SelectionEvent e) {
- Control clickedButton = (Control) e.widget;
- Control[] children = textFieldsComposite.getChildren();
- int currentColumn = 0;
- for (; currentColumn < numberOfVisibleColumns - 1; currentColumn++) {
- if (children[currentColumn*4 + 1].equals(clickedButton)) {
- break;
- }
- }
- String edgeName = ((Text)children[(numberOfVisibleColumns - 1)*4 + 2]).getText();
- for (int i = numberOfVisibleColumns - 1; i > currentColumn; i--) {
- ((Text)children[i*4 + 2]).setText(((Text)children[(i - 1)*4 + 2]).getText());
- }
- ((Text)children[currentColumn*4 + 2]).setText(edgeName);
- }
- });
- }
-
- /**
- * Removes a column from the currently-selected regex, and removes its
- * corresponding Text & Label from the UI.
- * @param saveNames Set to <code>true</code> if the contents of removed
- * columns are to be saved in a stack for later use.
- */
- private void removeColumn(Boolean saveNames) {
- Control[] children = textFieldsComposite.getChildren();
- int i = this.numberOfVisibleColumns*4 - 1;
-
- if (saveNames) {
- // Push the removed name on a stack.
- String name = ((Text)children[i-1]).getText();
- if (name != null && name != "") { //$NON-NLS-1$
- cachedNames.push(name);
- }
- columnNamesList.get(selectedRegex).remove(numberOfVisibleColumns - 1);
- }
-
- children[i].dispose();
- children[i-1].dispose();
- children[i-2].dispose();
- children[i-3].dispose();
-
- // Hide the previous column's "shift" buttons, if it exists.
- if (this.numberOfVisibleColumns > 2) {
- children[i - 6].setVisible(false);
- children[i - 7].setVisible(false);
- }
-
- this.numberOfVisibleColumns--;
-
- textFieldsComposite.layout();
- textFieldsComposite.pack();
- }
-
- /**
- * Marks all graphs belonging to the indicated regular expression that have an
- * error (missing column data, invalid graphID), or unmarks graphs that don't.
- * @param regex The index of the regular expression to check for invalid graphs.
- * @return An appropriate error message if an invalid graph is found, or if the
- * selected regular expression parses nothing.
- */
- private String findBadGraphs(int regex) {
- boolean foundBadID = false;
- boolean foundRemoved = false;
- int numberOfColumns = columnNamesList.get(regex).size();
-
- for (GraphData gd : graphsDataList.get(regex)) {
- boolean singleBadID = false;
- boolean singleRemoved = false;
-
- if (GraphFactory.getGraphName(gd.graphID) == null) {
- singleBadID = true;
- } else {
- if (gd.xSeries >= numberOfColumns) {
- singleRemoved = true;
- }
- for (int s = 0; s < gd.ySeries.length && !singleRemoved; s++) {
- if (gd.ySeries[s] >= numberOfColumns) {
- singleRemoved = true;
- }
- }
- }
- if (singleRemoved || singleBadID) {
- if (!badGraphs.contains(gd)) {
- badGraphs.add(gd);
- setUpGraphTableItem(findGraphTableItem(gd), null, true);
- }
- } else if (badGraphs.contains(gd)) {
- badGraphs.remove(gd);
- setUpGraphTableItem(findGraphTableItem(gd), null, false);
- }
-
- foundBadID |= singleBadID;
- foundRemoved |= singleRemoved;
- }
-
- if (numberOfColumns == 0) {
- return Messages.SystemTapScriptGraphOptionsTab_noGroups;
- }
- if (foundBadID) {
- return Messages.SystemTapScriptGraphOptionsTab_badGraphID;
- }
- if (foundRemoved) {
- return Messages.SystemTapScriptGraphOptionsTab_deletedGraphData;
- }
- return null;
- }
-
- private TableItem findGraphTableItem(GraphData gd) {
- for (TableItem item : graphsTable.getItems()) {
- if (item.getData().equals(gd)) {
- return item;
- }
- }
- return null;
- }
-
- /**
- * Sets up a given {@link TableItem} with the proper title & appearance based on
- * its graph data & (in)valid status.
- * @param item The {@link TableItem} to set up.
- * @param gd The {@link GraphData} that the item will hold. Set to <code>null</code>
- * to preserve the item's existing data.
- * @param bad <code>true</code> if the item should appear as invalid, <code>false</code> otherwise.
- */
- private void setUpGraphTableItem(TableItem item, GraphData gd, boolean bad) {
- // Include a null check to avoid accidentally marking non-visible items.
- if (item == null) {
- return;
- }
- if (gd != null) {
- item.setData(gd);
- } else {
- gd = (GraphData) item.getData();
- }
- item.setForeground(item.getDisplay().getSystemColor(bad ? SWT.COLOR_RED : SWT.COLOR_BLACK));
- String graphName = GraphFactory.getGraphName(gd.graphID);
- if (graphName == null) {
- graphName = Messages.SystemTapScriptGraphOptionsTab_invalidGraphID;
- }
- item.setText(graphName + ":" + gd.title //$NON-NLS-1$
- + (bad ? " " + Messages.SystemTapScriptGraphOptionsTab_invalidGraph : "")); //$NON-NLS-1$ //$NON-NLS-2$
- }
-
- @Override
- public void setDefaults(ILaunchConfigurationWorkingCopy configuration) {
- configuration.setAttribute(RUN_WITH_CHART, false);
- configuration.setAttribute(NUMBER_OF_REGEXS, 1);
- configuration.setAttribute(NUMBER_OF_COLUMNS + 0, 0);
- configuration.setAttribute(NUMBER_OF_EXTRAS + 0, 0);
- configuration.setAttribute(REGULAR_EXPRESSION + 0, ""); //$NON-NLS-1$
- configuration.setAttribute(SAMPLE_OUTPUT + 0, ""); //$NON-NLS-1$
- configuration.setAttribute(NUMBER_OF_GRAPHS + 0, 0);
- }
-
- @Override
- public void initializeFrom(ILaunchConfiguration configuration) {
- try {
- textListenersEnabled = false;
-
- // Reset lists & settings to keep things idempotent.
- regularExpressionCombo.removeAll();
- outputList.clear();
- regexErrorMessages.clear();
- columnNamesList.clear();
- cachedNamesList.clear();
- graphsTable.removeAll();
- badGraphs.clear();
-
- // There should always be at least one regular expression (a blank one still counts).
- // If configuration's number of regexs is zero, it is outdated.
- int numberOfRegexs = Math.max(configuration.getAttribute(NUMBER_OF_REGEXS, 1), 1);
-
- // Only allow removing regexs if there are more than one.
- removeRegexButton.setEnabled(numberOfRegexs > 1);
-
- for (int r = 0; r < numberOfRegexs; r++) {
- // Save all of the configuration's regular expressions & sample outputs in a list.
- regularExpressionCombo.add(configuration.getAttribute(REGULAR_EXPRESSION + r, "")); //$NON-NLS-1$
- outputList.add(configuration.getAttribute(SAMPLE_OUTPUT + r, "")); //$NON-NLS-1$
-
- // Save each regex's list of group names.
- int numberOfColumns = configuration.getAttribute(NUMBER_OF_COLUMNS + r, 0);
- ArrayList<String> namelist = new ArrayList<>(numberOfColumns);
- for (int i = 0; i < numberOfColumns; i++) {
- namelist.add(configuration.getAttribute(get2DConfigData(REGEX_BOX, r, i), (String)null));
- }
- columnNamesList.add(namelist);
-
- //Reclaim missing column data that was required for existing graphs at the time of the previous "apply".
- int numberOfExtras = configuration.getAttribute(NUMBER_OF_EXTRAS + r, 0);
- Stack<String> oldnames = new Stack<>();
- for (int i = 0; i < numberOfExtras; i++) {
- oldnames.push(configuration.getAttribute(get2DConfigData(EXTRA_BOX, r, i), (String)null));
- }
- cachedNamesList.add(oldnames);
-
- regexErrorMessages.add(null);
- }
- if (getNumberOfRegexs() < MAX_NUMBER_OF_REGEXS) {
- regularExpressionCombo.add(Messages.SystemTapScriptGraphOptionsTab_regexAddNew);
- }
-
- // When possible, preserve the selection on subsequent initializations, for user convenience.
- int defaultSelectedRegex = 0 <= selectedRegex && selectedRegex < numberOfRegexs ? selectedRegex : 0;
- regularExpressionCombo.select(defaultSelectedRegex);
-
- // Add graphs
- graphsDataList = createGraphsFromConfiguration(configuration);
- graphsData = graphsDataList.get(defaultSelectedRegex);
- for (GraphData graphData : graphsData) {
- TableItem item = new TableItem(graphsTable, SWT.NONE);
- setUpGraphTableItem(item, graphData, true);
- }
-
- updateRegexSelection(defaultSelectedRegex, true); // Handles all remaining updates.
- checkAllOtherErrors();
-
- boolean chart = configuration.getAttribute(RUN_WITH_CHART, false);
- setGraphingEnabled(chart);
- this.runWithChartCheckButton.setSelection(chart);
-
- } catch (CoreException e) {
- ExceptionErrorDialog.openError(Messages.SystemTapScriptGraphOptionsTab_cantInitializeTab, e);
- } finally {
- textListenersEnabled = true;
- }
- }
-
- @Override
- public void performApply(ILaunchConfigurationWorkingCopy configuration) {
- configuration.setAttribute(RUN_WITH_CHART, this.runWithChartCheckButton.getSelection());
-
- int numberOfRegexs = getNumberOfRegexs();
- for (int r = 0; r < numberOfRegexs; r++) {
- // Save data sets, and clear removed ones.
- configuration.setAttribute(REGULAR_EXPRESSION + r, regularExpressionCombo.getItem(r));
- configuration.setAttribute(SAMPLE_OUTPUT + r, outputList.get(r));
-
- ArrayList<String> columnNames = columnNamesList.get(r);
- int numberOfColumns = columnNames.size();
- for (int i = 0; i < numberOfColumns; i++) {
- configuration.setAttribute(get2DConfigData(REGEX_BOX, r, i), columnNames.get(i));
- }
- cleanUpConfigurationItem(configuration, NUMBER_OF_COLUMNS, REGEX_BOX, r, numberOfColumns);
- configuration.setAttribute(NUMBER_OF_COLUMNS + r, numberOfColumns);
-
- // If the current regex has graphs with missing data, store all cached names
- // in the configuration so that they will be easily restorable for next time.
- Stack<String> extranames = cachedNamesList.get(r);
- int numberOfExtras = findBadGraphs(r) == null ? 0 : extranames.size();
- for (int i = 0; i < numberOfExtras; i++) {
- configuration.setAttribute(get2DConfigData(EXTRA_BOX, r, i), extranames.get(i));
- }
- cleanUpConfigurationItem(configuration, NUMBER_OF_EXTRAS, EXTRA_BOX, r, numberOfExtras);
- configuration.setAttribute(NUMBER_OF_EXTRAS + r, numberOfExtras);
-
- // Save new graphs, and clear removed ones.
- LinkedList<GraphData> list = graphsDataList.get(r);
- int numberOfGraphs = list.size();
- for (int i = 0; i < numberOfGraphs; i++) {
- GraphData graphData = list.get(i);
- configuration.setAttribute(get2DConfigData(GRAPH_TITLE, r, i), graphData.title);
- configuration.setAttribute(get2DConfigData(GRAPH_KEY, r, i), graphData.key);
- configuration.setAttribute(get2DConfigData(GRAPH_X_SERIES, r, i), graphData.xSeries);
- configuration.setAttribute(get2DConfigData(GRAPH_ID, r, i), graphData.graphID);
-
- int ySeriesLength = graphData.ySeries.length;
- for (int j = 0; j < ySeriesLength; j++) {
- configuration.setAttribute(get2DConfigData(GRAPH_Y_SERIES, r, i + "_" + j), //$NON-NLS-1$
- graphData.ySeries[j]);
- }
- cleanUpConfigurationGraphYSeries(configuration, r, i, ySeriesLength);
- configuration.setAttribute(get2DConfigData(GRAPH_Y_SERIES_LENGTH, r, i), ySeriesLength);
- }
- cleanUpConfigurationGraphs(configuration, r, numberOfGraphs);
- configuration.setAttribute(NUMBER_OF_GRAPHS + r, numberOfGraphs);
- }
- cleanUpConfiguration(configuration, numberOfRegexs);
- configuration.setAttribute(NUMBER_OF_REGEXS, numberOfRegexs);
- }
-
- /**
- * Removes all configuration attributes associated with deleted regular expressions.
- * @param configuration The configuration to remove attributes from.
- * @param numberOfRegexs The number of regex-related properties to exist in the
- * configuration after cleanup.
- */
- private void cleanUpConfiguration(ILaunchConfigurationWorkingCopy configuration, int numberOfRegexs) {
- int oldNumberOfRegexs = 0;
- try {
- oldNumberOfRegexs = configuration.getAttribute(NUMBER_OF_REGEXS, 0);
- } catch (CoreException e) {}
- for (int r = numberOfRegexs; r < oldNumberOfRegexs; r++) {
- configuration.removeAttribute(REGULAR_EXPRESSION + r);
- configuration.removeAttribute(SAMPLE_OUTPUT + r);
-
- cleanUpConfigurationItem(configuration, NUMBER_OF_COLUMNS, REGEX_BOX, r, 0);
- configuration.removeAttribute(NUMBER_OF_COLUMNS + r);
-
- cleanUpConfigurationItem(configuration, NUMBER_OF_COLUMNS, EXTRA_BOX, r, 0);
- configuration.removeAttribute(NUMBER_OF_EXTRAS + r);
-
- cleanUpConfigurationGraphs(configuration, r, 0);
- configuration.removeAttribute(NUMBER_OF_GRAPHS + r);
- }
- }
-
- private void cleanUpConfigurationGraphs(ILaunchConfigurationWorkingCopy configuration, int regex, int newNumberOfGraphs) {
- int oldNumberOfGraphs = 0;
- try {
- oldNumberOfGraphs = configuration.getAttribute(NUMBER_OF_GRAPHS + regex, 0);
- } catch (CoreException e) {}
- for (int i = newNumberOfGraphs; i < oldNumberOfGraphs; i++) {
- configuration.removeAttribute(get2DConfigData(GRAPH_TITLE, regex, i));
- configuration.removeAttribute(get2DConfigData(GRAPH_KEY, regex, i));
- configuration.removeAttribute(get2DConfigData(GRAPH_X_SERIES, regex, i));
- configuration.removeAttribute(get2DConfigData(GRAPH_ID, regex, i));
-
- cleanUpConfigurationGraphYSeries(configuration, regex, i, 0);
- configuration.removeAttribute(get2DConfigData(GRAPH_Y_SERIES_LENGTH, regex, i));
- }
- }
-
- private void cleanUpConfigurationItem(ILaunchConfigurationWorkingCopy configuration, String counter, String property, int regex, int newNumberOfItems) {
- int oldNumberOfItems = 0;
- try {
- oldNumberOfItems = configuration.getAttribute(counter + regex, 0);
- } catch (CoreException e) {}
- for (int i = newNumberOfItems; i < oldNumberOfItems; i++) {
- configuration.removeAttribute(get2DConfigData(property, regex, i));
- }
- }
-
- private void cleanUpConfigurationGraphYSeries(ILaunchConfigurationWorkingCopy configuration, int regex, int graph, int newLength) {
- int oldYSeriesLength = 0;
- try {
- oldYSeriesLength = configuration.getAttribute(get2DConfigData(GRAPH_Y_SERIES_LENGTH, regex, graph), 0);
- } catch (CoreException e) {}
- for (int i = newLength; i < oldYSeriesLength; i++) {
- configuration.removeAttribute(get2DConfigData(GRAPH_Y_SERIES, regex, graph + "_" + i)); //$NON-NLS-1$
- }
- }
-
- /**
- * Checks all regular expressions for errors, except for the currently-selected
- * expression (as it should be checked by {@link #refreshRegexRows}).
- */
- private void checkAllOtherErrors() {
- for (int i = 0, n = getNumberOfRegexs(); i < n; i++) {
- if (i == selectedRegex) {
- continue;
- }
- checkErrors(i);
- }
- }
-
- /**
- * Checks the regular expression of the provided index for errors.
- * Sets the associated error message to contain relevant error information.
- * @param i The index of the regular expression to check for errors.
- */
- private void checkErrors(int i) {
- String regex = regularExpressionCombo.getItem(i);
- try {
- Pattern.compile(regex);
- } catch (PatternSyntaxException e) {
- regexErrorMessages.set(i, e.getMessage());
- return;
- }
-
- String error = findBadGraphs(i);
- if (error == null) {
- error = checkRegex(regex);
- }
-
- regexErrorMessages.set(i, error);
- }
-
- @Override
- public boolean isValid(ILaunchConfiguration launchConfig) {
- setErrorMessage(null);
-
- // If graphic is disabled then everything is valid.
- if (!this.graphingEnabled) {
- return true;
- }
-
- for (int r = 0, n = getNumberOfRegexs(); r < n; r++) {
- String regexErrorMessage = regexErrorMessages.get(r);
- if (regexErrorMessage != null) {
- setErrorMessage(MessageFormat.format(Messages.SystemTapScriptGraphOptionsTab_regexErrorMsgFormat,
- regularExpressionCombo.getItems()[r], regexErrorMessage));
- return false;
- }
- }
-
- return true;
- }
-
- /**
- * Checks if a launch configuration's Systemtap Graphing settings are valid.
- * @param launchConfig The launch configuration to check for graph validity.
- * @return <code>true</code> if the launch settings are valid, or <code>false</code> if
- * its graph settings are invalid in some way.
- * @since 2.2
- */
- public static boolean isValidLaunch(ILaunchConfiguration launchConfig) throws CoreException {
- // If graphic is disabled then everything is valid.
- if (!launchConfig.getAttribute(RUN_WITH_CHART, false)) {
- return true;
- }
-
- for (int r = 0, n = launchConfig.getAttribute(NUMBER_OF_REGEXS, 1); r < n; r++) {
- // Check for any invalid regexs.
- String regex = launchConfig.getAttribute(REGULAR_EXPRESSION + r, (String) null);
- if (regex == null || checkRegex(regex) != null) {
- return false;
- }
- try {
- Pattern.compile(regex);
- } catch (PatternSyntaxException e) {
- return false;
- }
-
- // If graphs are plotted but no data is captured by one of them, report this as a problem.
- int numberOfColumns = launchConfig.getAttribute(NUMBER_OF_COLUMNS + r, 0);
- if (numberOfColumns == 0) {
- return false;
- }
-
- // Check for graphs that are missing required data.
- for (int i = 0, g = launchConfig.getAttribute(NUMBER_OF_GRAPHS + r, 0); i < g; i++) {
- if (GraphFactory.getGraphName(launchConfig.getAttribute(get2DConfigData(GRAPH_ID, r, i), (String) null)) == null) {
- return false;
- }
- if (launchConfig.getAttribute(get2DConfigData(GRAPH_X_SERIES, r, i), 0) >= numberOfColumns) {
- return false;
- }
- for (int j = 0, y = launchConfig.getAttribute(get2DConfigData(GRAPH_Y_SERIES_LENGTH, r, i), 0); j < y; j++) {
- if (launchConfig.getAttribute(get2DConfigData(GRAPH_Y_SERIES, r, i + "_" + j), 0) >= numberOfColumns) { //$NON-NLS-1$
- return false;
- }
- }
- }
- }
-
- return true;
- }
-
- @Override
- public String getName() {
- return Messages.SystemTapScriptGraphOptionsTab_graphingTitle;
- }
-
- @Override
- public Image getImage() {
- return AbstractUIPlugin.imageDescriptorFromPlugin(IDEPlugin.PLUGIN_ID,
- "icons/graphing_tab.gif").createImage(); //$NON-NLS-1$
- }
-
- private void setGraphingEnabled(boolean enabled) {
- this.graphingEnabled = enabled;
- this.setControlEnabled(outputParsingGroup, enabled);
- this.setControlEnabled(graphsGroup, enabled);
- // Disable buttons that rely on a selected graph if no graph is selected.
- this.setSelectionControlsEnabled(selectedTableItem != null);
- this.addGraphButton.setEnabled(enabled && numberOfVisibleColumns > 0);
- this.removeRegexButton.setEnabled(enabled && getNumberOfRegexs() > 1);
- updateLaunchConfigurationDialog();
- }
-
- private void setControlEnabled(Composite composite, boolean enabled) {
- composite.setEnabled(enabled);
- for (Control child : composite.getChildren()) {
- child.setEnabled(enabled);
- if (child instanceof Composite) {
- setControlEnabled((Composite)child, enabled);
- }
- }
- }
-
- /**
- * Call this to enable/disable all buttons whose actions depend on a selected graph.
- * @param enabled Set to true to enable the buttons; set to false to disable them.
- */
- private void setSelectionControlsEnabled(boolean enabled) {
- duplicateGraphButton.setEnabled(enabled);
- editGraphButton.setEnabled(enabled && numberOfVisibleColumns > 0);
- removeGraphButton.setEnabled(enabled);
- }
+ AbstractLaunchConfigurationTab {
+
+ /**
+ * The maximum number of regular expressions that can be stored in a configuration.
+ */
+ static final int MAX_NUMBER_OF_REGEXS = 20;
+
+ /**
+ * The maximum length of an output-parsing regular expression.
+ */
+ static final int MAX_REGEX_LENGTH = 200;
+
+ // Note: any non-private String key with a trailing underscore is to be appended with an integer when looking up values.
+ static final String RUN_WITH_CHART = "runWithChart"; //$NON-NLS-1$
+ static final String NUMBER_OF_REGEXS = "numberOfRegexs"; //$NON-NLS-1$
+ static final String NUMBER_OF_COLUMNS = "numberOfColumns_"; //$NON-NLS-1$
+ static final String REGEX_BOX = "regexBox_"; //$NON-NLS-1$
+ static final String NUMBER_OF_EXTRAS = "numberOfExtras_"; //$NON-NLS-1$
+ static final String EXTRA_BOX = "extraBox_"; //$NON-NLS-1$
+ static final String REGULAR_EXPRESSION = "regularExpression_"; //$NON-NLS-1$
+ static final String SAMPLE_OUTPUT = "sampleOutput_"; //$NON-NLS-1$
+
+ // Note: all graph-related keys point to 2D lists (regular expression & graph number),
+ // except for GRAPH_Y_SERIES (which is a 3D list).
+ private static final String NUMBER_OF_GRAPHS = "numberOfGraphs"; //$NON-NLS-1$
+ private static final String GRAPH_TITLE = "graphTitle"; //$NON-NLS-1$
+ private static final String GRAPH_KEY = "graphKey"; //$NON-NLS-1$
+ private static final String GRAPH_X_SERIES = "graphXSeries"; //$NON-NLS-1$
+ private static final String GRAPH_ID = "graphID"; //$NON-NLS-1$
+ private static final String GRAPH_Y_SERIES_LENGTH = "graphYSeriesLength"; //$NON-NLS-1$
+ private static final String GRAPH_Y_SERIES = "graphYSeries"; //$NON-NLS-1$
+ protected Pattern pattern;
+ protected Matcher matcher;
+
+ private Combo regularExpressionCombo;
+ private Button removeRegexButton;
+ private Button generateExpsButton;
+
+ private Text sampleOutputText;
+ private Composite textFieldsComposite;
+
+ /**
+ * This value controls whether or not the ModifyListeners associated with
+ * the Texts will perform when dispatched. Sometimes the listeners should
+ * be disabled to prevent needless/unsafe operations.
+ */
+ private boolean textListenersEnabled = true;
+
+ private ScrolledComposite regexTextScrolledComposite;
+ private Group outputParsingGroup;
+ private Button runWithChartCheckButton;
+
+ private Table graphsTable;
+ private Button addGraphButton, duplicateGraphButton, editGraphButton, removeGraphButton;
+ private TableItem selectedTableItem;
+ private Group graphsGroup;
+ private int numberOfVisibleColumns = 0;
+ private boolean graphingEnabled = true;
+
+ /**
+ * A list of error messages, each entry corresponding to an entered regular expression.
+ */
+ private List<String> regexErrorMessages = new ArrayList<>();
+
+ /**
+ * The index of the selected regular expression.
+ */
+ private int selectedRegex = -1;
+
+ /**
+ * A list containing the user-defined sample outputs associated with the regex of every index.
+ */
+ private List<String> outputList = new ArrayList<>();
+
+ /**
+ * A name is given to each group captured by a regular expression. This stack contains
+ * the names of all of a regex's groups that have been deleted, so each name may be
+ * restored (without having to retype it) when a group is added again.
+ */
+ private Stack<String> cachedNames;
+
+ /**
+ * A list of cachedNames stacks, containing one entry for each regular expression stored.
+ */
+ private List<Stack<String>> cachedNamesList = new ArrayList<>();
+
+ /**
+ * A two-dimensional list that holds references to the names given to each regular expression's captured groups.
+ */
+ private List<ArrayList<String>> columnNamesList = new ArrayList<>();
+
+ /**
+ * A list holding the data of every graph for the selected regular expression.
+ */
+ private List<GraphData> graphsData = new LinkedList<>();
+
+ /**
+ * A list of graphsData lists. This is needed because each regular expression has its own set of graphs.
+ */
+ private List<LinkedList<GraphData>> graphsDataList = new ArrayList<>();
+
+ /**
+ * A list of GraphDatas that rely on series information that has been deleted from their relying regex.
+ */
+ private List<GraphData> 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<String> columnNames = new ArrayList<>();
+ Control[] children = textFieldsComposite.getChildren();
+ for (int i = 0; i < numberOfVisibleColumns; i++) {
+ columnNames.add(((Text)children[i*4 + 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 tEditor = (ITextEditor) editor.getAdapter(ITextEditor.class);
+ if (tEditor != null) {
+ IDocumentProvider provider = tEditor.getDocumentProvider();
+ IDocument document = provider.getDocument(tEditor.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) {
+ File scriptFile = scriptPath.toFile();
+ try (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("(?<=[^\\w])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<>();
+ 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
+ * @return
+ */
+ public static List<String> createDatasetNames(ILaunchConfiguration configuration) {
+ try {
+ int numberOfRegexs = configuration.getAttribute(NUMBER_OF_REGEXS, 0);
+ ArrayList<String> names = new ArrayList<>(numberOfRegexs);
+ for (int r = 0; r < numberOfRegexs; r++) {
+ names.add(MessageFormat.format(Messages.SystemTapScriptGraphOptionsTab_graphSetTitleBase, r + 1));
+ }
+ return names;
+ } catch (CoreException e) {
+ ExceptionErrorDialog.openError(Messages.SystemTapScriptGraphOptionsTab_cantInitializeTab, e);
+ }
+ return null;
+ }
+
+ /**
+ * Creates a list of parsers, one for each regular expression created, that will be used
+ * to parse the output of a running script.
+ * @param configuration The desired run configuration.
+ * @return A list of parsers.
+ */
+ public static List<IDataSetParser> createDatasetParsers(ILaunchConfiguration configuration) {
+ try {
+ int numberOfRegexs = configuration.getAttribute(NUMBER_OF_REGEXS, 0);
+ ArrayList<IDataSetParser> parsers = new ArrayList<>(numberOfRegexs);
+ for (int r = 0; r < numberOfRegexs; r++) {
+ parsers.add(new LineParser("^" + configuration.getAttribute(REGULAR_EXPRESSION + r, "") + "$")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ }
+ return parsers;
+ } catch (CoreException e) {
+ ExceptionErrorDialog.openError(Messages.SystemTapScriptGraphOptionsTab_cantInitializeTab, e);
+ }
+ return null;
+ }
+
+ /**
+ * Creates a data set corresponding to the titles given to each output column
+ * from each of a run configuration's regular expressions.
+ * @param configuration
+ * @return
+ */
+ public static List<IFilteredDataSet> createDataset(ILaunchConfiguration configuration) {
+ try {
+ int numberOfRegexs = configuration.getAttribute(NUMBER_OF_REGEXS, 0);
+ ArrayList<IFilteredDataSet> datasets = new ArrayList<>(numberOfRegexs);
+
+ for (int r = 0; r < numberOfRegexs; r++) {
+ int numberOfColumns = configuration.getAttribute(NUMBER_OF_COLUMNS + r, 0);
+ ArrayList<String> labels = new ArrayList<>(numberOfColumns);
+
+ for (int c = 0; c < numberOfColumns; c++) {
+ labels.add(configuration.getAttribute(get2DConfigData(REGEX_BOX, r, c), "")); //$NON-NLS-1$
+ }
+ datasets.add(DataSetFactory.createFilteredDataSet(RowDataSet.ID, labels.toArray(new String[] {})));
+ }
+
+ return datasets;
+ } catch (CoreException e) {
+ ExceptionErrorDialog.openError(Messages.SystemTapScriptGraphOptionsTab_cantInitializeTab, e);
+ }
+ return null;
+ }
+
+ /**
+ * Creates graph data corresponding to the graphs that will plot a script's parsed output data.
+ * @param configuration The desired run configuration.
+ * @return A data set.
+ */
+ public static List<LinkedList<GraphData>> createGraphsFromConfiguration (ILaunchConfiguration configuration)
+ throws CoreException {
+ // Restrict number of regexs to at least one, so at least
+ // one inner list will exist in the return value.
+ int numberOfRegexs = Math.max(configuration.getAttribute(NUMBER_OF_REGEXS, 1), 1);
+ ArrayList<LinkedList<GraphData>> graphsList = new ArrayList<>(numberOfRegexs);
+
+ for (int r = 0; r < numberOfRegexs; r++) {
+ int numberOfGraphs = configuration.getAttribute(NUMBER_OF_GRAPHS + r, 0);
+ LinkedList<GraphData> graphs = new LinkedList<>();
+ for (int i = 0; i < numberOfGraphs; i++) {
+ GraphData graphData = new GraphData();
+ graphData.title = configuration.getAttribute(get2DConfigData(GRAPH_TITLE, r, i), (String) null);
+
+ graphData.key = configuration.getAttribute(get2DConfigData(GRAPH_KEY, r, i), (String) null);
+ graphData.xSeries = configuration.getAttribute(get2DConfigData(GRAPH_X_SERIES, r, i), 0);
+ graphData.graphID = configuration.getAttribute(get2DConfigData(GRAPH_ID, r, i), (String) null);
+
+ int ySeriesLength = configuration.getAttribute(get2DConfigData(GRAPH_Y_SERIES_LENGTH, r, i), 0);
+ if (ySeriesLength == 0) {
+ graphData.ySeries = null;
+ } else {
+ int[] ySeries = new int[ySeriesLength];
+ for (int j = 0; j < ySeriesLength; j++) {
+ ySeries[j] = configuration.getAttribute(get2DConfigData(GRAPH_Y_SERIES, r, i + "_" + j), 0); //$NON-NLS-1$
+ }
+ graphData.ySeries = ySeries;
+ }
+
+ graphs.add(graphData);
+ }
+ graphsList.add(graphs);
+ }
+
+ return graphsList;
+ }
+
+ /**
+ * Returns the key associated with the i'th data item of the r'th regular expression.
+ * @param configDataName The type of data to access from the configuration.
+ * @param r The index of the regular expression.
+ * @param i The index of the data item to access.
+ */
+ private static String get2DConfigData(String configDataName, int r, int i) {
+ return configDataName + r + "_" + i; //$NON-NLS-1$
+ }
+
+ /**
+ * Returns the key associated with the data item of the r'th regular expression, tagged by string s.
+ * @param configDataName The type of data to access from the configuration.
+ * @param r The index of the regular expression.
+ * @param s The string to put at the end of the key.
+ */
+ private static String get2DConfigData(String configDataName, int r, String s) {
+ return configDataName + r + "_" + s; //$NON-NLS-1$
+ }
+
+ /**
+ * Returns the total number of regular expressions of the current configuration.
+ */
+ private int getNumberOfRegexs() {
+ return outputList.size();
+ }
+
+ @Override
+ public void createControl(Composite parent) {
+ GridLayout layout = new GridLayout();
+ Composite top = new Composite(parent, SWT.NONE);
+ setControl(top);
+ top.setLayout(layout);
+ top.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
+
+ this.runWithChartCheckButton = new Button(top, SWT.CHECK);
+ runWithChartCheckButton.setText(Messages.SystemTapScriptGraphOptionsTab_graphOutputRun);
+ runWithChartCheckButton.addSelectionListener(new SelectionListener() {
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ setGraphingEnabled(runWithChartCheckButton.getSelection());
+ }
+
+ @Override
+ public void widgetDefaultSelected(SelectionEvent e) {
+ setGraphingEnabled(runWithChartCheckButton.getSelection());
+ }
+ });
+
+ runWithChartCheckButton.setToolTipText(Messages.SystemTapScriptGraphOptionsTab_graphOutput);
+
+ this.outputParsingGroup = new Group(top, SWT.SHADOW_ETCHED_IN);
+ outputParsingGroup.setText(Messages.SystemTapScriptGraphOptionsTab_outputLabel);
+ outputParsingGroup.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
+ this.createColumnSelector(outputParsingGroup);
+
+ this.graphsGroup = new Group(top, SWT.SHADOW_ETCHED_IN);
+ // Set the text here just to allow proper sizing.
+ graphsGroup.setText(MessageFormat.format(Messages.SystemTapScriptGraphOptionsTab_graphSetTitleBase, 1));
+ graphsGroup.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
+ createGraphCreateArea(graphsGroup);
+
+ setGraphingEnabled(false);
+ runWithChartCheckButton.setSelection(false);
+ }
+
+ private void createColumnSelector(Composite parent) {
+
+ GridLayout layout = new GridLayout();
+ parent.setLayout(layout);
+
+ Composite topLayout = new Composite(parent, SWT.NONE);
+ topLayout.setLayout(new GridLayout(1, false));
+ 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(new GridLayout(3, false));
+ regexButtonLayout.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
+
+ Label selectedRegexLabel = new Label(regexButtonLayout, SWT.NONE);
+ selectedRegexLabel.setText(Messages.SystemTapScriptGraphOptionsTab_regexLabel);
+ selectedRegexLabel.setToolTipText(Messages.SystemTapScriptGraphOptionsTab_regexTooltip);
+ regularExpressionCombo = new Combo(regexButtonLayout, SWT.DROP_DOWN);
+ regularExpressionCombo.setTextLimit(MAX_REGEX_LENGTH);
+ regularExpressionCombo.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
+ regularExpressionCombo.addSelectionListener(new SelectionAdapter() {
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ int selected = regularExpressionCombo.getSelectionIndex();
+ if (selected == selectedRegex) {
+ return;
+ }
+
+ // If deselecting an empty regular expression, delete it automatically.
+ if (regularExpressionCombo.getItem(selectedRegex).isEmpty()
+ && graphsDataList.get(selectedRegex).size() == 0
+ && outputList.get(selectedRegex).isEmpty()) {
+
+ // If the deselected regex is the last one in the combo, just quit.
+ // Otherwise, the deleted blank entry would be replaced by another blank entry.
+ if (selected == regularExpressionCombo.getItemCount() - 1) {
+ regularExpressionCombo.select(selectedRegex); // To keep the text blank.
+ return;
+ }
+ removeRegex(false);
+ if (selected > selectedRegex) {
+ selected--;
+ }
+ }
+
+ // When selecting the "Add New Regex" item in the combo (which is always the last item),
+ // update all appropriate values to make room for a new regular expression.
+ if (selected == regularExpressionCombo.getItemCount() - 1 && getNumberOfRegexs() < MAX_NUMBER_OF_REGEXS) {
+ outputList.add(""); //$NON-NLS-1$
+ regexErrorMessages.add(null);
+ columnNamesList.add(new ArrayList<String>());
+ cachedNamesList.add(new Stack<String>());
+ graphsDataList.add(new LinkedList<GraphData>());
+
+ // Remove "Add New Regex" from the selected combo item; make it blank.
+ regularExpressionCombo.setItem(selected, ""); //$NON-NLS-1$
+ regularExpressionCombo.select(selected);
+ updateRegexSelection(selected, false);
+ updateLaunchConfigurationDialog();
+
+ // Enable the "remove" button if only one item was present before.
+ // (Don't do this _every_ time something is added.)
+ if (getNumberOfRegexs() == 2) {
+ removeRegexButton.setEnabled(true);
+ }
+ if (getNumberOfRegexs() < MAX_NUMBER_OF_REGEXS) {
+ regularExpressionCombo.add(Messages.SystemTapScriptGraphOptionsTab_regexAddNew);
+ }
+ } else {
+ updateRegexSelection(selected, false);
+ }
+ }
+ });
+ regularExpressionCombo.addModifyListener(regexListener);
+
+ removeRegexButton = new Button(regexButtonLayout, SWT.PUSH);
+ removeRegexButton.setLayoutData(new GridData(SWT.BEGINNING, SWT.BEGINNING, false, false));
+ removeRegexButton.setText(Messages.SystemTapScriptGraphOptionsTab_regexRemove);
+ removeRegexButton.addSelectionListener(new SelectionAdapter() {
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ IWorkbench workbench = PlatformUI.getWorkbench();
+ MessageDialog dialog = new MessageDialog(workbench
+ .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$
+ int result = dialog.open();
+ if (result == 0) { //Yes
+ removeRegex(true);
+ }
+ }
+ });
+
+ GridLayout twoColumns = new GridLayout(2, false);
+
+ Composite regexSummaryComposite = new Composite(parent, SWT.NONE);
+ regexSummaryComposite.setLayout(twoColumns);
+ regexSummaryComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
+
+ Label sampleOutputLabel = new Label(regexSummaryComposite, SWT.NONE);
+ sampleOutputLabel.setText(Messages.SystemTapScriptGraphOptionsTab_sampleOutputLabel);
+ sampleOutputLabel.setToolTipText(Messages.SystemTapScriptGraphOptionsTab_sampleOutputTooltip);
+ this.sampleOutputText = new Text(regexSummaryComposite, SWT.BORDER);
+ this.sampleOutputText.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
+ this.sampleOutputText.addModifyListener(sampleOutputListener);
+ sampleOutputText.setToolTipText(Messages.SystemTapScriptGraphOptionsTab_sampleOutputTooltip);
+
+
+ Composite expressionTableLabels = new Composite(parent, SWT.NONE);
+ expressionTableLabels.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false));
+ expressionTableLabels.setLayout(twoColumns);
+
+ Label label = new Label(expressionTableLabels, SWT.NONE);
+ label.setText(Messages.SystemTapScriptGraphOptionsTab_columnTitle);
+ label.setAlignment(SWT.LEFT);
+
+ Label label2 = new Label(expressionTableLabels, SWT.NONE);
+ label2.setAlignment(SWT.LEFT);
+ label2.setText(Messages.SystemTapScriptGraphOptionsTab_extractedValueLabel);
+
+ this.regexTextScrolledComposite = new ScrolledComposite(parent, SWT.V_SCROLL | SWT.BORDER);
+ GridData data = new GridData(SWT.FILL, SWT.FILL, true, false);
+ data.heightHint = 200;
+ regexTextScrolledComposite.setLayoutData(data);
+
+ textFieldsComposite = new Composite(regexTextScrolledComposite, SWT.NONE);
+ textFieldsComposite.setLayout(new GridLayout(4, false));
+ regexTextScrolledComposite.setContent(textFieldsComposite);
+ regexTextScrolledComposite.setExpandHorizontal(true);
+
+ // To position the column labels properly, add a dummy column and use its children's sizes for reference.
+ // This is necessary since expressionTableLabels can't share a layout with textFieldsComposite.
+ textListenersEnabled = false;
+ addColumn(""); //$NON-NLS-1$
+ data = new GridData(SWT.FILL, SWT.FILL, false, false);
+ data.horizontalIndent = textFieldsComposite.getChildren()[2].getLocation().x;
+ data.widthHint = textFieldsComposite.getChildren()[2].getSize().x;
+ label.setLayoutData(data);
+ label2.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false));
+ removeColumn(false);
+ textListenersEnabled = true;
+ }
+
+ private IDataSet getCurrentDataset() {
+ return DataSetFactory.createDataSet(RowDataSet.ID, columnNamesList.get(selectedRegex).toArray(new String[] {}));
+ }
+
+ private void createGraphCreateArea(Composite comp) {
+ comp.setLayout(new GridLayout(2, false));
+
+ graphsTable = new Table(comp, SWT.SINGLE | SWT.BORDER);
+ GridData layoutData = new GridData(SWT.FILL, SWT.FILL, true, true);
+ graphsTable.setLayoutData(layoutData);
+
+ // Button to add another graph
+ Composite buttonComposite = new Composite(comp, SWT.NONE);
+ buttonComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false));
+
+ GridLayout gridLayout = new GridLayout();
+ gridLayout.numColumns = 1;
+
+ buttonComposite.setLayout(gridLayout);
+ // Button to add a new graph
+ addGraphButton = new Button(buttonComposite, SWT.PUSH);
+ addGraphButton.setText(Messages.SystemTapScriptGraphOptionsTab_AddGraphButton);
+ addGraphButton.setToolTipText(Messages.SystemTapScriptGraphOptionsTab_AddGraphButtonToolTip);
+ addGraphButton.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
+
+ // Button to copy an existing graph
+ duplicateGraphButton = new Button(buttonComposite, SWT.PUSH);
+ duplicateGraphButton.setText(Messages.SystemTapScriptGraphOptionsTab_DuplicateGraphButton);
+ duplicateGraphButton.setToolTipText(Messages.SystemTapScriptGraphOptionsTab_DuplicateGraphButtonToolTip);
+ duplicateGraphButton.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
+
+ // Button to edit an existing graph
+ editGraphButton = new Button(buttonComposite, SWT.PUSH);
+ editGraphButton.setText(Messages.SystemTapScriptGraphOptionsTab_EditGraphButton);
+ editGraphButton.setToolTipText(Messages.SystemTapScriptGraphOptionsTab_EditGraphButtonToolTip);
+ editGraphButton.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
+
+ // Button to remove the selected graph/filter
+ removeGraphButton = new Button(buttonComposite, SWT.PUSH);
+ removeGraphButton.setText(Messages.SystemTapScriptGraphOptionsTab_RemoveGraphButton);
+ removeGraphButton.setToolTipText(Messages.SystemTapScriptGraphOptionsTab_RemoveGraphButtonToolTip);
+ removeGraphButton.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
+
+ // Action to notify the buttons when to enable/disable themselves based
+ // on list selection
+ graphsTable.addSelectionListener(new SelectionAdapter() {
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ selectedTableItem = (TableItem) e.item;
+ setSelectionControlsEnabled(true);
+ }
+ });
+
+ // Brings up a new dialog box when user clicks the add button. Allows
+ // selecting a new graph to display.
+ addGraphButton.addSelectionListener(new SelectionAdapter() {
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ SelectGraphAndSeriesWizard wizard = new SelectGraphAndSeriesWizard(getCurrentDataset(), null);
+ IWorkbench workbench = PlatformUI.getWorkbench();
+ wizard.init(workbench, null);
+ WizardDialog dialog = new WizardDialog(workbench
+ .getActiveWorkbenchWindow().getShell(), wizard);
+ dialog.create();
+ dialog.open();
+
+ GraphData gd = wizard.getGraphData();
+
+ if (null != gd) {
+ TableItem item = new TableItem(graphsTable, SWT.NONE);
+ graphsData.add(gd);
+ setUpGraphTableItem(item, gd, false);
+ updateLaunchConfigurationDialog();
+ }
+ }
+ });
+
+ // Adds a new entry to the list of graphs that is a copy of the one selected.
+ duplicateGraphButton.addSelectionListener(new SelectionAdapter() {
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ GraphData gd = ((GraphData) selectedTableItem.getData()).getCopy();
+
+ TableItem item = new TableItem(graphsTable, SWT.NONE);
+ graphsData.add(gd);
+ if (badGraphs.contains(selectedTableItem.getData())) {
+ badGraphs.add(gd);
+ setUpGraphTableItem(item, gd, true);
+ } else {
+ setUpGraphTableItem(item, gd, false);
+ }
+ updateLaunchConfigurationDialog();
+ }
+ });
+
+ // When button is clicked, brings up same wizard as the one for adding
+ // a graph. Data in the wizard is filled out to match the properties
+ // of the selected graph.
+ editGraphButton.addSelectionListener(new SelectionAdapter() {
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ SelectGraphAndSeriesWizard wizard = new SelectGraphAndSeriesWizard(getCurrentDataset(),
+ (GraphData) selectedTableItem.getData());
+ IWorkbench workbench = PlatformUI.getWorkbench();
+ wizard.init(workbench, null);
+ WizardDialog dialog = new WizardDialog(workbench
+ .getActiveWorkbenchWindow().getShell(), wizard);
+ dialog.create();
+ dialog.open();
+
+ GraphData gd = wizard.getGraphData();
+ if (null == gd) {
+ return;
+ }
+ GraphData old_gd = (GraphData) selectedTableItem.getData();
+ if (!gd.equals(old_gd)) {
+ badGraphs.remove(old_gd);
+ setUpGraphTableItem(selectedTableItem, gd, false);
+ graphsData.set(graphsTable.indexOf(selectedTableItem), gd);
+ checkErrors(selectedRegex);
+ updateLaunchConfigurationDialog();
+ }
+ }
+ });
+
+ // Removes the selected graph/filter from the table
+ removeGraphButton.addSelectionListener(new SelectionAdapter() {
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ GraphData gd = (GraphData) selectedTableItem.getData();
+ graphsData.remove(gd);
+ badGraphs.remove(gd);
+ selectedTableItem.dispose();
+ setSelectionControlsEnabled(false);
+ checkErrors(selectedRegex);
+ updateLaunchConfigurationDialog();
+ }
+ });
+ }
+
+ private void removeRegex(boolean autoSelect) {
+ int removedRegex = selectedRegex;
+ if (autoSelect) {
+ // The current selection is to be removed, so select something else that will be available.
+ regularExpressionCombo.select(selectedRegex != 0 ? selectedRegex - 1 : 1);
+ updateRegexSelection(regularExpressionCombo.getSelectionIndex(), false);
+ }
+
+ regularExpressionCombo.remove(removedRegex);
+ outputList.remove(removedRegex);
+ regexErrorMessages.remove(removedRegex);
+ columnNamesList.remove(removedRegex);
+ cachedNamesList.remove(removedRegex);
+ graphsDataList.remove(removedRegex);
+
+ if (autoSelect) {
+ // Make sure the index of the selection is accurate.
+ selectedRegex = regularExpressionCombo.getSelectionIndex();
+ }
+
+ // Re-add the "Add New Regex" entry if it is missing.
+ if (getNumberOfRegexs() == MAX_NUMBER_OF_REGEXS - 1) {
+ regularExpressionCombo.add(Messages.SystemTapScriptGraphOptionsTab_regexAddNew);
+ }
+
+ // Disable the "remove" button if only one selection is left; never want zero items.
+ if (getNumberOfRegexs() == 1) {
+ removeRegexButton.setEnabled(false);
+ }
+ updateLaunchConfigurationDialog();
+ }
+
+ /**
+ * This handles UI & list updating whenever a different regular expression is selected.
+ * @param newSelection The index of the regex to be selected.
+ * @param force If true, the UI will update even if the index of the selected regex did not change.
+ */
+ private void updateRegexSelection(int newSelection, boolean force) {
+ // Quit if the selection didn't change anything, or if the selection is invalid (-1).
+ if (newSelection == -1 || (!force && selectedRegex == newSelection)) {
+ return;
+ }
+ selectedRegex = newSelection;
+
+ boolean textListenersDisabled = !textListenersEnabled;
+ if (!textListenersDisabled) {
+ textListenersEnabled = false;
+ }
+
+ sampleOutputText.setText(outputList.get(selectedRegex));
+ cachedNames = cachedNamesList.get(selectedRegex);
+
+ // Update the number of columns and their titles here, and not in refreshRegexRows,
+ // using the list of saved active names instead of a cachedNames stack.
+ ArrayList<String> columnNames = columnNamesList.get(selectedRegex);
+ int desiredNumberOfColumns = columnNames.size();
+ // Remove all columns to easily update them all immediately afterwards.
+ while (numberOfVisibleColumns > 0) {
+ removeColumn(false);
+ }
+ while (numberOfVisibleColumns < desiredNumberOfColumns) {
+ addColumn(columnNames.get(numberOfVisibleColumns));
+ }
+
+ refreshRegexRows();
+
+ // Now, only display graphs that are associated with the selected regex.
+ graphsData = graphsDataList.get(selectedRegex);
+ graphsTable.removeAll();
+ selectedTableItem = null;
+ setSelectionControlsEnabled(false);
+
+ for (GraphData gd : graphsData) {
+ TableItem item = new TableItem(graphsTable, SWT.NONE);
+ setUpGraphTableItem(item, gd, badGraphs.contains(gd));
+ }
+ graphsGroup.setText(MessageFormat.format(Messages.SystemTapScriptGraphOptionsTab_graphSetTitleBase,
+ selectedRegex + 1));
+
+ if (!textListenersDisabled) {
+ textListenersEnabled = true;
+ }
+ }
+
+ private void refreshRegexRows() {
+ try {
+ pattern = Pattern.compile(regularExpressionCombo.getText());
+ matcher = pattern.matcher(sampleOutputText.getText());
+ regexErrorMessages.set(selectedRegex, null);
+ } catch (PatternSyntaxException e) {
+ regexErrorMessages.set(selectedRegex, e.getMessage());
+ return;
+ }
+ regexErrorMessages.set(selectedRegex, checkRegex(regularExpressionCombo.getText()));
+ if (regexErrorMessages.get(selectedRegex) != null) {
+ return;
+ }
+
+ int desiredNumberOfColumns = matcher.groupCount();
+
+ while (numberOfVisibleColumns < desiredNumberOfColumns) {
+ addColumn(null);
+ }
+
+ while (numberOfVisibleColumns > desiredNumberOfColumns) {
+ removeColumn(true);
+ }
+
+ // Set values
+ Control[] children = textFieldsComposite.getChildren();
+ for (int i = 0; i < numberOfVisibleColumns; i++) {
+ String sampleOutputResults;
+ if (matcher.matches()) {
+ sampleOutputResults = matcher.group(i+1);
+ }
+ else if (sampleOutputText.getText().length() == 0) {
+ sampleOutputResults = Messages.SystemTapScriptGraphOptionsTab_sampleOutputIsEmpty;
+ } else {
+ sampleOutputResults = Messages.SystemTapScriptGraphOptionsTab_sampleOutputNoMatch;
+ }
+ ((Label)children[i*4+3]).setText(" " + sampleOutputResults); //$NON-NLS-1$
+ }
+
+ // May only add/edit graphs if there is output data being captured.
+ addGraphButton.setEnabled(numberOfVisibleColumns > 0);
+ if (selectedTableItem != null) {
+ editGraphButton.setEnabled(numberOfVisibleColumns > 0);
+ }
+
+ regexErrorMessages.set(selectedRegex, findBadGraphs(selectedRegex));
+ }
+
+ /**
+ * Checks if a provided regular expression is valid.
+ * @param regex The regular expression to check for validity.
+ * @return <code>null</code> if the regular expression is valid, or an error message.
+ */
+ private static String checkRegex(String regex) {
+ //TODO may add more invalid regexs here, each with its own error message.
+ if (regex.contains("()")) { //$NON-NLS-1$
+ return Messages.SystemTapScriptGraphOptionsTab_emptyGroup;
+ }
+ return null;
+ }
+
+ /**
+ * Adds one column to the list of the currently-selected regex's columns.
+ * This creates an extra Text in which the name of the column may be entered,
+ * and a corresponding Label containing sample expected output.
+ * @param nameToAdd If non-null, the name of the newly-created column will
+ * match this String. If null, the column will be given a name recovered from
+ * the active stack of cached names, or a default name if one doesn't exist.
+ */
+ private void addColumn(String nameToAdd) {
+ // Show the "shift" buttons of the previous column, if it exists.
+ if (this.numberOfVisibleColumns > 0) {
+ textFieldsComposite.getChildren()[(this.numberOfVisibleColumns - 1) * 4].setVisible(true);
+ textFieldsComposite.getChildren()[(this.numberOfVisibleColumns - 1) * 4 + 1].setVisible(true);
+ }
+
+ // Add buttons for shifting column names up/down in the list.
+ Button buttonUp = new Button(textFieldsComposite, SWT.PUSH);
+ buttonUp.setText(Messages.SystemTapScriptGraphOptionsTab_columnShiftUp);
+ buttonUp.setVisible(false);
+ Button buttonDown = new Button(textFieldsComposite, SWT.PUSH);
+ buttonDown.setText(Messages.SystemTapScriptGraphOptionsTab_columnShiftDown);
+ buttonDown.setVisible(false);
+
+ Text text = new Text(textFieldsComposite, SWT.BORDER);
+ GridData data = new GridData(SWT.FILL, SWT.FILL, false, false);
+ data.minimumWidth = 200;
+ data.widthHint = 200;
+ text.setLayoutData(data);
+
+ numberOfVisibleColumns++;
+ text.addModifyListener(columnNameListener);
+ if (nameToAdd == null) {
+ // Restore a deleted name by popping from the stack.
+ if (cachedNames.size() > 0) {
+ text.setText(cachedNames.pop());
+ } else {
+ text.setText(MessageFormat.format(Messages.SystemTapScriptGraphOptionsTab_defaultColumnTitleBase,
+ numberOfVisibleColumns));
+ }
+ } else {
+ text.setText(nameToAdd);
+ }
+
+ Label label = new Label(textFieldsComposite, SWT.BORDER);
+ label.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
+
+ textFieldsComposite.layout();
+ textFieldsComposite.pack();
+
+ // Special value: if an empty string is given, don't add button listeners.
+ if (nameToAdd == "") { //$NON-NLS-1$
+ return;
+ }
+
+ // Add button listeners for shifting column names.
+ buttonUp.addSelectionListener(new SelectionAdapter() {
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ Control clickedButton = (Control) e.widget;
+ Control[] children = textFieldsComposite.getChildren();
+ int currentColumn = 0;
+ for (; currentColumn < numberOfVisibleColumns - 1; currentColumn++) {
+ if (children[currentColumn*4].equals(clickedButton)) {
+ break;
+ }
+ }
+ String edgeName = ((Text)children[currentColumn*4 + 2]).getText();
+ for (int i = currentColumn; i < numberOfVisibleColumns - 1; i++) {
+ ((Text)children[i*4 + 2]).setText(((Text)children[(i + 1)*4 + 2]).getText());
+ }
+ ((Text)children[(numberOfVisibleColumns - 1)*4 + 2]).setText(edgeName);
+ }
+ });
+
+ buttonDown.addSelectionListener(new SelectionAdapter() {
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ Control clickedButton = (Control) e.widget;
+ Control[] children = textFieldsComposite.getChildren();
+ int currentColumn = 0;
+ for (; currentColumn < numberOfVisibleColumns - 1; currentColumn++) {
+ if (children[currentColumn*4 + 1].equals(clickedButton)) {
+ break;
+ }
+ }
+ String edgeName = ((Text)children[(numberOfVisibleColumns - 1)*4 + 2]).getText();
+ for (int i = numberOfVisibleColumns - 1; i > currentColumn; i--) {
+ ((Text)children[i*4 + 2]).setText(((Text)children[(i - 1)*4 + 2]).getText());
+ }
+ ((Text)children[currentColumn*4 + 2]).setText(edgeName);
+ }
+ });
+ }
+
+ /**
+ * Removes a column from the currently-selected regex, and removes its
+ * corresponding Text & Label from the UI.
+ * @param saveNames Set to <code>true</code> if the contents of removed
+ * columns are to be saved in a stack for later use.
+ */
+ private void removeColumn(Boolean saveNames) {
+ Control[] children = textFieldsComposite.getChildren();
+ int i = this.numberOfVisibleColumns*4 - 1;
+
+ if (saveNames) {
+ // Push the removed name on a stack.
+ String name = ((Text)children[i-1]).getText();
+ if (name != null && name != "") { //$NON-NLS-1$
+ cachedNames.push(name);
+ }
+ columnNamesList.get(selectedRegex).remove(numberOfVisibleColumns - 1);
+ }
+
+ children[i].dispose();
+ children[i-1].dispose();
+ children[i-2].dispose();
+ children[i-3].dispose();
+
+ // Hide the previous column's "shift" buttons, if it exists.
+ if (this.numberOfVisibleColumns > 2) {
+ children[i - 6].setVisible(false);
+ children[i - 7].setVisible(false);
+ }
+
+ this.numberOfVisibleColumns--;
+
+ textFieldsComposite.layout();
+ textFieldsComposite.pack();
+ }
+
+ /**
+ * Marks all graphs belonging to the indicated regular expression that have an
+ * error (missing column data, invalid graphID), or unmarks graphs that don't.
+ * @param regex The index of the regular expression to check for invalid graphs.
+ * @return An appropriate error message if an invalid graph is found, or if the
+ * selected regular expression parses nothing.
+ */
+ private String findBadGraphs(int regex) {
+ boolean foundBadID = false;
+ boolean foundRemoved = false;
+ int numberOfColumns = columnNamesList.get(regex).size();
+
+ for (GraphData gd : graphsDataList.get(regex)) {
+ boolean singleBadID = false;
+ boolean singleRemoved = false;
+
+ if (GraphFactory.getGraphName(gd.graphID) == null) {
+ singleBadID = true;
+ } else {
+ if (gd.xSeries >= numberOfColumns) {
+ singleRemoved = true;
+ }
+ for (int s = 0; s < gd.ySeries.length && !singleRemoved; s++) {
+ if (gd.ySeries[s] >= numberOfColumns) {
+ singleRemoved = true;
+ }
+ }
+ }
+ if (singleRemoved || singleBadID) {
+ if (!badGraphs.contains(gd)) {
+ badGraphs.add(gd);
+ setUpGraphTableItem(findGraphTableItem(gd), null, true);
+ }
+ } else if (badGraphs.contains(gd)) {
+ badGraphs.remove(gd);
+ setUpGraphTableItem(findGraphTableItem(gd), null, false);
+ }
+
+ foundBadID |= singleBadID;
+ foundRemoved |= singleRemoved;
+ }
+
+ if (numberOfColumns == 0) {
+ return Messages.SystemTapScriptGraphOptionsTab_noGroups;
+ }
+ if (foundBadID) {
+ return Messages.SystemTapScriptGraphOptionsTab_badGraphID;
+ }
+ if (foundRemoved) {
+ return Messages.SystemTapScriptGraphOptionsTab_deletedGraphData;
+ }
+ return null;
+ }
+
+ private TableItem findGraphTableItem(GraphData gd) {
+ for (TableItem item : graphsTable.getItems()) {
+ if (item.getData().equals(gd)) {
+ return item;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Sets up a given {@link TableItem} with the proper title & appearance based on
+ * its graph data & (in)valid status.
+ * @param item The {@link TableItem} to set up.
+ * @param gd The {@link GraphData} that the item will hold. Set to <code>null</code>
+ * to preserve the item's existing data.
+ * @param bad <code>true</code> if the item should appear as invalid, <code>false</code> otherwise.
+ */
+ private void setUpGraphTableItem(TableItem item, GraphData gd, boolean bad) {
+ // Include a null check to avoid accidentally marking non-visible items.
+ if (item == null) {
+ return;
+ }
+ if (gd != null) {
+ item.setData(gd);
+ } else {
+ gd = (GraphData) item.getData();
+ }
+ item.setForeground(item.getDisplay().getSystemColor(bad ? SWT.COLOR_RED : SWT.COLOR_BLACK));
+ String graphName = GraphFactory.getGraphName(gd.graphID);
+ if (graphName == null) {
+ graphName = Messages.SystemTapScriptGraphOptionsTab_invalidGraphID;
+ }
+ item.setText(graphName + ":" + gd.title //$NON-NLS-1$
+ + (bad ? " " + Messages.SystemTapScriptGraphOptionsTab_invalidGraph : "")); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+ @Override
+ public void setDefaults(ILaunchConfigurationWorkingCopy configuration) {
+ configuration.setAttribute(RUN_WITH_CHART, false);
+ configuration.setAttribute(NUMBER_OF_REGEXS, 1);
+ configuration.setAttribute(NUMBER_OF_COLUMNS + 0, 0);
+ configuration.setAttribute(NUMBER_OF_EXTRAS + 0, 0);
+ configuration.setAttribute(REGULAR_EXPRESSION + 0, ""); //$NON-NLS-1$
+ configuration.setAttribute(SAMPLE_OUTPUT + 0, ""); //$NON-NLS-1$
+ configuration.setAttribute(NUMBER_OF_GRAPHS + 0, 0);
+ }
+
+ @Override
+ public void initializeFrom(ILaunchConfiguration configuration) {
+ try {
+ textListenersEnabled = false;
+
+ // Reset lists & settings to keep things idempotent.
+ regularExpressionCombo.removeAll();
+ outputList.clear();
+ regexErrorMessages.clear();
+ columnNamesList.clear();
+ cachedNamesList.clear();
+ graphsTable.removeAll();
+ badGraphs.clear();
+
+ // There should always be at least one regular expression (a blank one still counts).
+ // If configuration's number of regexs is zero, it is outdated.
+ int numberOfRegexs = Math.max(configuration.getAttribute(NUMBER_OF_REGEXS, 1), 1);
+
+ // Only allow removing regexs if there are more than one.
+ removeRegexButton.setEnabled(numberOfRegexs > 1);
+
+ for (int r = 0; r < numberOfRegexs; r++) {
+ // Save all of the configuration's regular expressions & sample outputs in a list.
+ regularExpressionCombo.add(configuration.getAttribute(REGULAR_EXPRESSION + r, "")); //$NON-NLS-1$
+ outputList.add(configuration.getAttribute(SAMPLE_OUTPUT + r, "")); //$NON-NLS-1$
+
+ // Save each regex's list of group names.
+ int numberOfColumns = configuration.getAttribute(NUMBER_OF_COLUMNS + r, 0);
+ ArrayList<String> namelist = new ArrayList<>(numberOfColumns);
+ for (int i = 0; i < numberOfColumns; i++) {
+ namelist.add(configuration.getAttribute(get2DConfigData(REGEX_BOX, r, i), (String)null));
+ }
+ columnNamesList.add(namelist);
+
+ //Reclaim missing column data that was required for existing graphs at the time of the previous "apply".
+ int numberOfExtras = configuration.getAttribute(NUMBER_OF_EXTRAS + r, 0);
+ Stack<String> oldnames = new Stack<>();
+ for (int i = 0; i < numberOfExtras; i++) {
+ oldnames.push(configuration.getAttribute(get2DConfigData(EXTRA_BOX, r, i), (String)null));
+ }
+ cachedNamesList.add(oldnames);
+
+ regexErrorMessages.add(null);
+ }
+ if (getNumberOfRegexs() < MAX_NUMBER_OF_REGEXS) {
+ regularExpressionCombo.add(Messages.SystemTapScriptGraphOptionsTab_regexAddNew);
+ }
+
+ // When possible, preserve the selection on subsequent initializations, for user convenience.
+ int defaultSelectedRegex = 0 <= selectedRegex && selectedRegex < numberOfRegexs ? selectedRegex : 0;
+ regularExpressionCombo.select(defaultSelectedRegex);
+
+ // Add graphs
+ graphsDataList = createGraphsFromConfiguration(configuration);
+ graphsData = graphsDataList.get(defaultSelectedRegex);
+ for (GraphData graphData : graphsData) {
+ TableItem item = new TableItem(graphsTable, SWT.NONE);
+ setUpGraphTableItem(item, graphData, true);
+ }
+
+ updateRegexSelection(defaultSelectedRegex, true); // Handles all remaining updates.
+ checkAllOtherErrors();
+
+ boolean chart = configuration.getAttribute(RUN_WITH_CHART, false);
+ setGraphingEnabled(chart);
+ this.runWithChartCheckButton.setSelection(chart);
+
+ } catch (CoreException e) {
+ ExceptionErrorDialog.openError(Messages.SystemTapScriptGraphOptionsTab_cantInitializeTab, e);
+ } finally {
+ textListenersEnabled = true;
+ }
+ }
+
+ @Override
+ public void performApply(ILaunchConfigurationWorkingCopy configuration) {
+ configuration.setAttribute(RUN_WITH_CHART, this.runWithChartCheckButton.getSelection());
+
+ int numberOfRegexs = getNumberOfRegexs();
+ for (int r = 0; r < numberOfRegexs; r++) {
+ // Save data sets, and clear removed ones.
+ configuration.setAttribute(REGULAR_EXPRESSION + r, regularExpressionCombo.getItem(r));
+ configuration.setAttribute(SAMPLE_OUTPUT + r, outputList.get(r));
+
+ ArrayList<String> columnNames = columnNamesList.get(r);
+ int numberOfColumns = columnNames.size();
+ for (int i = 0; i < numberOfColumns; i++) {
+ configuration.setAttribute(get2DConfigData(REGEX_BOX, r, i), columnNames.get(i));
+ }
+ cleanUpConfigurationItem(configuration, NUMBER_OF_COLUMNS, REGEX_BOX, r, numberOfColumns);
+ configuration.setAttribute(NUMBER_OF_COLUMNS + r, numberOfColumns);
+
+ // If the current regex has graphs with missing data, store all cached names
+ // in the configuration so that they will be easily restorable for next time.
+ Stack<String> extranames = cachedNamesList.get(r);
+ int numberOfExtras = findBadGraphs(r) == null ? 0 : extranames.size();
+ for (int i = 0; i < numberOfExtras; i++) {
+ configuration.setAttribute(get2DConfigData(EXTRA_BOX, r, i), extranames.get(i));
+ }
+ cleanUpConfigurationItem(configuration, NUMBER_OF_EXTRAS, EXTRA_BOX, r, numberOfExtras);
+ configuration.setAttribute(NUMBER_OF_EXTRAS + r, numberOfExtras);
+
+ // Save new graphs, and clear removed ones.
+ LinkedList<GraphData> list = graphsDataList.get(r);
+ int numberOfGraphs = list.size();
+ for (int i = 0; i < numberOfGraphs; i++) {
+ GraphData graphData = list.get(i);
+ configuration.setAttribute(get2DConfigData(GRAPH_TITLE, r, i), graphData.title);
+ configuration.setAttribute(get2DConfigData(GRAPH_KEY, r, i), graphData.key);
+ configuration.setAttribute(get2DConfigData(GRAPH_X_SERIES, r, i), graphData.xSeries);
+ configuration.setAttribute(get2DConfigData(GRAPH_ID, r, i), graphData.graphID);
+
+ int ySeriesLength = graphData.ySeries.length;
+ for (int j = 0; j < ySeriesLength; j++) {
+ configuration.setAttribute(get2DConfigData(GRAPH_Y_SERIES, r, i + "_" + j), //$NON-NLS-1$
+ graphData.ySeries[j]);
+ }
+ cleanUpConfigurationGraphYSeries(configuration, r, i, ySeriesLength);
+ configuration.setAttribute(get2DConfigData(GRAPH_Y_SERIES_LENGTH, r, i), ySeriesLength);
+ }
+ cleanUpConfigurationGraphs(configuration, r, numberOfGraphs);
+ configuration.setAttribute(NUMBER_OF_GRAPHS + r, numberOfGraphs);
+ }
+ cleanUpConfiguration(configuration, numberOfRegexs);
+ configuration.setAttribute(NUMBER_OF_REGEXS, numberOfRegexs);
+ }
+
+ /**
+ * Removes all configuration attributes associated with deleted regular expressions.
+ * @param configuration The configuration to remove attributes from.
+ * @param numberOfRegexs The number of regex-related properties to exist in the
+ * configuration after cleanup.
+ */
+ private void cleanUpConfiguration(ILaunchConfigurationWorkingCopy configuration, int numberOfRegexs) {
+ int oldNumberOfRegexs = 0;
+ try {
+ oldNumberOfRegexs = configuration.getAttribute(NUMBER_OF_REGEXS, 0);
+ } catch (CoreException e) {}
+ for (int r = numberOfRegexs; r < oldNumberOfRegexs; r++) {
+ configuration.removeAttribute(REGULAR_EXPRESSION + r);
+ configuration.removeAttribute(SAMPLE_OUTPUT + r);
+
+ cleanUpConfigurationItem(configuration, NUMBER_OF_COLUMNS, REGEX_BOX, r, 0);
+ configuration.removeAttribute(NUMBER_OF_COLUMNS + r);
+
+ cleanUpConfigurationItem(configuration, NUMBER_OF_COLUMNS, EXTRA_BOX, r, 0);
+ configuration.removeAttribute(NUMBER_OF_EXTRAS + r);
+
+ cleanUpConfigurationGraphs(configuration, r, 0);
+ configuration.removeAttribute(NUMBER_OF_GRAPHS + r);
+ }
+ }
+
+ private void cleanUpConfigurationGraphs(ILaunchConfigurationWorkingCopy configuration, int regex, int newNumberOfGraphs) {
+ int oldNumberOfGraphs = 0;
+ try {
+ oldNumberOfGraphs = configuration.getAttribute(NUMBER_OF_GRAPHS + regex, 0);
+ } catch (CoreException e) {}
+ for (int i = newNumberOfGraphs; i < oldNumberOfGraphs; i++) {
+ configuration.removeAttribute(get2DConfigData(GRAPH_TITLE, regex, i));
+ configuration.removeAttribute(get2DConfigData(GRAPH_KEY, regex, i));
+ configuration.removeAttribute(get2DConfigData(GRAPH_X_SERIES, regex, i));
+ configuration.removeAttribute(get2DConfigData(GRAPH_ID, regex, i));
+
+ cleanUpConfigurationGraphYSeries(configuration, regex, i, 0);
+ configuration.removeAttribute(get2DConfigData(GRAPH_Y_SERIES_LENGTH, regex, i));
+ }
+ }
+
+ private void cleanUpConfigurationItem(ILaunchConfigurationWorkingCopy configuration, String counter, String property, int regex, int newNumberOfItems) {
+ int oldNumberOfItems = 0;
+ try {
+ oldNumberOfItems = configuration.getAttribute(counter + regex, 0);
+ } catch (CoreException e) {}
+ for (int i = newNumberOfItems; i < oldNumberOfItems; i++) {
+ configuration.removeAttribute(get2DConfigData(property, regex, i));
+ }
+ }
+
+ private void cleanUpConfigurationGraphYSeries(ILaunchConfigurationWorkingCopy configuration, int regex, int graph, int newLength) {
+ int oldYSeriesLength = 0;
+ try {
+ oldYSeriesLength = configuration.getAttribute(get2DConfigData(GRAPH_Y_SERIES_LENGTH, regex, graph), 0);
+ } catch (CoreException e) {}
+ for (int i = newLength; i < oldYSeriesLength; i++) {
+ configuration.removeAttribute(get2DConfigData(GRAPH_Y_SERIES, regex, graph + "_" + i)); //$NON-NLS-1$
+ }
+ }
+
+ /**
+ * Checks all regular expressions for errors, except for the currently-selected
+ * expression (as it should be checked by {@link #refreshRegexRows}).
+ */
+ private void checkAllOtherErrors() {
+ for (int i = 0, n = getNumberOfRegexs(); i < n; i++) {
+ if (i == selectedRegex) {
+ continue;
+ }
+ checkErrors(i);
+ }
+ }
+
+ /**
+ * Checks the regular expression of the provided index for errors.
+ * Sets the associated error message to contain relevant error information.
+ * @param i The index of the regular expression to check for errors.
+ */
+ private void checkErrors(int i) {
+ String regex = regularExpressionCombo.getItem(i);
+ try {
+ Pattern.compile(regex);
+ } catch (PatternSyntaxException e) {
+ regexErrorMessages.set(i, e.getMessage());
+ return;
+ }
+
+ String error = findBadGraphs(i);
+ if (error == null) {
+ error = checkRegex(regex);
+ }
+
+ regexErrorMessages.set(i, error);
+ }
+
+ @Override
+ public boolean isValid(ILaunchConfiguration launchConfig) {
+ setErrorMessage(null);
+
+ // If graphic is disabled then everything is valid.
+ if (!this.graphingEnabled) {
+ return true;
+ }
+
+ for (int r = 0, n = getNumberOfRegexs(); r < n; r++) {
+ String regexErrorMessage = regexErrorMessages.get(r);
+ if (regexErrorMessage != null) {
+ setErrorMessage(MessageFormat.format(Messages.SystemTapScriptGraphOptionsTab_regexErrorMsgFormat,
+ regularExpressionCombo.getItems()[r], regexErrorMessage));
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ /**
+ * Checks if a launch configuration's Systemtap Graphing settings are valid.
+ * @param launchConfig The launch configuration to check for graph validity.
+ * @return <code>true</code> if the launch settings are valid, or <code>false</code> if
+ * its graph settings are invalid in some way.
+ * @since 2.2
+ */
+ public static boolean isValidLaunch(ILaunchConfiguration launchConfig) throws CoreException {
+ // If graphic is disabled then everything is valid.
+ if (!launchConfig.getAttribute(RUN_WITH_CHART, false)) {
+ return true;
+ }
+
+ for (int r = 0, n = launchConfig.getAttribute(NUMBER_OF_REGEXS, 1); r < n; r++) {
+ // Check for any invalid regexs.
+ String regex = launchConfig.getAttribute(REGULAR_EXPRESSION + r, (String) null);
+ if (regex == null || checkRegex(regex) != null) {
+ return false;
+ }
+ try {
+ Pattern.compile(regex);
+ } catch (PatternSyntaxException e) {
+ return false;
+ }
+
+ // If graphs are plotted but no data is captured by one of them, report this as a problem.
+ int numberOfColumns = launchConfig.getAttribute(NUMBER_OF_COLUMNS + r, 0);
+ if (numberOfColumns == 0) {
+ return false;
+ }
+
+ // Check for graphs that are missing required data.
+ for (int i = 0, g = launchConfig.getAttribute(NUMBER_OF_GRAPHS + r, 0); i < g; i++) {
+ if (GraphFactory.getGraphName(launchConfig.getAttribute(get2DConfigData(GRAPH_ID, r, i), (String) null)) == null) {
+ return false;
+ }
+ if (launchConfig.getAttribute(get2DConfigData(GRAPH_X_SERIES, r, i), 0) >= numberOfColumns) {
+ return false;
+ }
+ for (int j = 0, y = launchConfig.getAttribute(get2DConfigData(GRAPH_Y_SERIES_LENGTH, r, i), 0); j < y; j++) {
+ if (launchConfig.getAttribute(get2DConfigData(GRAPH_Y_SERIES, r, i + "_" + j), 0) >= numberOfColumns) { //$NON-NLS-1$
+ return false;
+ }
+ }
+ }
+ }
+
+ return true;
+ }
+
+ @Override
+ public String getName() {
+ return Messages.SystemTapScriptGraphOptionsTab_graphingTitle;
+ }
+
+ @Override
+ public Image getImage() {
+ return AbstractUIPlugin.imageDescriptorFromPlugin(IDEPlugin.PLUGIN_ID,
+ "icons/graphing_tab.gif").createImage(); //$NON-NLS-1$
+ }
+
+ private void setGraphingEnabled(boolean enabled) {
+ this.graphingEnabled = enabled;
+ this.setControlEnabled(outputParsingGroup, enabled);
+ this.setControlEnabled(graphsGroup, enabled);
+ // Disable buttons that rely on a selected graph if no graph is selected.
+ this.setSelectionControlsEnabled(selectedTableItem != null);
+ this.addGraphButton.setEnabled(enabled && numberOfVisibleColumns > 0);
+ this.removeRegexButton.setEnabled(enabled && getNumberOfRegexs() > 1);
+ updateLaunchConfigurationDialog();
+ }
+
+ private void setControlEnabled(Composite composite, boolean enabled) {
+ composite.setEnabled(enabled);
+ for (Control child : composite.getChildren()) {
+ child.setEnabled(enabled);
+ if (child instanceof Composite) {
+ setControlEnabled((Composite)child, enabled);
+ }
+ }
+ }
+
+ /**
+ * Call this to enable/disable all buttons whose actions depend on a selected graph.
+ * @param enabled Set to true to enable the buttons; set to false to disable them.
+ */
+ private void setSelectionControlsEnabled(boolean enabled) {
+ duplicateGraphButton.setEnabled(enabled);
+ editGraphButton.setEnabled(enabled && numberOfVisibleColumns > 0);
+ removeGraphButton.setEnabled(enabled);
+ }
}
diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/launcher/SystemTapScriptLaunch.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/launcher/SystemTapScriptLaunch.java
index 7a04169047..36444cea05 100644
--- a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/launcher/SystemTapScriptLaunch.java
+++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/launcher/SystemTapScriptLaunch.java
@@ -9,95 +9,95 @@ import org.eclipse.linuxtools.systemtap.ui.consolelog.structures.ScriptConsole;
import org.eclipse.linuxtools.systemtap.ui.consolelog.structures.ScriptConsole.ScriptConsoleObserver;
public class SystemTapScriptLaunch extends Launch
- implements ScriptConsoleObserver {
+ implements ScriptConsoleObserver {
- private ScriptConsole console = null;
- private boolean runStarted = false;
- private boolean runStopped = false;
+ private ScriptConsole console = null;
+ private boolean runStarted = false;
+ private boolean runStopped = false;
- public SystemTapScriptLaunch(ILaunchConfiguration launchConfiguration, String mode) {
- super(launchConfiguration, mode, null);
- }
+ public SystemTapScriptLaunch(ILaunchConfiguration launchConfiguration, String mode) {
+ super(launchConfiguration, mode, null);
+ }
- public void setConsole(ScriptConsole console) {
- // If another launch is using the same console, remove that launch since
- // ScriptConsole prevents two identical stap scripts from being be run at once.
- this.console = console;
- ILaunchManager manager = DebugPlugin.getDefault().getLaunchManager();
- for (ILaunch launch : manager.getLaunches()) {
- if (launch.equals(this)) {
- continue;
- }
- if (launch instanceof SystemTapScriptLaunch) {
- SystemTapScriptLaunch olaunch = (SystemTapScriptLaunch) launch;
- if (olaunch.console == null || olaunch.console.equals(console)) {
- olaunch.forceRemove();
- }
- }
- }
- console.addScriptConsoleObserver(this);
- }
+ public void setConsole(ScriptConsole console) {
+ // If another launch is using the same console, remove that launch since
+ // ScriptConsole prevents two identical stap scripts from being be run at once.
+ this.console = console;
+ ILaunchManager manager = DebugPlugin.getDefault().getLaunchManager();
+ for (ILaunch launch : manager.getLaunches()) {
+ if (launch.equals(this)) {
+ continue;
+ }
+ if (launch instanceof SystemTapScriptLaunch) {
+ SystemTapScriptLaunch olaunch = (SystemTapScriptLaunch) launch;
+ if (olaunch.console == null || olaunch.console.equals(console)) {
+ olaunch.forceRemove();
+ }
+ }
+ }
+ console.addScriptConsoleObserver(this);
+ }
- public ScriptConsole getConsole() {
- return console;
- }
+ public ScriptConsole getConsole() {
+ return console;
+ }
- @Override
- public void runningStateChanged(boolean started, boolean stopped) {
- if (!runStarted && started) {
- runStarted = started;
- if (console.getCommand().getProcess() != null) {
- DebugPlugin.newProcess(this, console.getCommand().getProcess(), console.getName());
- }
- if (stopped) {
- runStopped = true;
- }
- console.removeScriptConsoleObserver(this);
- }
- }
+ @Override
+ public void runningStateChanged(boolean started, boolean stopped) {
+ if (!runStarted && started) {
+ runStarted = started;
+ if (console.getCommand().getProcess() != null) {
+ DebugPlugin.newProcess(this, console.getCommand().getProcess(), console.getName());
+ }
+ if (stopped) {
+ runStopped = true;
+ }
+ console.removeScriptConsoleObserver(this);
+ }
+ }
- @Override
- public boolean canTerminate() {
- return !isTerminated();
- }
+ @Override
+ public boolean canTerminate() {
+ return !isTerminated();
+ }
- @Override
- public boolean isTerminated() {
- if (!runStopped) {
- if (super.isTerminated() || (console != null && !console.isRunning())) {
- runStopped = true;
- }
- }
- return runStopped;
- }
+ @Override
+ public boolean isTerminated() {
+ if (!runStopped) {
+ if (super.isTerminated() || (console != null && !console.isRunning())) {
+ runStopped = true;
+ }
+ }
+ return runStopped;
+ }
- @Override
- public void terminate() {
- if (console != null) {
- console.stop();
- }
- }
+ @Override
+ public void terminate() {
+ if (console != null) {
+ console.stop();
+ }
+ }
- @Override
- public void launchRemoved(ILaunch launch) {
- super.launchRemoved(launch);
- if (launch.equals(this)) {
- removeConsole();
- }
- }
+ @Override
+ public void launchRemoved(ILaunch launch) {
+ super.launchRemoved(launch);
+ if (launch.equals(this)) {
+ removeConsole();
+ }
+ }
- private void removeConsole() {
- if (console != null) {
- console.removeScriptConsoleObserver(this);
- console.stop();
- console = null;
- }
- }
+ private void removeConsole() {
+ if (console != null) {
+ console.removeScriptConsoleObserver(this);
+ console.stop();
+ console = null;
+ }
+ }
- public void forceRemove() {
- removeConsole();
- runStopped = true;
- ILaunchManager manager = DebugPlugin.getDefault().getLaunchManager();
- manager.removeLaunch(this);
- }
+ public void forceRemove() {
+ removeConsole();
+ runStopped = true;
+ ILaunchManager manager = DebugPlugin.getDefault().getLaunchManager();
+ manager.removeLaunch(this);
+ }
}
diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/launcher/SystemTapScriptLaunchConfigurationDelegate.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/launcher/SystemTapScriptLaunchConfigurationDelegate.java
index c22b853873..8f95f5c435 100644
--- a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/launcher/SystemTapScriptLaunchConfigurationDelegate.java
+++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/launcher/SystemTapScriptLaunchConfigurationDelegate.java
@@ -42,137 +42,137 @@ import org.eclipse.linuxtools.systemtap.structures.process.SystemTapRuntimeProce
import org.eclipse.linuxtools.systemtap.ui.consolelog.structures.RemoteScriptOptions;
public class SystemTapScriptLaunchConfigurationDelegate extends
- LaunchConfigurationDelegate {
-
- static final String CONFIGURATION_TYPE = "org.eclipse.linuxtools.systemtap.ui.ide.SystemTapLaunchConfigurationType"; //$NON-NLS-1$
-
- private IProject[] scriptProject;
-
- /**
- * Keep a reference to the target running script's parent project, so only that project
- * will be saved when the script is run.
- */
- @Override
- protected IProject[] getBuildOrder(ILaunchConfiguration configuration, String mode) {
- return scriptProject;
- }
-
- @Override
- public ILaunch getLaunch(ILaunchConfiguration configuration, String mode) {
- return new SystemTapScriptLaunch(configuration, mode);
- }
-
- @Override
- public boolean preLaunchCheck(ILaunchConfiguration configuration, String mode, IProgressMonitor monitor) throws CoreException {
- // Force the configuration to use the proper Process Factory.
- if (!configuration.getAttribute(DebugPlugin.ATTR_PROCESS_FACTORY_ID, "").equals(SystemTapRuntimeProcessFactory.PROCESS_FACTORY_ID)) { //$NON-NLS-1$
- ILaunchConfigurationWorkingCopy wc = configuration.getWorkingCopy();
- wc.setAttribute(DebugPlugin.ATTR_PROCESS_FACTORY_ID, SystemTapRuntimeProcessFactory.PROCESS_FACTORY_ID);
- wc.doSave();
- }
- // Find the parent project of the target script.
- IPath path = Path.fromOSString(configuration.getAttribute(SystemTapScriptLaunchConfigurationTab.SCRIPT_PATH_ATTR, (String)null));
- IFile file = ResourcesPlugin.getWorkspace().getRoot().getFileForLocation(path);
- scriptProject = file == null ? null : new IProject[]{file.getProject()};
-
- // Only save the target script's project if a project is found.
- if (scriptProject != null) {
- return super.preLaunchCheck(configuration, mode, monitor);
- }
- return true;
- }
-
- @Override
- public void launch(ILaunchConfiguration configuration, String mode,
- ILaunch launch, IProgressMonitor monitor) throws CoreException {
-
- // Wait for other stap launches' consoles to be initiated before starting a new launch.
- ILaunchManager manager = DebugPlugin.getDefault().getLaunchManager();
- for (ILaunch olaunch : manager.getLaunches()) {
- if (olaunch.equals(launch)) {
- continue;
- }
- if (olaunch instanceof SystemTapScriptLaunch && ((SystemTapScriptLaunch) olaunch).getConsole() == null) {
- throw new CoreException(new Status(IStatus.ERROR, IDEPlugin.PLUGIN_ID,
- Messages.SystemTapScriptLaunchError_waitForConsoles));
- }
- }
-
- if (!SystemTapScriptGraphOptionsTab.isValidLaunch(configuration)) {
- throw new CoreException(new Status(IStatus.ERROR, IDEPlugin.PLUGIN_ID, Messages.SystemTapScriptLaunchError_graph));
- }
-
- RunScriptHandler action;
-
- boolean runWithChart = configuration.getAttribute(SystemTapScriptGraphOptionsTab.RUN_WITH_CHART, false);
- // If runWithChart is true there must be at least one graph, but this isn't guaranteed
- // to be true for outdated Launch Configurations. So for safety, make sure there are graphs.
- int numGraphs = configuration.getAttribute(SystemTapScriptGraphOptionsTab.NUMBER_OF_REGEXS, 0);
- if (runWithChart && numGraphs > 0){
- List<IDataSetParser> parsers = SystemTapScriptGraphOptionsTab.createDatasetParsers(configuration);
- List<IFilteredDataSet> dataSets = SystemTapScriptGraphOptionsTab.createDataset(configuration);
- List<String> names = SystemTapScriptGraphOptionsTab.createDatasetNames(configuration);
- List<LinkedList<GraphData>> graphs = SystemTapScriptGraphOptionsTab.createGraphsFromConfiguration(configuration);
- action = new RunScriptChartHandler(parsers, dataSets, names, graphs);
- }else{
- action = new RunScriptHandler();
- }
-
- // Path
- IPath scriptPath = new Path(configuration.getAttribute(SystemTapScriptLaunchConfigurationTab.SCRIPT_PATH_ATTR, "")); //$NON-NLS-1$
- if (!scriptPath.toFile().exists()) {
- throw new CoreException(new Status(IStatus.ERROR, IDEPlugin.PLUGIN_ID,
- MessageFormat.format(Messages.SystemTapScriptLaunchError_fileNotFound, scriptPath.toString())));
- }
- String extension = scriptPath.getFileExtension();
- if (extension == null || !extension.equals("stp")) { //$NON-NLS-1$
- throw new CoreException(new Status(IStatus.ERROR, IDEPlugin.PLUGIN_ID,
- MessageFormat.format(Messages.SystemTapScriptLaunchError_fileNotStp, scriptPath.toString())));
- }
- action.setPath(scriptPath);
-
- // Run locally and/or as current user.
- boolean runAsCurrentUser = configuration.getAttribute(SystemTapScriptLaunchConfigurationTab.CURRENT_USER_ATTR, true);
- boolean runLocal = configuration.getAttribute(SystemTapScriptLaunchConfigurationTab.LOCAL_HOST_ATTR, true);
-
- action.setRemoteScriptOptions(runLocal && runAsCurrentUser ? null : new RemoteScriptOptions(
- configuration.getAttribute(SystemTapScriptLaunchConfigurationTab.USER_NAME_ATTR, ""), //$NON-NLS-1$
- configuration.getAttribute(SystemTapScriptLaunchConfigurationTab.USER_PASS_ATTR, ""), //$NON-NLS-1$
- configuration.getAttribute(SystemTapScriptLaunchConfigurationTab.HOST_NAME_ATTR, "localhost"))); //$NON-NLS-1$
-
- String value = configuration.getAttribute(IDEPreferenceConstants.STAP_CMD_OPTION[IDEPreferenceConstants.KEY], ""); //$NON-NLS-1$
- if (!value.isEmpty()){
- action.addComandLineOptions(IDEPreferenceConstants.STAP_CMD_OPTION[IDEPreferenceConstants.FLAG] + " " + value); //$NON-NLS-1$
- }
-
- // Add command line options
- for(int i=0; i<IDEPreferenceConstants.STAP_BOOLEAN_OPTIONS.length; i++) {
- boolean flag = configuration.getAttribute(
- IDEPreferenceConstants.STAP_BOOLEAN_OPTIONS[i][IDEPreferenceConstants.KEY],
- false);
- if (flag){
- action.addComandLineOptions(IDEPreferenceConstants.STAP_BOOLEAN_OPTIONS[i][IDEPreferenceConstants.FLAG]);
- }
- }
-
- for(int i=0; i<IDEPreferenceConstants.STAP_STRING_OPTIONS.length; i++) {
- value = configuration.getAttribute(IDEPreferenceConstants.STAP_STRING_OPTIONS[i][IDEPreferenceConstants.KEY],""); //$NON-NLS-1$
- if (!value.isEmpty()){
- action.addComandLineOptions(IDEPreferenceConstants.STAP_STRING_OPTIONS[i][IDEPreferenceConstants.FLAG] + " " + value); //$NON-NLS-1$
- }
- }
-
- value = configuration.getAttribute(SystemTapScriptOptionsTab.MISC_COMMANDLINE_OPTIONS,""); //$NON-NLS-1$
- if (!value.isEmpty()){
- action.addComandLineOptions(value);
- }
-
- action.setLaunch((SystemTapScriptLaunch) launch);
- try {
- action.execute(null);
- } catch (ExecutionException e) {
- throw new CoreException(new Status(IStatus.ERROR, IDEPlugin.PLUGIN_ID, e.getMessage()));
- }
- }
+ LaunchConfigurationDelegate {
+
+ static final String CONFIGURATION_TYPE = "org.eclipse.linuxtools.systemtap.ui.ide.SystemTapLaunchConfigurationType"; //$NON-NLS-1$
+
+ private IProject[] scriptProject;
+
+ /**
+ * Keep a reference to the target running script's parent project, so only that project
+ * will be saved when the script is run.
+ */
+ @Override
+ protected IProject[] getBuildOrder(ILaunchConfiguration configuration, String mode) {
+ return scriptProject;
+ }
+
+ @Override
+ public ILaunch getLaunch(ILaunchConfiguration configuration, String mode) {
+ return new SystemTapScriptLaunch(configuration, mode);
+ }
+
+ @Override
+ public boolean preLaunchCheck(ILaunchConfiguration configuration, String mode, IProgressMonitor monitor) throws CoreException {
+ // Force the configuration to use the proper Process Factory.
+ if (!configuration.getAttribute(DebugPlugin.ATTR_PROCESS_FACTORY_ID, "").equals(SystemTapRuntimeProcessFactory.PROCESS_FACTORY_ID)) { //$NON-NLS-1$
+ ILaunchConfigurationWorkingCopy wc = configuration.getWorkingCopy();
+ wc.setAttribute(DebugPlugin.ATTR_PROCESS_FACTORY_ID, SystemTapRuntimeProcessFactory.PROCESS_FACTORY_ID);
+ wc.doSave();
+ }
+ // Find the parent project of the target script.
+ IPath path = Path.fromOSString(configuration.getAttribute(SystemTapScriptLaunchConfigurationTab.SCRIPT_PATH_ATTR, (String)null));
+ IFile file = ResourcesPlugin.getWorkspace().getRoot().getFileForLocation(path);
+ scriptProject = file == null ? null : new IProject[]{file.getProject()};
+
+ // Only save the target script's project if a project is found.
+ if (scriptProject != null) {
+ return super.preLaunchCheck(configuration, mode, monitor);
+ }
+ return true;
+ }
+
+ @Override
+ public void launch(ILaunchConfiguration configuration, String mode,
+ ILaunch launch, IProgressMonitor monitor) throws CoreException {
+
+ // Wait for other stap launches' consoles to be initiated before starting a new launch.
+ ILaunchManager manager = DebugPlugin.getDefault().getLaunchManager();
+ for (ILaunch olaunch : manager.getLaunches()) {
+ if (olaunch.equals(launch)) {
+ continue;
+ }
+ if (olaunch instanceof SystemTapScriptLaunch && ((SystemTapScriptLaunch) olaunch).getConsole() == null) {
+ throw new CoreException(new Status(IStatus.ERROR, IDEPlugin.PLUGIN_ID,
+ Messages.SystemTapScriptLaunchError_waitForConsoles));
+ }
+ }
+
+ if (!SystemTapScriptGraphOptionsTab.isValidLaunch(configuration)) {
+ throw new CoreException(new Status(IStatus.ERROR, IDEPlugin.PLUGIN_ID, Messages.SystemTapScriptLaunchError_graph));
+ }
+
+ RunScriptHandler action;
+
+ boolean runWithChart = configuration.getAttribute(SystemTapScriptGraphOptionsTab.RUN_WITH_CHART, false);
+ // If runWithChart is true there must be at least one graph, but this isn't guaranteed
+ // to be true for outdated Launch Configurations. So for safety, make sure there are graphs.
+ int numGraphs = configuration.getAttribute(SystemTapScriptGraphOptionsTab.NUMBER_OF_REGEXS, 0);
+ if (runWithChart && numGraphs > 0){
+ List<IDataSetParser> parsers = SystemTapScriptGraphOptionsTab.createDatasetParsers(configuration);
+ List<IFilteredDataSet> dataSets = SystemTapScriptGraphOptionsTab.createDataset(configuration);
+ List<String> names = SystemTapScriptGraphOptionsTab.createDatasetNames(configuration);
+ List<LinkedList<GraphData>> graphs = SystemTapScriptGraphOptionsTab.createGraphsFromConfiguration(configuration);
+ action = new RunScriptChartHandler(parsers, dataSets, names, graphs);
+ }else{
+ action = new RunScriptHandler();
+ }
+
+ // Path
+ IPath scriptPath = new Path(configuration.getAttribute(SystemTapScriptLaunchConfigurationTab.SCRIPT_PATH_ATTR, "")); //$NON-NLS-1$
+ if (!scriptPath.toFile().exists()) {
+ throw new CoreException(new Status(IStatus.ERROR, IDEPlugin.PLUGIN_ID,
+ MessageFormat.format(Messages.SystemTapScriptLaunchError_fileNotFound, scriptPath.toString())));
+ }
+ String extension = scriptPath.getFileExtension();
+ if (extension == null || !extension.equals("stp")) { //$NON-NLS-1$
+ throw new CoreException(new Status(IStatus.ERROR, IDEPlugin.PLUGIN_ID,
+ MessageFormat.format(Messages.SystemTapScriptLaunchError_fileNotStp, scriptPath.toString())));
+ }
+ action.setPath(scriptPath);
+
+ // Run locally and/or as current user.
+ boolean runAsCurrentUser = configuration.getAttribute(SystemTapScriptLaunchConfigurationTab.CURRENT_USER_ATTR, true);
+ boolean runLocal = configuration.getAttribute(SystemTapScriptLaunchConfigurationTab.LOCAL_HOST_ATTR, true);
+
+ action.setRemoteScriptOptions(runLocal && runAsCurrentUser ? null : new RemoteScriptOptions(
+ configuration.getAttribute(SystemTapScriptLaunchConfigurationTab.USER_NAME_ATTR, ""), //$NON-NLS-1$
+ configuration.getAttribute(SystemTapScriptLaunchConfigurationTab.USER_PASS_ATTR, ""), //$NON-NLS-1$
+ configuration.getAttribute(SystemTapScriptLaunchConfigurationTab.HOST_NAME_ATTR, "localhost"))); //$NON-NLS-1$
+
+ String value = configuration.getAttribute(IDEPreferenceConstants.STAP_CMD_OPTION[IDEPreferenceConstants.KEY], ""); //$NON-NLS-1$
+ if (!value.isEmpty()){
+ action.addComandLineOptions(IDEPreferenceConstants.STAP_CMD_OPTION[IDEPreferenceConstants.FLAG] + " " + value); //$NON-NLS-1$
+ }
+
+ // Add command line options
+ for(int i=0; i<IDEPreferenceConstants.STAP_BOOLEAN_OPTIONS.length; i++) {
+ boolean flag = configuration.getAttribute(
+ IDEPreferenceConstants.STAP_BOOLEAN_OPTIONS[i][IDEPreferenceConstants.KEY],
+ false);
+ if (flag){
+ action.addComandLineOptions(IDEPreferenceConstants.STAP_BOOLEAN_OPTIONS[i][IDEPreferenceConstants.FLAG]);
+ }
+ }
+
+ for(int i=0; i<IDEPreferenceConstants.STAP_STRING_OPTIONS.length; i++) {
+ value = configuration.getAttribute(IDEPreferenceConstants.STAP_STRING_OPTIONS[i][IDEPreferenceConstants.KEY],""); //$NON-NLS-1$
+ if (!value.isEmpty()){
+ action.addComandLineOptions(IDEPreferenceConstants.STAP_STRING_OPTIONS[i][IDEPreferenceConstants.FLAG] + " " + value); //$NON-NLS-1$
+ }
+ }
+
+ value = configuration.getAttribute(SystemTapScriptOptionsTab.MISC_COMMANDLINE_OPTIONS,""); //$NON-NLS-1$
+ if (!value.isEmpty()){
+ action.addComandLineOptions(value);
+ }
+
+ action.setLaunch((SystemTapScriptLaunch) launch);
+ try {
+ action.execute(null);
+ } catch (ExecutionException e) {
+ throw new CoreException(new Status(IStatus.ERROR, IDEPlugin.PLUGIN_ID, e.getMessage()));
+ }
+ }
}
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 0c4d63ee8f..5640440fdb 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
@@ -48,300 +48,300 @@ import org.eclipse.ui.ide.ResourceUtil;
import org.eclipse.ui.plugin.AbstractUIPlugin;
public class SystemTapScriptLaunchConfigurationTab extends
- AbstractLaunchConfigurationTab {
-
- static final String SCRIPT_PATH_ATTR = "ScriptPath"; //$NON-NLS-1$
- static final String CURRENT_USER_ATTR = "executeAsCurrentUser"; //$NON-NLS-1$
- static final String USER_NAME_ATTR = "userName"; //$NON-NLS-1$
- static final String USER_PASS_ATTR = "userPassword"; //$NON-NLS-1$
- static final String LOCAL_HOST_ATTR = "executeOnLocalHost"; //$NON-NLS-1$
- static final String HOST_NAME_ATTR = "hostName"; //$NON-NLS-1$
-
- private Text scriptPathText;
- private Button currentUserCheckButton;
- private Text userNameText;
- private Text userPasswordText;
- private Button localHostCheckButton;
- private Text hostNameText;
- private Label userNameLabel;
- private Label userPasswordLabel;
- private Label hostNamelabel;
- private FileDialog fileDialog;
-
- /**
- * @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.
- */
- IPath getScriptPath() {
- IPath scriptPath = new Path(scriptPathText.getText());
- return scriptPath.toFile().exists() ? scriptPath : null;
- }
-
- @Override
- public void createControl(Composite parent) {
-
- this.fileDialog = new FileDialog(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(), SWT.OPEN);
+ AbstractLaunchConfigurationTab {
+
+ static final String SCRIPT_PATH_ATTR = "ScriptPath"; //$NON-NLS-1$
+ static final String CURRENT_USER_ATTR = "executeAsCurrentUser"; //$NON-NLS-1$
+ static final String USER_NAME_ATTR = "userName"; //$NON-NLS-1$
+ static final String USER_PASS_ATTR = "userPassword"; //$NON-NLS-1$
+ static final String LOCAL_HOST_ATTR = "executeOnLocalHost"; //$NON-NLS-1$
+ static final String HOST_NAME_ATTR = "hostName"; //$NON-NLS-1$
+
+ private Text scriptPathText;
+ private Button currentUserCheckButton;
+ private Text userNameText;
+ private Text userPasswordText;
+ private Button localHostCheckButton;
+ private Text hostNameText;
+ private Label userNameLabel;
+ private Label userPasswordLabel;
+ private Label hostNamelabel;
+ private FileDialog fileDialog;
+
+ /**
+ * @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.
+ */
+ IPath getScriptPath() {
+ IPath scriptPath = new Path(scriptPathText.getText());
+ return scriptPath.toFile().exists() ? scriptPath : null;
+ }
+
+ @Override
+ public void createControl(Composite parent) {
+
+ this.fileDialog = new FileDialog(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(), SWT.OPEN);
fileDialog.setText(Messages.SystemTapScriptLaunchConfigurationTab_selectScript);
fileDialog.setFilterPath(Platform.getLocation().toOSString());
- GridLayout layout = new GridLayout();
- Composite top = new Composite(parent, SWT.NONE);
- setControl(top);
- top.setLayout(layout);
- top.setLayoutData( new GridData(SWT.FILL, SWT.FILL, true, true));
-
- // Script path
- Group scriptSettingsGroup = new Group(top, SWT.SHADOW_ETCHED_IN);
- scriptSettingsGroup.setText(Messages.SystemTapScriptLaunchConfigurationTab_script);
- scriptSettingsGroup.setLayoutData( new GridData(SWT.FILL, SWT.FILL, true, false));
- layout = new GridLayout();
- layout.numColumns = 2;
- scriptSettingsGroup.setLayout(layout);
- this.scriptPathText = new Text(scriptSettingsGroup, SWT.SINGLE | SWT.BORDER);
- scriptPathText.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
- scriptPathText.addModifyListener(new ModifyListener() {
- @Override
- public void modifyText(ModifyEvent e) {
- updateLaunchConfigurationDialog();
- }
- });
- Button selectScriptButon = new Button(scriptSettingsGroup, 0);
- GridData gridData = new GridData();
- gridData.widthHint = 110;
- selectScriptButon.setLayoutData(gridData);
- selectScriptButon.setText(Messages.SystemTapScriptLaunchConfigurationTab_browse);
- selectScriptButon.addSelectionListener(new SelectionListener() {
-
- @Override
- public void widgetSelected(SelectionEvent e) {
- String path = fileDialog.open();
- if (path != null){
- scriptPathText.setText(path);
- }
- }
-
- @Override
- public void widgetDefaultSelected(SelectionEvent e) {
- }
- });
-
- // User Settings
- Group userSettingsGroup = new Group(top, SWT.SHADOW_ETCHED_IN);
- layout = new GridLayout();
- userSettingsGroup.setLayout(layout);
- layout.numColumns = 2;
- userSettingsGroup.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
-
- this.currentUserCheckButton = new Button(userSettingsGroup, SWT.CHECK);
- currentUserCheckButton.setText(Messages.SystemTapScriptLaunchConfigurationTab_currentUser);
- currentUserCheckButton.setSelection(true);
- gridData = new GridData();
- gridData.horizontalSpan = 2;
- currentUserCheckButton.setLayoutData(gridData);
-
- this.userNameLabel = new Label(userSettingsGroup, SWT.NONE);
- userNameLabel.setText(Messages.SystemTapScriptLaunchConfigurationTab_username);
- this.userNameText = new Text(userSettingsGroup, SWT.SINGLE | SWT.BORDER);
- userNameText.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
-
- this.userPasswordLabel = new Label(userSettingsGroup, SWT.NONE);
- userPasswordLabel.setText(Messages.SystemTapScriptLaunchConfigurationTab_password);
- this.userPasswordText = new Text(userSettingsGroup, SWT.SINGLE | SWT.BORDER | SWT.PASSWORD);
- userPasswordText.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
-
- userSettingsGroup.setLayoutData( new GridData(SWT.FILL, SWT.FILL, true, false));
- userSettingsGroup.setText(Messages.SystemTapScriptLaunchConfigurationTab_user);
-
- currentUserCheckButton.addSelectionListener(new SelectionListener() {
- @Override
- public void widgetSelected(SelectionEvent e) {
- update();
- }
-
- @Override
- public void widgetDefaultSelected(SelectionEvent e) {
- update();
- }
-
- private void update(){
- boolean enable = !currentUserCheckButton.getSelection();
- setUserGroupEnablement(enable);
- updateLaunchConfigurationDialog();
- }
- });
-
- userNameText.addModifyListener(new ModifyListener() {
- @Override
- public void modifyText(ModifyEvent e) {
- updateLaunchConfigurationDialog();
- }
- });
-
- userPasswordText.addModifyListener(new ModifyListener() {
- @Override
- public void modifyText(ModifyEvent e) {
- updateLaunchConfigurationDialog();
- }
- });
-
- setUserGroupEnablement(false);
-
- // Host settings
- Group hostSettingsGroup = new Group(top, SWT.SHADOW_ETCHED_IN);
- hostSettingsGroup.setLayoutData( new GridData(SWT.FILL, SWT.FILL, true, false));
- hostSettingsGroup.setText(Messages.SystemTapScriptLaunchConfigurationTab_host);
- layout = new GridLayout();
- hostSettingsGroup.setLayout(layout);
- layout.numColumns = 2;
-
- this.localHostCheckButton = new Button(hostSettingsGroup, SWT.CHECK);
- localHostCheckButton.setText(Messages.SystemTapScriptLaunchConfigurationTab_runLocally);
- gridData = new GridData();
- gridData.horizontalSpan = 2;
-
- this.hostNamelabel = new Label(hostSettingsGroup, SWT.NONE);
- hostNamelabel.setText(Messages.SystemTapScriptLaunchConfigurationTab_hostname);
- this.hostNameText = new Text(hostSettingsGroup, SWT.SINGLE | SWT.BORDER);
- hostNameText.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
- localHostCheckButton.setLayoutData(gridData);
- localHostCheckButton.addSelectionListener(new SelectionListener() {
- @Override
- public void widgetSelected(SelectionEvent e) {
- update();
- }
-
- @Override
- public void widgetDefaultSelected(SelectionEvent e) {
- update();
- }
-
- private void update(){
- updateLaunchConfigurationDialog();
- }
- });
- hostNameText.addModifyListener(new ModifyListener() {
- @Override
- public void modifyText(ModifyEvent e) {
- updateLaunchConfigurationDialog();
- }
- });
- }
-
- private void setUserGroupEnablement(boolean enable){
- userNameText.setEnabled(enable);
- userNameLabel.setEnabled(enable);
- userPasswordText.setEnabled(enable);
- userPasswordLabel.setEnabled(enable);
- }
-
- private void setHostGroupEnablement(boolean enable){
- hostNamelabel.setEnabled(enable);
- hostNameText.setEnabled(enable);
- }
-
- @Override
- public void setDefaults(ILaunchConfigurationWorkingCopy configuration) {
- configuration.setAttribute(SCRIPT_PATH_ATTR, this.getSelectedScriptPath());
- configuration.setAttribute(CURRENT_USER_ATTR, true);
- configuration.setAttribute(USER_NAME_ATTR, ""); //$NON-NLS-1$
- configuration.setAttribute(USER_PASS_ATTR, ""); //$NON-NLS-1$
- configuration.setAttribute(LOCAL_HOST_ATTR, true);
- configuration.setAttribute(HOST_NAME_ATTR, ""); //$NON-NLS-1$
- }
-
- @Override
- public void initializeFrom(ILaunchConfiguration configuration) {
- try {
- this.scriptPathText.setText(configuration.getAttribute(SCRIPT_PATH_ATTR, "")); //$NON-NLS-1$
- this.currentUserCheckButton.setSelection(configuration.getAttribute(CURRENT_USER_ATTR, true));
- this.userNameText.setText(configuration.getAttribute(USER_NAME_ATTR, "")); //$NON-NLS-1$
- this.userPasswordText.setText(configuration.getAttribute(USER_PASS_ATTR, "")); //$NON-NLS-1$
- this.localHostCheckButton.setSelection(configuration.getAttribute(LOCAL_HOST_ATTR, true));
- this.hostNameText.setText(configuration.getAttribute(HOST_NAME_ATTR, "")); //$NON-NLS-1$
- } catch (CoreException e) {
- ExceptionErrorDialog.openError(Messages.SystemTapScriptLaunchConfigurationTab_errorInitializingTab, e);
- }
- }
-
- @Override
- public void performApply(ILaunchConfigurationWorkingCopy configuration) {
- configuration.setAttribute(SCRIPT_PATH_ATTR, this.scriptPathText.getText());
- configuration.setAttribute(CURRENT_USER_ATTR, this.currentUserCheckButton.getSelection());
- configuration.setAttribute(USER_NAME_ATTR, this.userNameText.getText());
- configuration.setAttribute(USER_PASS_ATTR, this.userPasswordText.getText());
- configuration.setAttribute(LOCAL_HOST_ATTR, this.localHostCheckButton.getSelection());
- configuration.setAttribute(HOST_NAME_ATTR, this.hostNameText.getText());
-
- boolean enable = !currentUserCheckButton.getSelection();
- setUserGroupEnablement(enable);
-
- enable = !localHostCheckButton.getSelection();
- setHostGroupEnablement(enable);
- }
-
- @Override
- public boolean isValid(ILaunchConfiguration launchConfig) {
- setErrorMessage(null);
-
- IPath scriptPath = getScriptPath();
- if (scriptPath == null) {
- setErrorMessage(MessageFormat.format(Messages.SystemTapScriptLaunchConfigurationTab_fileNotFound, scriptPathText.getText()));
- return false;
- }
- String extension = scriptPath.getFileExtension();
- if (extension == null || !extension.equals("stp")) { //$NON-NLS-1$
- setErrorMessage(Messages.SystemTapScriptLaunchConfigurationTab_fileNotStp);
- return false;
- }
-
- return true;
- }
-
- @Override
- public String getName() {
- return Messages.SystemTapScriptLaunchConfigurationTab_general;
- }
-
- private String getSelectedScriptPath(){
- IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
-
- String pathString = ""; //$NON-NLS-1$
-
- if (window != null)
- {
- ISelection selection = window.getSelectionService().getSelection();
-
- // Figure out the selected systemtap script
- if (selection instanceof TreeSelection){
- Object selectedElement = ((TreeSelection)selection).getFirstElement();
- if (selectedElement instanceof IFile)
- {
- IPath path = ((IFile)selectedElement).getLocation();
- pathString = path.toOSString();
- }
- }
-
- // If it is a text selection use the path from the active editor.
- if (selection instanceof TextSelection){
- IEditorPart ed = window.getActivePage().getActiveEditor();
- if(ed.getEditorInput() instanceof PathEditorInput) {
- pathString = ((PathEditorInput)ed.getEditorInput()).getPath().toString();
- } else {
- pathString = ResourceUtil.getFile(ed.getEditorInput()).getLocation().toString();
- }
- }
- }
-
- if (pathString.endsWith(".stp")) { //$NON-NLS-1$
- return pathString;
- }
-
- return ""; //$NON-NLS-1$
- }
-
- @Override
- public Image getImage() {
- return AbstractUIPlugin.imageDescriptorFromPlugin(IDEPlugin.PLUGIN_ID,
- "icons/main_tab.gif").createImage(); //$NON-NLS-1$
- }
+ GridLayout layout = new GridLayout();
+ Composite top = new Composite(parent, SWT.NONE);
+ setControl(top);
+ top.setLayout(layout);
+ top.setLayoutData( new GridData(SWT.FILL, SWT.FILL, true, true));
+
+ // Script path
+ Group scriptSettingsGroup = new Group(top, SWT.SHADOW_ETCHED_IN);
+ scriptSettingsGroup.setText(Messages.SystemTapScriptLaunchConfigurationTab_script);
+ scriptSettingsGroup.setLayoutData( new GridData(SWT.FILL, SWT.FILL, true, false));
+ layout = new GridLayout();
+ layout.numColumns = 2;
+ scriptSettingsGroup.setLayout(layout);
+ this.scriptPathText = new Text(scriptSettingsGroup, SWT.SINGLE | SWT.BORDER);
+ scriptPathText.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
+ scriptPathText.addModifyListener(new ModifyListener() {
+ @Override
+ public void modifyText(ModifyEvent e) {
+ updateLaunchConfigurationDialog();
+ }
+ });
+ Button selectScriptButon = new Button(scriptSettingsGroup, 0);
+ GridData gridData = new GridData();
+ gridData.widthHint = 110;
+ selectScriptButon.setLayoutData(gridData);
+ selectScriptButon.setText(Messages.SystemTapScriptLaunchConfigurationTab_browse);
+ selectScriptButon.addSelectionListener(new SelectionListener() {
+
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ String path = fileDialog.open();
+ if (path != null){
+ scriptPathText.setText(path);
+ }
+ }
+
+ @Override
+ public void widgetDefaultSelected(SelectionEvent e) {
+ }
+ });
+
+ // User Settings
+ Group userSettingsGroup = new Group(top, SWT.SHADOW_ETCHED_IN);
+ layout = new GridLayout();
+ userSettingsGroup.setLayout(layout);
+ layout.numColumns = 2;
+ userSettingsGroup.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
+
+ this.currentUserCheckButton = new Button(userSettingsGroup, SWT.CHECK);
+ currentUserCheckButton.setText(Messages.SystemTapScriptLaunchConfigurationTab_currentUser);
+ currentUserCheckButton.setSelection(true);
+ gridData = new GridData();
+ gridData.horizontalSpan = 2;
+ currentUserCheckButton.setLayoutData(gridData);
+
+ this.userNameLabel = new Label(userSettingsGroup, SWT.NONE);
+ userNameLabel.setText(Messages.SystemTapScriptLaunchConfigurationTab_username);
+ this.userNameText = new Text(userSettingsGroup, SWT.SINGLE | SWT.BORDER);
+ userNameText.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
+
+ this.userPasswordLabel = new Label(userSettingsGroup, SWT.NONE);
+ userPasswordLabel.setText(Messages.SystemTapScriptLaunchConfigurationTab_password);
+ this.userPasswordText = new Text(userSettingsGroup, SWT.SINGLE | SWT.BORDER | SWT.PASSWORD);
+ userPasswordText.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
+
+ userSettingsGroup.setLayoutData( new GridData(SWT.FILL, SWT.FILL, true, false));
+ userSettingsGroup.setText(Messages.SystemTapScriptLaunchConfigurationTab_user);
+
+ currentUserCheckButton.addSelectionListener(new SelectionListener() {
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ update();
+ }
+
+ @Override
+ public void widgetDefaultSelected(SelectionEvent e) {
+ update();
+ }
+
+ private void update(){
+ boolean enable = !currentUserCheckButton.getSelection();
+ setUserGroupEnablement(enable);
+ updateLaunchConfigurationDialog();
+ }
+ });
+
+ userNameText.addModifyListener(new ModifyListener() {
+ @Override
+ public void modifyText(ModifyEvent e) {
+ updateLaunchConfigurationDialog();
+ }
+ });
+
+ userPasswordText.addModifyListener(new ModifyListener() {
+ @Override
+ public void modifyText(ModifyEvent e) {
+ updateLaunchConfigurationDialog();
+ }
+ });
+
+ setUserGroupEnablement(false);
+
+ // Host settings
+ Group hostSettingsGroup = new Group(top, SWT.SHADOW_ETCHED_IN);
+ hostSettingsGroup.setLayoutData( new GridData(SWT.FILL, SWT.FILL, true, false));
+ hostSettingsGroup.setText(Messages.SystemTapScriptLaunchConfigurationTab_host);
+ layout = new GridLayout();
+ hostSettingsGroup.setLayout(layout);
+ layout.numColumns = 2;
+
+ this.localHostCheckButton = new Button(hostSettingsGroup, SWT.CHECK);
+ localHostCheckButton.setText(Messages.SystemTapScriptLaunchConfigurationTab_runLocally);
+ gridData = new GridData();
+ gridData.horizontalSpan = 2;
+
+ this.hostNamelabel = new Label(hostSettingsGroup, SWT.NONE);
+ hostNamelabel.setText(Messages.SystemTapScriptLaunchConfigurationTab_hostname);
+ this.hostNameText = new Text(hostSettingsGroup, SWT.SINGLE | SWT.BORDER);
+ hostNameText.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
+ localHostCheckButton.setLayoutData(gridData);
+ localHostCheckButton.addSelectionListener(new SelectionListener() {
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ update();
+ }
+
+ @Override
+ public void widgetDefaultSelected(SelectionEvent e) {
+ update();
+ }
+
+ private void update(){
+ updateLaunchConfigurationDialog();
+ }
+ });
+ hostNameText.addModifyListener(new ModifyListener() {
+ @Override
+ public void modifyText(ModifyEvent e) {
+ updateLaunchConfigurationDialog();
+ }
+ });
+ }
+
+ private void setUserGroupEnablement(boolean enable){
+ userNameText.setEnabled(enable);
+ userNameLabel.setEnabled(enable);
+ userPasswordText.setEnabled(enable);
+ userPasswordLabel.setEnabled(enable);
+ }
+
+ private void setHostGroupEnablement(boolean enable){
+ hostNamelabel.setEnabled(enable);
+ hostNameText.setEnabled(enable);
+ }
+
+ @Override
+ public void setDefaults(ILaunchConfigurationWorkingCopy configuration) {
+ configuration.setAttribute(SCRIPT_PATH_ATTR, this.getSelectedScriptPath());
+ configuration.setAttribute(CURRENT_USER_ATTR, true);
+ configuration.setAttribute(USER_NAME_ATTR, ""); //$NON-NLS-1$
+ configuration.setAttribute(USER_PASS_ATTR, ""); //$NON-NLS-1$
+ configuration.setAttribute(LOCAL_HOST_ATTR, true);
+ configuration.setAttribute(HOST_NAME_ATTR, ""); //$NON-NLS-1$
+ }
+
+ @Override
+ public void initializeFrom(ILaunchConfiguration configuration) {
+ try {
+ this.scriptPathText.setText(configuration.getAttribute(SCRIPT_PATH_ATTR, "")); //$NON-NLS-1$
+ this.currentUserCheckButton.setSelection(configuration.getAttribute(CURRENT_USER_ATTR, true));
+ this.userNameText.setText(configuration.getAttribute(USER_NAME_ATTR, "")); //$NON-NLS-1$
+ this.userPasswordText.setText(configuration.getAttribute(USER_PASS_ATTR, "")); //$NON-NLS-1$
+ this.localHostCheckButton.setSelection(configuration.getAttribute(LOCAL_HOST_ATTR, true));
+ this.hostNameText.setText(configuration.getAttribute(HOST_NAME_ATTR, "")); //$NON-NLS-1$
+ } catch (CoreException e) {
+ ExceptionErrorDialog.openError(Messages.SystemTapScriptLaunchConfigurationTab_errorInitializingTab, e);
+ }
+ }
+
+ @Override
+ public void performApply(ILaunchConfigurationWorkingCopy configuration) {
+ configuration.setAttribute(SCRIPT_PATH_ATTR, this.scriptPathText.getText());
+ configuration.setAttribute(CURRENT_USER_ATTR, this.currentUserCheckButton.getSelection());
+ configuration.setAttribute(USER_NAME_ATTR, this.userNameText.getText());
+ configuration.setAttribute(USER_PASS_ATTR, this.userPasswordText.getText());
+ configuration.setAttribute(LOCAL_HOST_ATTR, this.localHostCheckButton.getSelection());
+ configuration.setAttribute(HOST_NAME_ATTR, this.hostNameText.getText());
+
+ boolean enable = !currentUserCheckButton.getSelection();
+ setUserGroupEnablement(enable);
+
+ enable = !localHostCheckButton.getSelection();
+ setHostGroupEnablement(enable);
+ }
+
+ @Override
+ public boolean isValid(ILaunchConfiguration launchConfig) {
+ setErrorMessage(null);
+
+ IPath scriptPath = getScriptPath();
+ if (scriptPath == null) {
+ setErrorMessage(MessageFormat.format(Messages.SystemTapScriptLaunchConfigurationTab_fileNotFound, scriptPathText.getText()));
+ return false;
+ }
+ String extension = scriptPath.getFileExtension();
+ if (extension == null || !extension.equals("stp")) { //$NON-NLS-1$
+ setErrorMessage(Messages.SystemTapScriptLaunchConfigurationTab_fileNotStp);
+ return false;
+ }
+
+ return true;
+ }
+
+ @Override
+ public String getName() {
+ return Messages.SystemTapScriptLaunchConfigurationTab_general;
+ }
+
+ private String getSelectedScriptPath(){
+ IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
+
+ String pathString = ""; //$NON-NLS-1$
+
+ if (window != null)
+ {
+ ISelection selection = window.getSelectionService().getSelection();
+
+ // Figure out the selected systemtap script
+ if (selection instanceof TreeSelection){
+ Object selectedElement = ((TreeSelection)selection).getFirstElement();
+ if (selectedElement instanceof IFile)
+ {
+ IPath path = ((IFile)selectedElement).getLocation();
+ pathString = path.toOSString();
+ }
+ }
+
+ // If it is a text selection use the path from the active editor.
+ if (selection instanceof TextSelection){
+ IEditorPart ed = window.getActivePage().getActiveEditor();
+ if(ed.getEditorInput() instanceof PathEditorInput) {
+ pathString = ((PathEditorInput)ed.getEditorInput()).getPath().toString();
+ } else {
+ pathString = ResourceUtil.getFile(ed.getEditorInput()).getLocation().toString();
+ }
+ }
+ }
+
+ if (pathString.endsWith(".stp")) { //$NON-NLS-1$
+ return pathString;
+ }
+
+ return ""; //$NON-NLS-1$
+ }
+
+ @Override
+ public Image getImage() {
+ return AbstractUIPlugin.imageDescriptorFromPlugin(IDEPlugin.PLUGIN_ID,
+ "icons/main_tab.gif").createImage(); //$NON-NLS-1$
+ }
}
diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/launcher/SystemTapScriptLaunchConfigurationTabGroup.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/launcher/SystemTapScriptLaunchConfigurationTabGroup.java
index 761f4bdece..475f6323ea 100644
--- a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/launcher/SystemTapScriptLaunchConfigurationTabGroup.java
+++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/launcher/SystemTapScriptLaunchConfigurationTabGroup.java
@@ -17,19 +17,19 @@ import org.eclipse.debug.ui.CommonTab;
import org.eclipse.debug.ui.ILaunchConfigurationDialog;
public class SystemTapScriptLaunchConfigurationTabGroup extends
- AbstractLaunchConfigurationTabGroup {
+ AbstractLaunchConfigurationTabGroup {
- public SystemTapScriptLaunchConfigurationTabGroup() {
- }
+ public SystemTapScriptLaunchConfigurationTabGroup() {
+ }
- @Override
- public void createTabs(ILaunchConfigurationDialog dialog, String mode) {
- AbstractLaunchConfigurationTab[] tabs = new AbstractLaunchConfigurationTab[] {
- new SystemTapScriptLaunchConfigurationTab(),
- new SystemTapScriptOptionsTab(),
- new SystemTapScriptGraphOptionsTab(),
- new CommonTab() };
- setTabs(tabs);
- }
+ @Override
+ public void createTabs(ILaunchConfigurationDialog dialog, String mode) {
+ AbstractLaunchConfigurationTab[] tabs = new AbstractLaunchConfigurationTab[] {
+ new SystemTapScriptLaunchConfigurationTab(),
+ new SystemTapScriptOptionsTab(),
+ new SystemTapScriptGraphOptionsTab(),
+ new CommonTab() };
+ setTabs(tabs);
+ }
}
diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/launcher/SystemTapScriptLaunchShortcut.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/launcher/SystemTapScriptLaunchShortcut.java
index 3ed71d458a..3446d71c06 100644
--- a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/launcher/SystemTapScriptLaunchShortcut.java
+++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/launcher/SystemTapScriptLaunchShortcut.java
@@ -34,117 +34,117 @@ import org.eclipse.ui.ide.ResourceUtil;
public class SystemTapScriptLaunchShortcut extends ProfileLaunchShortcut implements ILaunchShortcut2 {
- @Override
- public void launch(IEditorPart editor, String mode) {
- String path;
- String project = null;
- if(editor.getEditorInput() instanceof PathEditorInput){
- path = ((PathEditorInput)editor.getEditorInput()).getPath().toString();
- } else {
- IFile file = ResourceUtil.getFile(editor.getEditorInput());
- path = file.getLocation().toString();
- project = file.getProject().getName();
- }
- this.searchAndLaunch(path, project);
- }
-
- @Override
- public void launch(ISelection selection, String mode) {
- IFile file = (IFile)((TreeSelection)selection).getFirstElement();
- String path = file.getLocation().toOSString();
- String project = file.getProject().getName();
- this.searchAndLaunch(path, project);
- }
-
- private void searchAndLaunch(String path, String project){
- ILaunchConfiguration configuration = findLaunchConfiguration(path, project);
- if (configuration == null){
- return;
- }
- try {
- configuration.launch(ILaunchManager.RUN_MODE, new NullProgressMonitor());
- } catch (CoreException e) {
- ExceptionErrorDialog.openError(Messages.SystemTapScriptLaunchShortcut_couldNotLaunchScript, e);
- }
-
- }
-
- private ILaunchConfiguration findLaunchConfiguration(String scriptPath, String scriptProject) {
- ILaunchConfiguration configuration = null;
- ArrayList<ILaunchConfiguration> candidateConfigurations = new ArrayList<>();
- try {
- ILaunchManager launchManager = DebugPlugin.getDefault().getLaunchManager();
- ILaunchConfiguration[] configs = launchManager
- .getLaunchConfigurations(getLaunchConfigType());
-
- for (ILaunchConfiguration config: configs){
- if (config.getAttribute(SystemTapScriptLaunchConfigurationTab.SCRIPT_PATH_ATTR, "").equals(scriptPath)){ //$NON-NLS-1$
- candidateConfigurations.add(config);
- }
- }
-
- int candidateCount = candidateConfigurations.size();
- if (candidateCount == 0) {
- LinkedList<String> configNames = new LinkedList<>();
- configs = launchManager.getLaunchConfigurations();
- for (ILaunchConfiguration config : configs) {
- configNames.add(config.getName());
- }
- String configName = (scriptProject == null ? "" : scriptProject + " ") //$NON-NLS-1$ //$NON-NLS-2$
- + Path.fromOSString(scriptPath).lastSegment();
- String wcName = configName;
- int conflict_index, conflict_count = 0;
- while ((conflict_index = configNames.indexOf(wcName)) != -1) {
- wcName = configName.concat(String.format(" (%d)", ++conflict_count)); //$NON-NLS-1$
- configNames.remove(conflict_index);
- }
-
- ILaunchConfigurationType type = getLaunchConfigType();
- ILaunchConfigurationWorkingCopy wc = type.newInstance(null, wcName);
- wc.setAttribute(SystemTapScriptLaunchConfigurationTab.SCRIPT_PATH_ATTR, scriptPath);
- configuration = wc.doSave();
- } else if (candidateCount == 1) {
- configuration = candidateConfigurations.get(0);
- } else {
- configuration = chooseConfiguration(candidateConfigurations,
- ILaunchManager.RUN_MODE);
- }
- } catch (CoreException e) {
- ExceptionErrorDialog.openError(Messages.SystemTapScriptLaunchShortcut_couldNotFindConfig, e);
- }
-
- return configuration;
- }
-
- @Override
- protected ILaunchConfigurationType getLaunchConfigType() {
- return getLaunchManager().getLaunchConfigurationType(
- SystemTapScriptLaunchConfigurationDelegate.CONFIGURATION_TYPE);
- }
-
- @Override
- protected void setDefaultProfileAttributes(ILaunchConfigurationWorkingCopy wc) {
- }
-
- @Override
- public ILaunchConfiguration[] getLaunchConfigurations(ISelection selection) {
- return null;
- }
-
- @Override
- public ILaunchConfiguration[] getLaunchConfigurations(IEditorPart editorpart) {
- return null;
- }
-
- @Override
- public IResource getLaunchableResource(ISelection selection) {
- return null;
- }
-
- @Override
- public IResource getLaunchableResource(IEditorPart editorpart) {
- return null;
- }
+ @Override
+ public void launch(IEditorPart editor, String mode) {
+ String path;
+ String project = null;
+ if(editor.getEditorInput() instanceof PathEditorInput){
+ path = ((PathEditorInput)editor.getEditorInput()).getPath().toString();
+ } else {
+ IFile file = ResourceUtil.getFile(editor.getEditorInput());
+ path = file.getLocation().toString();
+ project = file.getProject().getName();
+ }
+ this.searchAndLaunch(path, project);
+ }
+
+ @Override
+ public void launch(ISelection selection, String mode) {
+ IFile file = (IFile)((TreeSelection)selection).getFirstElement();
+ String path = file.getLocation().toOSString();
+ String project = file.getProject().getName();
+ this.searchAndLaunch(path, project);
+ }
+
+ private void searchAndLaunch(String path, String project){
+ ILaunchConfiguration configuration = findLaunchConfiguration(path, project);
+ if (configuration == null){
+ return;
+ }
+ try {
+ configuration.launch(ILaunchManager.RUN_MODE, new NullProgressMonitor());
+ } catch (CoreException e) {
+ ExceptionErrorDialog.openError(Messages.SystemTapScriptLaunchShortcut_couldNotLaunchScript, e);
+ }
+
+ }
+
+ private ILaunchConfiguration findLaunchConfiguration(String scriptPath, String scriptProject) {
+ ILaunchConfiguration configuration = null;
+ ArrayList<ILaunchConfiguration> candidateConfigurations = new ArrayList<>();
+ try {
+ ILaunchManager launchManager = DebugPlugin.getDefault().getLaunchManager();
+ ILaunchConfiguration[] configs = launchManager
+ .getLaunchConfigurations(getLaunchConfigType());
+
+ for (ILaunchConfiguration config: configs){
+ if (config.getAttribute(SystemTapScriptLaunchConfigurationTab.SCRIPT_PATH_ATTR, "").equals(scriptPath)){ //$NON-NLS-1$
+ candidateConfigurations.add(config);
+ }
+ }
+
+ int candidateCount = candidateConfigurations.size();
+ if (candidateCount == 0) {
+ LinkedList<String> configNames = new LinkedList<>();
+ configs = launchManager.getLaunchConfigurations();
+ for (ILaunchConfiguration config : configs) {
+ configNames.add(config.getName());
+ }
+ String configName = (scriptProject == null ? "" : scriptProject + " ") //$NON-NLS-1$ //$NON-NLS-2$
+ + Path.fromOSString(scriptPath).lastSegment();
+ String wcName = configName;
+ int conflict_index, conflict_count = 0;
+ while ((conflict_index = configNames.indexOf(wcName)) != -1) {
+ wcName = configName.concat(String.format(" (%d)", ++conflict_count)); //$NON-NLS-1$
+ configNames.remove(conflict_index);
+ }
+
+ ILaunchConfigurationType type = getLaunchConfigType();
+ ILaunchConfigurationWorkingCopy wc = type.newInstance(null, wcName);
+ wc.setAttribute(SystemTapScriptLaunchConfigurationTab.SCRIPT_PATH_ATTR, scriptPath);
+ configuration = wc.doSave();
+ } else if (candidateCount == 1) {
+ configuration = candidateConfigurations.get(0);
+ } else {
+ configuration = chooseConfiguration(candidateConfigurations,
+ ILaunchManager.RUN_MODE);
+ }
+ } catch (CoreException e) {
+ ExceptionErrorDialog.openError(Messages.SystemTapScriptLaunchShortcut_couldNotFindConfig, e);
+ }
+
+ return configuration;
+ }
+
+ @Override
+ protected ILaunchConfigurationType getLaunchConfigType() {
+ return getLaunchManager().getLaunchConfigurationType(
+ SystemTapScriptLaunchConfigurationDelegate.CONFIGURATION_TYPE);
+ }
+
+ @Override
+ protected void setDefaultProfileAttributes(ILaunchConfigurationWorkingCopy wc) {
+ }
+
+ @Override
+ public ILaunchConfiguration[] getLaunchConfigurations(ISelection selection) {
+ return null;
+ }
+
+ @Override
+ public ILaunchConfiguration[] getLaunchConfigurations(IEditorPart editorpart) {
+ return null;
+ }
+
+ @Override
+ public IResource getLaunchableResource(ISelection selection) {
+ return null;
+ }
+
+ @Override
+ public IResource getLaunchableResource(IEditorPart editorpart) {
+ return null;
+ }
diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/launcher/SystemTapScriptOptionsTab.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/launcher/SystemTapScriptOptionsTab.java
index 63e525b833..ce9d746760 100644
--- a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/launcher/SystemTapScriptOptionsTab.java
+++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/launcher/SystemTapScriptOptionsTab.java
@@ -42,244 +42,244 @@ import org.eclipse.ui.plugin.AbstractUIPlugin;
public class SystemTapScriptOptionsTab extends AbstractLaunchConfigurationTab {
- static final String MISC_COMMANDLINE_OPTIONS = "MiscComandLineOptions"; //$NON-NLS-1$
-
- private Button checkBox[] = new Button[IDEPreferenceConstants.STAP_BOOLEAN_OPTIONS.length];
- private Text text[] = new Text[IDEPreferenceConstants.STAP_STRING_OPTIONS.length];
- private Text targetProgramText;
-
- private ModifyListener modifyListener = new ModifyListener() {
- @Override
- public void modifyText(ModifyEvent e) {
- updateLaunchConfigurationDialog();
- }
- };
- private FileDialog fileDialog;
- private Text miscCommandsText;
-
- private Button dyninstCheckBox;
-
- private Text targetPidText;
-
- @Override
- public void createControl(Composite parent) {
-
- GridLayout singleColumnGridLayout = new GridLayout();
- singleColumnGridLayout.numColumns = 1;
- Composite comp = new Composite(parent, SWT.NONE);
- setControl(comp);
- comp.setLayout(singleColumnGridLayout);
- comp.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
-
- this.fileDialog = new FileDialog(PlatformUI.getWorkbench()
- .getActiveWorkbenchWindow().getShell(), SWT.OPEN);
- fileDialog.setText(Messages.SystemTapScriptOptionsTab_selectExec);
- fileDialog.setFilterPath(Platform.getLocation().toOSString());
- // Target Executable path
- Group targetExecutableGroup = new Group(comp, SWT.SHADOW_ETCHED_IN);
- targetExecutableGroup.setText(Messages.SystemTapScriptOptionsTab_targetExec);
- targetExecutableGroup
- .setToolTipText(Messages.SystemTapScriptOptionsTab_targetToolTip);
-
- targetExecutableGroup.setLayoutData(new GridData(SWT.FILL, SWT.FILL,
- true, false));
- GridLayout twoColumnGridLayout = new GridLayout();
- twoColumnGridLayout.numColumns = 2;
- targetExecutableGroup.setLayout(twoColumnGridLayout);
- this.targetProgramText = new Text(targetExecutableGroup, SWT.SINGLE
- | SWT.BORDER);
- targetProgramText.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true,
- true));
- targetProgramText.addModifyListener(modifyListener);
- Button selectTargetProgramButton = new Button(targetExecutableGroup, 0);
- GridData gridData = new GridData();
-
- selectTargetProgramButton.setLayoutData(gridData);
- selectTargetProgramButton
- .setText(Messages.SystemTapScriptLaunchConfigurationTab_browse);
- selectTargetProgramButton.addSelectionListener(new SelectionListener() {
-
- @Override
- public void widgetSelected(SelectionEvent e) {
- String fileName = fileDialog.open();
- if (fileName != null) {
- targetProgramText.setText(fileName);
- }
- }
-
- @Override
- public void widgetDefaultSelected(SelectionEvent e) {
- }
- });
-
- // Check boxes
- Composite cmpChkBoxes = new Composite(comp, SWT.NONE);
- cmpChkBoxes.setLayout(twoColumnGridLayout);
- cmpChkBoxes.setLayoutData(new GridData(SWT.FILL, SWT.BEGINNING, true, false));
-
- for (int i = 0; i < IDEPreferenceConstants.STAP_BOOLEAN_OPTIONS.length; i++) {
- checkBox[i] = new Button(cmpChkBoxes, SWT.CHECK);
- checkBox[i]
- .setText(IDEPreferenceConstants.STAP_BOOLEAN_OPTIONS[i][IDEPreferenceConstants.LABEL]
- + " (" + IDEPreferenceConstants.STAP_BOOLEAN_OPTIONS[i][IDEPreferenceConstants.FLAG] + ")"); //$NON-NLS-1$//$NON-NLS-2$
- checkBox[i].addSelectionListener(new SelectionListener() {
- @Override
- public void widgetSelected(SelectionEvent e) {
- updateLaunchConfigurationDialog();
- }
-
- @Override
- public void widgetDefaultSelected(SelectionEvent e) {
- updateLaunchConfigurationDialog();
- }
- });
- checkBox[i]
- .setToolTipText(IDEPreferenceConstants.STAP_BOOLEAN_OPTIONS[i][IDEPreferenceConstants.TOOLTIP]);
-
- if (IDEPreferenceConstants.STAP_BOOLEAN_OPTIONS[i][IDEPreferenceConstants.FLAG]
- .contains(Messages.SystemTapScriptOptionsTab_dyninst)) {
- this.dyninstCheckBox = checkBox[i];
- }
- }
-
- // Labels and Text fields
- Composite cmpTxtBoxes = new Composite(comp, SWT.NONE);
- cmpTxtBoxes.setLayout(twoColumnGridLayout);
- cmpTxtBoxes.setLayoutData(new GridData(SWT.FILL, SWT.BEGINNING, true, false));
-
- Label label;
- for (int i = 0; i < IDEPreferenceConstants.STAP_STRING_OPTIONS.length; i++) {
- label = new Label(cmpTxtBoxes, SWT.NONE);
- label.setText(IDEPreferenceConstants.STAP_STRING_OPTIONS[i][IDEPreferenceConstants.LABEL]
- + " (" + IDEPreferenceConstants.STAP_STRING_OPTIONS[i][IDEPreferenceConstants.FLAG] + ")"); //$NON-NLS-1$ //$NON-NLS-2$
- label.setToolTipText(IDEPreferenceConstants.STAP_STRING_OPTIONS[i][IDEPreferenceConstants.TOOLTIP]);
- text[i] = new Text(cmpTxtBoxes, SWT.BORDER);
- text[i].setLayoutData(new GridData(SWT.FILL, SWT.BEGINNING, true, true));
- text[i].addModifyListener(modifyListener);
- text[i].setToolTipText(IDEPreferenceConstants.STAP_STRING_OPTIONS[i][IDEPreferenceConstants.TOOLTIP]);
-
- if (IDEPreferenceConstants.STAP_STRING_OPTIONS[i][IDEPreferenceConstants.FLAG]
- .contains("-x")) { //$NON-NLS-1$
- this.targetPidText = text[i];
- }
- }
-
- label = new Label(cmpTxtBoxes, SWT.NONE);
- label.setText(Messages.SystemTapScriptOptionsTab_otherOptions);
- miscCommandsText = new Text(cmpTxtBoxes, SWT.BORDER);
- miscCommandsText.setLayoutData(new GridData(SWT.FILL, SWT.BEGINNING,
- true, true));
- miscCommandsText.addModifyListener(modifyListener);
- }
-
- @Override
- public void setDefaults(ILaunchConfigurationWorkingCopy configuration) {
- IPreferenceStore store = IDEPlugin.getDefault().getPreferenceStore();
-
- configuration.setAttribute(STAP_CMD_OPTION[KEY],
- store.getString(STAP_CMD_OPTION[IDEPreferenceConstants.KEY]));
-
- for (int i = 0; i < IDEPreferenceConstants.STAP_BOOLEAN_OPTIONS.length; i++) {
- configuration
- .setAttribute(
- IDEPreferenceConstants.STAP_BOOLEAN_OPTIONS[i][IDEPreferenceConstants.KEY],
- store.getBoolean(IDEPreferenceConstants.STAP_BOOLEAN_OPTIONS[i][IDEPreferenceConstants.KEY]));
- }
-
- for (int i = 0; i < IDEPreferenceConstants.STAP_STRING_OPTIONS.length; i++) {
- configuration
- .setAttribute(
- IDEPreferenceConstants.STAP_STRING_OPTIONS[i][IDEPreferenceConstants.KEY],
- store.getString(IDEPreferenceConstants.STAP_STRING_OPTIONS[i][IDEPreferenceConstants.KEY]));
- }
-
- configuration.setAttribute(MISC_COMMANDLINE_OPTIONS,
- store.getString(MISC_COMMANDLINE_OPTIONS));
- }
-
- @Override
- public void initializeFrom(ILaunchConfiguration configuration) {
- try {
- targetProgramText.setText(configuration.getAttribute(
- STAP_CMD_OPTION[KEY], "")); //$NON-NLS-1$
-
- for (int i = 0; i < IDEPreferenceConstants.STAP_BOOLEAN_OPTIONS.length; i++) {
- checkBox[i]
- .setSelection(configuration
- .getAttribute(
- IDEPreferenceConstants.STAP_BOOLEAN_OPTIONS[i][IDEPreferenceConstants.KEY],
- false));
- }
-
- for (int i = 0; i < IDEPreferenceConstants.STAP_STRING_OPTIONS.length; i++) {
- text[i].setText(configuration
- .getAttribute(
- IDEPreferenceConstants.STAP_STRING_OPTIONS[i][IDEPreferenceConstants.KEY],
- "")); //$NON-NLS-1$
- }
-
- miscCommandsText.setText(configuration.getAttribute(
- MISC_COMMANDLINE_OPTIONS, "")); //$NON-NLS-1$
-
- } catch (Exception e) {
- ExceptionErrorDialog
- .openError(
- Messages.SystemTapScriptOptionsTab_initializeConfigurationFailed,
- e);
- }
- }
-
- @Override
- public void performApply(ILaunchConfigurationWorkingCopy configuration) {
-
- configuration.setAttribute(STAP_CMD_OPTION[KEY],
- targetProgramText.getText());
-
- for (int i = 0; i < STAP_BOOLEAN_OPTIONS.length; i++) {
- configuration.setAttribute(STAP_BOOLEAN_OPTIONS[i][KEY],
- checkBox[i].getSelection());
- }
-
- for (int i = 0; i < IDEPreferenceConstants.STAP_STRING_OPTIONS.length; i++) {
- configuration.setAttribute(
- IDEPreferenceConstants.STAP_STRING_OPTIONS[i][KEY],
- text[i].getText());
- }
-
- configuration.setAttribute(MISC_COMMANDLINE_OPTIONS,
- miscCommandsText.getText());
- }
-
- @Override
- public String getName() {
- return Messages.SystemTapScriptLaunchConfigurationTab_tabName;
- }
-
- @Override
- public boolean isValid(ILaunchConfiguration launchConfig) {
- setErrorMessage(null);
-
- // If dyninst is being used a pid or a target executable must be
- // specified.
- if (this.dyninstCheckBox.getSelection()
- && this.targetProgramText.getText().isEmpty()
- && this.targetPidText.getText().isEmpty()) {
- setErrorMessage(Messages.SystemTapScriptOptionsTab_dyninstError);
- return false;
- }
-
- if (!this.targetPidText.getText().isEmpty() && !this.targetPidText.getText().matches("[0-9]*")) { //$NON-NLS-1$
- setErrorMessage(Messages.SystemTapScriptOptionsTab_pidError);
- return false;
- }
-
- return true;
- }
-
- @Override
- public Image getImage() {
- return AbstractUIPlugin.imageDescriptorFromPlugin(IDEPlugin.PLUGIN_ID,
- "icons/smileytap_small.gif").createImage(); //$NON-NLS-1$
- }
+ static final String MISC_COMMANDLINE_OPTIONS = "MiscComandLineOptions"; //$NON-NLS-1$
+
+ private Button checkBox[] = new Button[IDEPreferenceConstants.STAP_BOOLEAN_OPTIONS.length];
+ private Text text[] = new Text[IDEPreferenceConstants.STAP_STRING_OPTIONS.length];
+ private Text targetProgramText;
+
+ private ModifyListener modifyListener = new ModifyListener() {
+ @Override
+ public void modifyText(ModifyEvent e) {
+ updateLaunchConfigurationDialog();
+ }
+ };
+ private FileDialog fileDialog;
+ private Text miscCommandsText;
+
+ private Button dyninstCheckBox;
+
+ private Text targetPidText;
+
+ @Override
+ public void createControl(Composite parent) {
+
+ GridLayout singleColumnGridLayout = new GridLayout();
+ singleColumnGridLayout.numColumns = 1;
+ Composite comp = new Composite(parent, SWT.NONE);
+ setControl(comp);
+ comp.setLayout(singleColumnGridLayout);
+ comp.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
+
+ this.fileDialog = new FileDialog(PlatformUI.getWorkbench()
+ .getActiveWorkbenchWindow().getShell(), SWT.OPEN);
+ fileDialog.setText(Messages.SystemTapScriptOptionsTab_selectExec);
+ fileDialog.setFilterPath(Platform.getLocation().toOSString());
+ // Target Executable path
+ Group targetExecutableGroup = new Group(comp, SWT.SHADOW_ETCHED_IN);
+ targetExecutableGroup.setText(Messages.SystemTapScriptOptionsTab_targetExec);
+ targetExecutableGroup
+ .setToolTipText(Messages.SystemTapScriptOptionsTab_targetToolTip);
+
+ targetExecutableGroup.setLayoutData(new GridData(SWT.FILL, SWT.FILL,
+ true, false));
+ GridLayout twoColumnGridLayout = new GridLayout();
+ twoColumnGridLayout.numColumns = 2;
+ targetExecutableGroup.setLayout(twoColumnGridLayout);
+ this.targetProgramText = new Text(targetExecutableGroup, SWT.SINGLE
+ | SWT.BORDER);
+ targetProgramText.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true,
+ true));
+ targetProgramText.addModifyListener(modifyListener);
+ Button selectTargetProgramButton = new Button(targetExecutableGroup, 0);
+ GridData gridData = new GridData();
+
+ selectTargetProgramButton.setLayoutData(gridData);
+ selectTargetProgramButton
+ .setText(Messages.SystemTapScriptLaunchConfigurationTab_browse);
+ selectTargetProgramButton.addSelectionListener(new SelectionListener() {
+
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ String fileName = fileDialog.open();
+ if (fileName != null) {
+ targetProgramText.setText(fileName);
+ }
+ }
+
+ @Override
+ public void widgetDefaultSelected(SelectionEvent e) {
+ }
+ });
+
+ // Check boxes
+ Composite cmpChkBoxes = new Composite(comp, SWT.NONE);
+ cmpChkBoxes.setLayout(twoColumnGridLayout);
+ cmpChkBoxes.setLayoutData(new GridData(SWT.FILL, SWT.BEGINNING, true, false));
+
+ for (int i = 0; i < IDEPreferenceConstants.STAP_BOOLEAN_OPTIONS.length; i++) {
+ checkBox[i] = new Button(cmpChkBoxes, SWT.CHECK);
+ checkBox[i]
+ .setText(IDEPreferenceConstants.STAP_BOOLEAN_OPTIONS[i][IDEPreferenceConstants.LABEL]
+ + " (" + IDEPreferenceConstants.STAP_BOOLEAN_OPTIONS[i][IDEPreferenceConstants.FLAG] + ")"); //$NON-NLS-1$//$NON-NLS-2$
+ checkBox[i].addSelectionListener(new SelectionListener() {
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ updateLaunchConfigurationDialog();
+ }
+
+ @Override
+ public void widgetDefaultSelected(SelectionEvent e) {
+ updateLaunchConfigurationDialog();
+ }
+ });
+ checkBox[i]
+ .setToolTipText(IDEPreferenceConstants.STAP_BOOLEAN_OPTIONS[i][IDEPreferenceConstants.TOOLTIP]);
+
+ if (IDEPreferenceConstants.STAP_BOOLEAN_OPTIONS[i][IDEPreferenceConstants.FLAG]
+ .contains(Messages.SystemTapScriptOptionsTab_dyninst)) {
+ this.dyninstCheckBox = checkBox[i];
+ }
+ }
+
+ // Labels and Text fields
+ Composite cmpTxtBoxes = new Composite(comp, SWT.NONE);
+ cmpTxtBoxes.setLayout(twoColumnGridLayout);
+ cmpTxtBoxes.setLayoutData(new GridData(SWT.FILL, SWT.BEGINNING, true, false));
+
+ Label label;
+ for (int i = 0; i < IDEPreferenceConstants.STAP_STRING_OPTIONS.length; i++) {
+ label = new Label(cmpTxtBoxes, SWT.NONE);
+ label.setText(IDEPreferenceConstants.STAP_STRING_OPTIONS[i][IDEPreferenceConstants.LABEL]
+ + " (" + IDEPreferenceConstants.STAP_STRING_OPTIONS[i][IDEPreferenceConstants.FLAG] + ")"); //$NON-NLS-1$ //$NON-NLS-2$
+ label.setToolTipText(IDEPreferenceConstants.STAP_STRING_OPTIONS[i][IDEPreferenceConstants.TOOLTIP]);
+ text[i] = new Text(cmpTxtBoxes, SWT.BORDER);
+ text[i].setLayoutData(new GridData(SWT.FILL, SWT.BEGINNING, true, true));
+ text[i].addModifyListener(modifyListener);
+ text[i].setToolTipText(IDEPreferenceConstants.STAP_STRING_OPTIONS[i][IDEPreferenceConstants.TOOLTIP]);
+
+ if (IDEPreferenceConstants.STAP_STRING_OPTIONS[i][IDEPreferenceConstants.FLAG]
+ .contains("-x")) { //$NON-NLS-1$
+ this.targetPidText = text[i];
+ }
+ }
+
+ label = new Label(cmpTxtBoxes, SWT.NONE);
+ label.setText(Messages.SystemTapScriptOptionsTab_otherOptions);
+ miscCommandsText = new Text(cmpTxtBoxes, SWT.BORDER);
+ miscCommandsText.setLayoutData(new GridData(SWT.FILL, SWT.BEGINNING,
+ true, true));
+ miscCommandsText.addModifyListener(modifyListener);
+ }
+
+ @Override
+ public void setDefaults(ILaunchConfigurationWorkingCopy configuration) {
+ IPreferenceStore store = IDEPlugin.getDefault().getPreferenceStore();
+
+ configuration.setAttribute(STAP_CMD_OPTION[KEY],
+ store.getString(STAP_CMD_OPTION[IDEPreferenceConstants.KEY]));
+
+ for (int i = 0; i < IDEPreferenceConstants.STAP_BOOLEAN_OPTIONS.length; i++) {
+ configuration
+ .setAttribute(
+ IDEPreferenceConstants.STAP_BOOLEAN_OPTIONS[i][IDEPreferenceConstants.KEY],
+ store.getBoolean(IDEPreferenceConstants.STAP_BOOLEAN_OPTIONS[i][IDEPreferenceConstants.KEY]));
+ }
+
+ for (int i = 0; i < IDEPreferenceConstants.STAP_STRING_OPTIONS.length; i++) {
+ configuration
+ .setAttribute(
+ IDEPreferenceConstants.STAP_STRING_OPTIONS[i][IDEPreferenceConstants.KEY],
+ store.getString(IDEPreferenceConstants.STAP_STRING_OPTIONS[i][IDEPreferenceConstants.KEY]));
+ }
+
+ configuration.setAttribute(MISC_COMMANDLINE_OPTIONS,
+ store.getString(MISC_COMMANDLINE_OPTIONS));
+ }
+
+ @Override
+ public void initializeFrom(ILaunchConfiguration configuration) {
+ try {
+ targetProgramText.setText(configuration.getAttribute(
+ STAP_CMD_OPTION[KEY], "")); //$NON-NLS-1$
+
+ for (int i = 0; i < IDEPreferenceConstants.STAP_BOOLEAN_OPTIONS.length; i++) {
+ checkBox[i]
+ .setSelection(configuration
+ .getAttribute(
+ IDEPreferenceConstants.STAP_BOOLEAN_OPTIONS[i][IDEPreferenceConstants.KEY],
+ false));
+ }
+
+ for (int i = 0; i < IDEPreferenceConstants.STAP_STRING_OPTIONS.length; i++) {
+ text[i].setText(configuration
+ .getAttribute(
+ IDEPreferenceConstants.STAP_STRING_OPTIONS[i][IDEPreferenceConstants.KEY],
+ "")); //$NON-NLS-1$
+ }
+
+ miscCommandsText.setText(configuration.getAttribute(
+ MISC_COMMANDLINE_OPTIONS, "")); //$NON-NLS-1$
+
+ } catch (Exception e) {
+ ExceptionErrorDialog
+ .openError(
+ Messages.SystemTapScriptOptionsTab_initializeConfigurationFailed,
+ e);
+ }
+ }
+
+ @Override
+ public void performApply(ILaunchConfigurationWorkingCopy configuration) {
+
+ configuration.setAttribute(STAP_CMD_OPTION[KEY],
+ targetProgramText.getText());
+
+ for (int i = 0; i < STAP_BOOLEAN_OPTIONS.length; i++) {
+ configuration.setAttribute(STAP_BOOLEAN_OPTIONS[i][KEY],
+ checkBox[i].getSelection());
+ }
+
+ for (int i = 0; i < IDEPreferenceConstants.STAP_STRING_OPTIONS.length; i++) {
+ configuration.setAttribute(
+ IDEPreferenceConstants.STAP_STRING_OPTIONS[i][KEY],
+ text[i].getText());
+ }
+
+ configuration.setAttribute(MISC_COMMANDLINE_OPTIONS,
+ miscCommandsText.getText());
+ }
+
+ @Override
+ public String getName() {
+ return Messages.SystemTapScriptLaunchConfigurationTab_tabName;
+ }
+
+ @Override
+ public boolean isValid(ILaunchConfiguration launchConfig) {
+ setErrorMessage(null);
+
+ // If dyninst is being used a pid or a target executable must be
+ // specified.
+ if (this.dyninstCheckBox.getSelection()
+ && this.targetProgramText.getText().isEmpty()
+ && this.targetPidText.getText().isEmpty()) {
+ setErrorMessage(Messages.SystemTapScriptOptionsTab_dyninstError);
+ return false;
+ }
+
+ if (!this.targetPidText.getText().isEmpty() && !this.targetPidText.getText().matches("[0-9]*")) { //$NON-NLS-1$
+ setErrorMessage(Messages.SystemTapScriptOptionsTab_pidError);
+ return false;
+ }
+
+ return true;
+ }
+
+ @Override
+ public Image getImage() {
+ return AbstractUIPlugin.imageDescriptorFromPlugin(IDEPlugin.PLUGIN_ID,
+ "icons/smileytap_small.gif").createImage(); //$NON-NLS-1$
+ }
}
diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/preferences/CodeAssistPreferencePage.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/preferences/CodeAssistPreferencePage.java
index 9d4829bada..127174bac9 100644
--- a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/preferences/CodeAssistPreferencePage.java
+++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/preferences/CodeAssistPreferencePage.java
@@ -23,47 +23,47 @@ import org.eclipse.ui.IWorkbenchPreferencePage;
public class CodeAssistPreferencePage extends FieldEditorPreferencePage implements IWorkbenchPreferencePage {
- public CodeAssistPreferencePage() {
- super(GRID);
- setPreferenceStore(IDEPlugin.getDefault().getPreferenceStore());
- setDescription(Localization.getString("CodeAssistPreferencePage.CodeAssistPreferenceDescription")); //$NON-NLS-1$
- }
-
- /**
- * Creates the field editors. Field editors are abstractions of
- * the common GUI blocks needed to manipulate various types
- * of preferences. Each field editor knows how to save and
- * restore itself.
- */
- @Override
- public void createFieldEditors() {
- addField(
- new BooleanFieldEditor(
- IDEPreferenceConstants.P_USE_CODE_ASSIST,
- Localization.getString("CodeAssistPreferencePage.UseCodeAssist"), //$NON-NLS-1$
- getFieldEditorParent()));
- addField(new RadioGroupFieldEditor(
- IDEPreferenceConstants.P_COMPLETION,
- Localization.getString("CodeAssistPreferencePage.HowCodeAdded"), //$NON-NLS-1$
- 1,
- new String[][] {
- {Localization.getString("CodeAssistPreferencePage.Insert"), IDEPreferenceConstants.P_COMPLETION_INSERT }, //$NON-NLS-1$
- {Localization.getString("CodeAssistPreferencePage.Overwrite"), IDEPreferenceConstants.P_COMPLETION_OVERWRITE }}, //$NON-NLS-1$
- getFieldEditorParent()));
- addField(
- new IntegerFieldEditor(
- IDEPreferenceConstants.P_ACTIVATION_DELAY,
- Localization.getString("CodeAssistPreferencePage.ActivationDelay"), //$NON-NLS-1$
- getFieldEditorParent()));
- addField(
- new StringFieldEditor(
- IDEPreferenceConstants.P_ACTIVATION_TRIGGER,
- Localization.getString("CodeAssistPreferencePage.ActivationTrigger"), //$NON-NLS-1$
- getFieldEditorParent()));
- }
+ public CodeAssistPreferencePage() {
+ super(GRID);
+ setPreferenceStore(IDEPlugin.getDefault().getPreferenceStore());
+ setDescription(Localization.getString("CodeAssistPreferencePage.CodeAssistPreferenceDescription")); //$NON-NLS-1$
+ }
- @Override
- public void init(IWorkbench workbench) {
- }
+ /**
+ * Creates the field editors. Field editors are abstractions of
+ * the common GUI blocks needed to manipulate various types
+ * of preferences. Each field editor knows how to save and
+ * restore itself.
+ */
+ @Override
+ public void createFieldEditors() {
+ addField(
+ new BooleanFieldEditor(
+ IDEPreferenceConstants.P_USE_CODE_ASSIST,
+ Localization.getString("CodeAssistPreferencePage.UseCodeAssist"), //$NON-NLS-1$
+ getFieldEditorParent()));
+ addField(new RadioGroupFieldEditor(
+ IDEPreferenceConstants.P_COMPLETION,
+ Localization.getString("CodeAssistPreferencePage.HowCodeAdded"), //$NON-NLS-1$
+ 1,
+ new String[][] {
+ {Localization.getString("CodeAssistPreferencePage.Insert"), IDEPreferenceConstants.P_COMPLETION_INSERT }, //$NON-NLS-1$
+ {Localization.getString("CodeAssistPreferencePage.Overwrite"), IDEPreferenceConstants.P_COMPLETION_OVERWRITE }}, //$NON-NLS-1$
+ getFieldEditorParent()));
+ addField(
+ new IntegerFieldEditor(
+ IDEPreferenceConstants.P_ACTIVATION_DELAY,
+ Localization.getString("CodeAssistPreferencePage.ActivationDelay"), //$NON-NLS-1$
+ getFieldEditorParent()));
+ addField(
+ new StringFieldEditor(
+ IDEPreferenceConstants.P_ACTIVATION_TRIGGER,
+ Localization.getString("CodeAssistPreferencePage.ActivationTrigger"), //$NON-NLS-1$
+ getFieldEditorParent()));
+ }
+
+ @Override
+ public void init(IWorkbench workbench) {
+ }
}
diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/preferences/ConditionalExpressionValidator.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/preferences/ConditionalExpressionValidator.java
index a400539348..f8e00c0998 100644
--- a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/preferences/ConditionalExpressionValidator.java
+++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/preferences/ConditionalExpressionValidator.java
@@ -17,30 +17,30 @@ import org.eclipse.jface.dialogs.IInputValidator;
public class ConditionalExpressionValidator implements IInputValidator {
- /**
- * Determines whether or not the string is valid within the contraints.
- *
- * @param s The string to check.
- *
- * @return The return message.
- */
- @Override
- public String isValid(String s) {
- if(null == s) {
- return Messages.ConditionalExpressionValidator_NotNull;
- }
- if(!s.startsWith("if")) {//$NON-NLS-1$
- return Messages.ConditionalExpressionValidator_MustStartWith;
- }
- if(!s.contains("(")) {//$NON-NLS-1$
- return Messages.ConditionalExpressionValidator_MustContain;
- }
- if(!s.endsWith(")")) {//$NON-NLS-1$
- return Messages.ConditionalExpressionValidator_MustEndWith;
- }
- if(s.length() < 5) {
- return Messages.ConditionalExpressionValidator_MustEnterSomething;
- }
- return null;
- }
+ /**
+ * Determines whether or not the string is valid within the contraints.
+ *
+ * @param s The string to check.
+ *
+ * @return The return message.
+ */
+ @Override
+ public String isValid(String s) {
+ if(null == s) {
+ return Messages.ConditionalExpressionValidator_NotNull;
+ }
+ if(!s.startsWith("if")) {//$NON-NLS-1$
+ return Messages.ConditionalExpressionValidator_MustStartWith;
+ }
+ if(!s.contains("(")) {//$NON-NLS-1$
+ return Messages.ConditionalExpressionValidator_MustContain;
+ }
+ if(!s.endsWith(")")) {//$NON-NLS-1$
+ return Messages.ConditionalExpressionValidator_MustEndWith;
+ }
+ if(s.length() < 5) {
+ return Messages.ConditionalExpressionValidator_MustEnterSomething;
+ }
+ return null;
+ }
}
diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/preferences/ConditionalFilterPreferencePage.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/preferences/ConditionalFilterPreferencePage.java
index 1e8b7c1cee..47d1f53a4e 100644
--- a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/preferences/ConditionalFilterPreferencePage.java
+++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/preferences/ConditionalFilterPreferencePage.java
@@ -20,19 +20,19 @@ import org.eclipse.ui.IWorkbenchPreferencePage;
public class ConditionalFilterPreferencePage extends FieldEditorPreferencePage implements IWorkbenchPreferencePage {
- public ConditionalFilterPreferencePage() {
- super(GRID);
- setPreferenceStore(IDEPlugin.getDefault().getPreferenceStore());
- setDescription(Localization.getString("ConditionalFilterPreferencePage.ConditiionalFilterSelector")); //$NON-NLS-1$
- }
-
- @Override
- public void createFieldEditors() {
- addField(new ListEditor(IDEPreferenceConstants.P_CONDITIONAL_FILTERS,
- Localization.getString("ConditionalFilterPreferencePage.ConditionalFilters"), Localization.getString("ConditionalFilterPreferencePage.NewFilter"), "if()", new ConditionalExpressionValidator(), getFieldEditorParent())); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
- }
+ public ConditionalFilterPreferencePage() {
+ super(GRID);
+ setPreferenceStore(IDEPlugin.getDefault().getPreferenceStore());
+ setDescription(Localization.getString("ConditionalFilterPreferencePage.ConditiionalFilterSelector")); //$NON-NLS-1$
+ }
- @Override
- public void init(IWorkbench workbench) {
- }
+ @Override
+ public void createFieldEditors() {
+ addField(new ListEditor(IDEPreferenceConstants.P_CONDITIONAL_FILTERS,
+ Localization.getString("ConditionalFilterPreferencePage.ConditionalFilters"), Localization.getString("ConditionalFilterPreferencePage.NewFilter"), "if()", new ConditionalExpressionValidator(), getFieldEditorParent())); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ }
+
+ @Override
+ public void init(IWorkbench workbench) {
+ }
}
diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/preferences/DirectoryValidator.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/preferences/DirectoryValidator.java
index 748fa2d245..8f082442bc 100644
--- a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/preferences/DirectoryValidator.java
+++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/preferences/DirectoryValidator.java
@@ -17,27 +17,27 @@ import org.eclipse.jface.dialogs.IInputValidator;
public class DirectoryValidator implements IInputValidator {
- /**
- * Determines whether or not the string is valid within the contraints.
- *
- * @param s The string to check.
- *
- * @return The return message.
- */
- @Override
- public String isValid(String s) {
- if(null == s) {
- return Messages.DirectoryValidator_NotNull;
- }
- if(s.length() < 1) {
- return Messages.DirectoryValidator_FolderName;
- }
- if(!s.endsWith("/")) {//$NON-NLS-1$
- return Messages.DirectoryValidator_MustEnd;
- }
- if(s.contains("//")) {//$NON-NLS-1$
- return Messages.DirectoryValidator_CanNotContain;
- }
- return null;
- }
+ /**
+ * Determines whether or not the string is valid within the contraints.
+ *
+ * @param s The string to check.
+ *
+ * @return The return message.
+ */
+ @Override
+ public String isValid(String s) {
+ if(null == s) {
+ return Messages.DirectoryValidator_NotNull;
+ }
+ if(s.length() < 1) {
+ return Messages.DirectoryValidator_FolderName;
+ }
+ if(!s.endsWith("/")) {//$NON-NLS-1$
+ return Messages.DirectoryValidator_MustEnd;
+ }
+ if(s.contains("//")) {//$NON-NLS-1$
+ return Messages.DirectoryValidator_CanNotContain;
+ }
+ return null;
+ }
}
diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/preferences/EditorPreferencePage.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/preferences/EditorPreferencePage.java
index 1fbea1b548..1d14b17359 100644
--- a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/preferences/EditorPreferencePage.java
+++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/preferences/EditorPreferencePage.java
@@ -21,25 +21,25 @@ import org.eclipse.ui.IWorkbenchPreferencePage;
public class EditorPreferencePage extends FieldEditorPreferencePage implements IWorkbenchPreferencePage {
- public EditorPreferencePage() {
- super(GRID);
- setPreferenceStore(IDEPlugin.getDefault().getPreferenceStore());
- setDescription(Localization.getString("EditorPreferencePage.EditorPreferenceDescription")); //$NON-NLS-1$
- }
-
- @Override
- public void createFieldEditors() {
- addField(new ColorFieldEditor(
- IDEPreferenceConstants.P_EDITOR_BACKGROUND,
- Localization.getString("EditorPreferencePage.BackgroundColor"), getFieldEditorParent())); //$NON-NLS-1$
-
- addField(new BooleanFieldEditor(
- IDEPreferenceConstants.P_SHOW_LINE_NUMBERS,
- Localization.getString("EditorPreferencePage.ShowLineNumbers"), //$NON-NLS-1$
- getFieldEditorParent()));
- }
+ public EditorPreferencePage() {
+ super(GRID);
+ setPreferenceStore(IDEPlugin.getDefault().getPreferenceStore());
+ setDescription(Localization.getString("EditorPreferencePage.EditorPreferenceDescription")); //$NON-NLS-1$
+ }
- @Override
- public void init(IWorkbench workbench) {
- }
+ @Override
+ public void createFieldEditors() {
+ addField(new ColorFieldEditor(
+ IDEPreferenceConstants.P_EDITOR_BACKGROUND,
+ Localization.getString("EditorPreferencePage.BackgroundColor"), getFieldEditorParent())); //$NON-NLS-1$
+
+ addField(new BooleanFieldEditor(
+ IDEPreferenceConstants.P_SHOW_LINE_NUMBERS,
+ Localization.getString("EditorPreferencePage.ShowLineNumbers"), //$NON-NLS-1$
+ getFieldEditorParent()));
+ }
+
+ @Override
+ public void init(IWorkbench workbench) {
+ }
}
diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/preferences/EnvironmentVariablesPreferencePage.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/preferences/EnvironmentVariablesPreferencePage.java
index 5426114c45..c5f1af46e2 100644
--- a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/preferences/EnvironmentVariablesPreferencePage.java
+++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/preferences/EnvironmentVariablesPreferencePage.java
@@ -28,132 +28,132 @@ import org.eclipse.ui.IWorkbenchPreferencePage;
public class EnvironmentVariablesPreferencePage extends PreferencePage implements IWorkbenchPreferencePage {
- /**
- * Set the description of the page.
- */
- public EnvironmentVariablesPreferencePage() {
- super();
- setPreferenceStore(IDEPlugin.getDefault().getPreferenceStore());
- setDescription(Messages.EnvironmentVariablesPreferencePage_Title);
- }
-
- @Override
- public void init(IWorkbench workbench) {
- }
-
- /**
- * Creates a ScrolledComposite, sets options on oit, opens string field editors for the
- * preferences.
- *
- * @param parent The parent of the ScrolledComposite object.
- *
- * @return The ScrolledComposite object that is created configured.
- */
- @Override
- protected Control createContents(Composite parent) {
- ScrolledComposite sc = new ScrolledComposite(parent, SWT.H_SCROLL | SWT.V_SCROLL );
- Composite c = new Composite(sc, SWT.NONE);
- sc.setExpandHorizontal(true);
- sc.setExpandVertical(true);
- sc.setContent(c);
-
- envVariables = new StringFieldEditor[PreferenceConstants.P_ENV.length];
- for(int i=0; i<envVariables.length; i++) {
- envVariables[i] = createStringFieldEditor(PreferenceConstants.P_ENV[i][0],
- PreferenceConstants.P_ENV[i][1], c);
- }
- return sc;
- }
-
- /**
- * Creates and returns a StringFieldEditor object with preferences set to it.
- *
- * @param name Name of the field.
- * @param lblText Label text of the field.
- * @param parent Composite object parent of the object.
- *
- * @return The created and configued StringFieldEditor ojbect.
- */
- private StringFieldEditor createStringFieldEditor(String name, String lblText, Composite parent) {
- StringFieldEditor sfe = new StringFieldEditor(name, lblText, parent);
- sfe.setPage(this);
- sfe.setPreferenceStore(getPreferenceStore());
- sfe.load();
-
- return sfe;
- }
-
- /**
- * Loads the default environment variables.
- */
- @Override
- protected void performDefaults() {
- for (StringFieldEditor envVariable : envVariables) {
- envVariable.loadDefault();
- }
-
- super.performDefaults();
- }
-
- /**
- * Stores the modified environment variables.
- *
- * @return True.
- */
- @Override
- public boolean performOk() {
- for (StringFieldEditor envVariable : envVariables) {
- envVariable.store();
- }
-
- return true;
- }
-
- /**
- * Returns the currently stored environment variables in the form of a string array.
- *
- * @return The string array containing the current environment variables.
- */
- public static String[] getEnvironmentVariables() {
- ArrayList<String> vars = new ArrayList<>();
- String[] envVars = null;
- String var;
-
- int i;
- if(null == IDEPlugin.getDefault() || null == IDEPlugin.getDefault().getPreferenceStore()) {
- return null;
- }
- IPreferenceStore p = IDEPlugin.getDefault().getPreferenceStore();
- for(i=0; i<PreferenceConstants.P_ENV.length; i++) {
- var = p.getString(PreferenceConstants.P_ENV[i][0]).trim();
- if(!var.isEmpty()) {
- vars.add(PreferenceConstants.P_ENV[i][0] + "=" + var); //$NON-NLS-1$
- }
- }
-
- if(vars.size() > 0) {
- envVars = new String[vars.size()];
- for (i = 0; i < vars.size(); i++) {
- envVars[i] = vars.get(i);
- }
- }
-
- return envVars;
- }
-
- /**
- * Clears the environment variables string array.
- */
- @Override
- public void dispose() {
- super.dispose();
-
- for(int i=0; i<envVariables.length; i++) {
- envVariables[i].dispose();
- envVariables[i] = null;
- }
- envVariables = null;
- }
-
- private static StringFieldEditor[] envVariables;
+ /**
+ * Set the description of the page.
+ */
+ public EnvironmentVariablesPreferencePage() {
+ super();
+ setPreferenceStore(IDEPlugin.getDefault().getPreferenceStore());
+ setDescription(Messages.EnvironmentVariablesPreferencePage_Title);
+ }
+
+ @Override
+ public void init(IWorkbench workbench) {
+ }
+
+ /**
+ * Creates a ScrolledComposite, sets options on oit, opens string field editors for the
+ * preferences.
+ *
+ * @param parent The parent of the ScrolledComposite object.
+ *
+ * @return The ScrolledComposite object that is created configured.
+ */
+ @Override
+ protected Control createContents(Composite parent) {
+ ScrolledComposite sc = new ScrolledComposite(parent, SWT.H_SCROLL | SWT.V_SCROLL );
+ Composite c = new Composite(sc, SWT.NONE);
+ sc.setExpandHorizontal(true);
+ sc.setExpandVertical(true);
+ sc.setContent(c);
+
+ envVariables = new StringFieldEditor[PreferenceConstants.P_ENV.length];
+ for(int i=0; i<envVariables.length; i++) {
+ envVariables[i] = createStringFieldEditor(PreferenceConstants.P_ENV[i][0],
+ PreferenceConstants.P_ENV[i][1], c);
+ }
+ return sc;
+ }
+
+ /**
+ * Creates and returns a StringFieldEditor object with preferences set to it.
+ *
+ * @param name Name of the field.
+ * @param lblText Label text of the field.
+ * @param parent Composite object parent of the object.
+ *
+ * @return The created and configued StringFieldEditor ojbect.
+ */
+ private StringFieldEditor createStringFieldEditor(String name, String lblText, Composite parent) {
+ StringFieldEditor sfe = new StringFieldEditor(name, lblText, parent);
+ sfe.setPage(this);
+ sfe.setPreferenceStore(getPreferenceStore());
+ sfe.load();
+
+ return sfe;
+ }
+
+ /**
+ * Loads the default environment variables.
+ */
+ @Override
+ protected void performDefaults() {
+ for (StringFieldEditor envVariable : envVariables) {
+ envVariable.loadDefault();
+ }
+
+ super.performDefaults();
+ }
+
+ /**
+ * Stores the modified environment variables.
+ *
+ * @return True.
+ */
+ @Override
+ public boolean performOk() {
+ for (StringFieldEditor envVariable : envVariables) {
+ envVariable.store();
+ }
+
+ return true;
+ }
+
+ /**
+ * Returns the currently stored environment variables in the form of a string array.
+ *
+ * @return The string array containing the current environment variables.
+ */
+ public static String[] getEnvironmentVariables() {
+ ArrayList<String> vars = new ArrayList<>();
+ String[] envVars = null;
+ String var;
+
+ int i;
+ if(null == IDEPlugin.getDefault() || null == IDEPlugin.getDefault().getPreferenceStore()) {
+ return null;
+ }
+ IPreferenceStore p = IDEPlugin.getDefault().getPreferenceStore();
+ for(i=0; i<PreferenceConstants.P_ENV.length; i++) {
+ var = p.getString(PreferenceConstants.P_ENV[i][0]).trim();
+ if(!var.isEmpty()) {
+ vars.add(PreferenceConstants.P_ENV[i][0] + "=" + var); //$NON-NLS-1$
+ }
+ }
+
+ if(vars.size() > 0) {
+ envVars = new String[vars.size()];
+ for (i = 0; i < vars.size(); i++) {
+ envVars[i] = vars.get(i);
+ }
+ }
+
+ return envVars;
+ }
+
+ /**
+ * Clears the environment variables string array.
+ */
+ @Override
+ public void dispose() {
+ super.dispose();
+
+ for(int i=0; i<envVariables.length; i++) {
+ envVariables[i].dispose();
+ envVariables[i] = null;
+ }
+ envVariables = null;
+ }
+
+ private static StringFieldEditor[] envVariables;
}
diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/preferences/IDEPreferenceConstants.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/preferences/IDEPreferenceConstants.java
index 7def8d0c75..285f1d100f 100644
--- a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/preferences/IDEPreferenceConstants.java
+++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/preferences/IDEPreferenceConstants.java
@@ -12,69 +12,69 @@
package org.eclipse.linuxtools.internal.systemtap.ui.ide.preferences;
public class IDEPreferenceConstants {
- //ide
- public static final String P_STORED_TREE = "UseStoredTreePreference"; //$NON-NLS-1$
- public static final String P_REMOTE_PROBES = "RemoteProbes"; //$NON-NLS-1$
+ //ide
+ public static final String P_STORED_TREE = "UseStoredTreePreference"; //$NON-NLS-1$
+ public static final String P_REMOTE_PROBES = "RemoteProbes"; //$NON-NLS-1$
- //ide.path
- public static final String P_KERNEL_SOURCE = "KernelSourcePreference"; //$NON-NLS-1$
- public static final String P_EXCLUDED_KERNEL_SOURCE = "ExcludedKernelSource"; //$NON-NLS-1$
- public static final String P_REMOTE_LOCAL_KERNEL_SOURCE = "RemoteLocalKernelSource"; //$NON-NLS-1$
+ //ide.path
+ public static final String P_KERNEL_SOURCE = "KernelSourcePreference"; //$NON-NLS-1$
+ public static final String P_EXCLUDED_KERNEL_SOURCE = "ExcludedKernelSource"; //$NON-NLS-1$
+ public static final String P_REMOTE_LOCAL_KERNEL_SOURCE = "RemoteLocalKernelSource"; //$NON-NLS-1$
- //ide.stap.tapsets
- public static final String P_TAPSETS = "TapsetPreference"; //$NON-NLS-1$
+ //ide.stap.tapsets
+ public static final String P_TAPSETS = "TapsetPreference"; //$NON-NLS-1$
- //ide.editor
- public static final String P_EDITOR_BACKGROUND = "EditorBackgroundPreference"; //$NON-NLS-1$
- public static final String P_SHOW_LINE_NUMBERS = "ShowLineNumbers"; //$NON-NLS-1$
+ //ide.editor
+ public static final String P_EDITOR_BACKGROUND = "EditorBackgroundPreference"; //$NON-NLS-1$
+ public static final String P_SHOW_LINE_NUMBERS = "ShowLineNumbers"; //$NON-NLS-1$
- //ide.editor.codeassist
- public static final String P_USE_CODE_ASSIST = "UseCodeAssistPreference"; //$NON-NLS-1$
- public static final String P_COMPLETION = "CompletionPreference"; //$NON-NLS-1$
- public static final String P_COMPLETION_INSERT = "CompletionInsertPreference"; //$NON-NLS-1$
- public static final String P_COMPLETION_OVERWRITE = "CompletionOverwritePreference"; //$NON-NLS-1$
- public static final String P_ACTIVATION_DELAY = "ActivationDelayPreference"; //$NON-NLS-1$
- public static final String P_ACTIVATION_TRIGGER = "ActivationTriggerPreference"; //$NON-NLS-1$
+ //ide.editor.codeassist
+ public static final String P_USE_CODE_ASSIST = "UseCodeAssistPreference"; //$NON-NLS-1$
+ public static final String P_COMPLETION = "CompletionPreference"; //$NON-NLS-1$
+ public static final String P_COMPLETION_INSERT = "CompletionInsertPreference"; //$NON-NLS-1$
+ public static final String P_COMPLETION_OVERWRITE = "CompletionOverwritePreference"; //$NON-NLS-1$
+ public static final String P_ACTIVATION_DELAY = "ActivationDelayPreference"; //$NON-NLS-1$
+ public static final String P_ACTIVATION_TRIGGER = "ActivationTriggerPreference"; //$NON-NLS-1$
- //ide.editor.preferenceconstants
- public static final String P_CONDITIONAL_FILTERS = "ConditionalFilters"; //$NON-NLS-1$
+ //ide.editor.preferenceconstants
+ public static final String P_CONDITIONAL_FILTERS = "ConditionalFilters"; //$NON-NLS-1$
- public static final int FLAG = 0;
- public static final int LABEL = 1;
- public static final int KEY = 2;
- public static final int TOOLTIP = 3;
+ public static final int FLAG = 0;
+ public static final int LABEL = 1;
+ public static final int KEY = 2;
+ public static final int TOOLTIP = 3;
- public static final String[][] STAP_BOOLEAN_OPTIONS = new String[][] {
- {"-k", "Keep temporary directory", "kStapPreference", "Keep the temporary directory after all processing. This may be useful in order to examine the generated C code, or to reuse the compiled kernel object."}, //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
- {"-u", "Unoptimized translation", "uStapPreference", "Unoptimized mode. Disable unused code elision during elabora‐tion."}, //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
- {"-b", "Bulk (relayfs) mode", "bStapPreference", "Use bulk mode (percpu files) for kernel-to-user data transfer."}, //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
- {"-t", "Benchmarking timing information", "tStapPreference", "Collect timing information on the number of times probe executes and average amount of time spent in each probe-point. Also shows the derivation for each probe-point."}, //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
- {"-v", "Increase verbosity", "vStapPreference", "Increase verbosity for all passes."}, //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
- {"--runtime=dyninst", "Use dyninst", "dyninstStapPreference", "Dyninst mode allows you to probe userspace processes without root access. This mode requires a -c COMMAND or a -x PID"}}; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+ public static final String[][] STAP_BOOLEAN_OPTIONS = new String[][] {
+ {"-k", "Keep temporary directory", "kStapPreference", "Keep the temporary directory after all processing. This may be useful in order to examine the generated C code, or to reuse the compiled kernel object."}, //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+ {"-u", "Unoptimized translation", "uStapPreference", "Unoptimized mode. Disable unused code elision during elabora‐tion."}, //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+ {"-b", "Bulk (relayfs) mode", "bStapPreference", "Use bulk mode (percpu files) for kernel-to-user data transfer."}, //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+ {"-t", "Benchmarking timing information", "tStapPreference", "Collect timing information on the number of times probe executes and average amount of time spent in each probe-point. Also shows the derivation for each probe-point."}, //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+ {"-v", "Increase verbosity", "vStapPreference", "Increase verbosity for all passes."}, //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+ {"--runtime=dyninst", "Use dyninst", "dyninstStapPreference", "Dyninst mode allows you to probe userspace processes without root access. This mode requires a -c COMMAND or a -x PID"}}; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
- public static final String[][] STAP_STRING_OPTIONS = new String[][] {
- {"-p", "Stop at pass", "pStapPreference", "Stop after the given pass number. The passes are numbered 1-5: parse, elaborate, translate, compile, run."}, //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
- {"-s", "Buffer size", "sStapPreference", "The size of the buffer in megabytes used for kernel-to-user data transfer. On a multiprocessor in bulk mode, this is a per-processor amount."}, //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
- {"-R", "Runtime directory", "RStapPreference", "Look for the systemtap runtime sources in the given directory."}, //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
- {"-r", "Kernel release", "rStapPreference", "Specify a kernel version to use"}, //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
- {"-o", "Output file", "oStapPreference", "Send standard output to the given file"}, //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
- {"-x", "Target PID", "xStapPreference", "Set target() to the given PID. This allows scripts to be written that filter on a specific process."}}; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+ public static final String[][] STAP_STRING_OPTIONS = new String[][] {
+ {"-p", "Stop at pass", "pStapPreference", "Stop after the given pass number. The passes are numbered 1-5: parse, elaborate, translate, compile, run."}, //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+ {"-s", "Buffer size", "sStapPreference", "The size of the buffer in megabytes used for kernel-to-user data transfer. On a multiprocessor in bulk mode, this is a per-processor amount."}, //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+ {"-R", "Runtime directory", "RStapPreference", "Look for the systemtap runtime sources in the given directory."}, //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+ {"-r", "Kernel release", "rStapPreference", "Specify a kernel version to use"}, //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+ {"-o", "Output file", "oStapPreference", "Send standard output to the given file"}, //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+ {"-x", "Target PID", "xStapPreference", "Set target() to the given PID. This allows scripts to be written that filter on a specific process."}}; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
- public static final String[] STAP_CMD_OPTION = new String[] {"-c", "CMD run CMD under systemtap", "cStapPreference", "start the probes, run CMD, and exit when it finishes"}; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+ public static final String[] STAP_CMD_OPTION = new String[] {"-c", "CMD run CMD under systemtap", "cStapPreference", "start the probes, run CMD, and exit when it finishes"}; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
- //ide.editor.syntaxcoloring
- public static final String P_STP_DEFAULT_COLOR = "stpDefaultColorPreference"; //$NON-NLS-1$
- public static final String P_STP_KEYWORD_COLOR = "stpKeywordColorPreference"; //$NON-NLS-1$
- public static final String P_STP_EMBEDDED_C_COLOR = "stpEmbeddedCColorPreference"; //$NON-NLS-1$
- public static final String P_STP_EMBEDDED_COLOR = "stpEmbeddedColorPreference"; //$NON-NLS-1$
- public static final String P_STP_COMMENT_COLOR = "stpCommentColorPreference"; //$NON-NLS-1$
- public static final String P_STP_TYPE_COLOR = "stpTypeColorPreference"; //$NON-NLS-1$
- public static final String P_STP_STRING_COLOR = "stpStringColorPreference"; //$NON-NLS-1$
- public static final String P_C_DEFAULT_COLOR = "cDefaultColorPreference"; //$NON-NLS-1$
- public static final String P_C_KEYWORD_COLOR = "cKeywordColorPreference"; //$NON-NLS-1$
- public static final String P_C_COMMENT_COLOR = "cCommentColorPreference"; //$NON-NLS-1$
- public static final String P_C_PREPROCESSOR_COLOR = "cPreprocessorColorPreference"; //$NON-NLS-1$
- public static final String P_C_TYPE_COLOR = "cTypeColorPreference"; //$NON-NLS-1$
- public static final String P_C_STRING_COLOR = "cStringColorPreference"; //$NON-NLS-1$
+ //ide.editor.syntaxcoloring
+ public static final String P_STP_DEFAULT_COLOR = "stpDefaultColorPreference"; //$NON-NLS-1$
+ public static final String P_STP_KEYWORD_COLOR = "stpKeywordColorPreference"; //$NON-NLS-1$
+ public static final String P_STP_EMBEDDED_C_COLOR = "stpEmbeddedCColorPreference"; //$NON-NLS-1$
+ public static final String P_STP_EMBEDDED_COLOR = "stpEmbeddedColorPreference"; //$NON-NLS-1$
+ public static final String P_STP_COMMENT_COLOR = "stpCommentColorPreference"; //$NON-NLS-1$
+ public static final String P_STP_TYPE_COLOR = "stpTypeColorPreference"; //$NON-NLS-1$
+ public static final String P_STP_STRING_COLOR = "stpStringColorPreference"; //$NON-NLS-1$
+ public static final String P_C_DEFAULT_COLOR = "cDefaultColorPreference"; //$NON-NLS-1$
+ public static final String P_C_KEYWORD_COLOR = "cKeywordColorPreference"; //$NON-NLS-1$
+ public static final String P_C_COMMENT_COLOR = "cCommentColorPreference"; //$NON-NLS-1$
+ public static final String P_C_PREPROCESSOR_COLOR = "cPreprocessorColorPreference"; //$NON-NLS-1$
+ public static final String P_C_TYPE_COLOR = "cTypeColorPreference"; //$NON-NLS-1$
+ public static final String P_C_STRING_COLOR = "cStringColorPreference"; //$NON-NLS-1$
}
diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/preferences/IDEPreferencePage.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/preferences/IDEPreferencePage.java
index 3badd1607c..074bba7255 100644
--- a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/preferences/IDEPreferencePage.java
+++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/preferences/IDEPreferencePage.java
@@ -20,26 +20,26 @@ import org.eclipse.ui.IWorkbenchPreferencePage;
public class IDEPreferencePage extends FieldEditorPreferencePage implements IWorkbenchPreferencePage {
- public IDEPreferencePage() {
- super(GRID);
- setPreferenceStore(IDEPlugin.getDefault().getPreferenceStore());
- setDescription("Preferences when loading the IDE perspective"); //$NON-NLS-1$
- }
-
- @Override
- public void createFieldEditors() {
- addField(new BooleanFieldEditor(
- IDEPreferenceConstants.P_STORED_TREE,
- Localization.getString("IDEPreferencePage.UseStoredTapsetTree"), //$NON-NLS-1$
- getFieldEditorParent()));
- addField(new BooleanFieldEditor(
- IDEPreferenceConstants.P_REMOTE_PROBES,
- Localization.getString("IDEPreferencePage.RemoteProbes"), //$NON-NLS-1$
- getFieldEditorParent()));
- }
+ public IDEPreferencePage() {
+ super(GRID);
+ setPreferenceStore(IDEPlugin.getDefault().getPreferenceStore());
+ setDescription("Preferences when loading the IDE perspective"); //$NON-NLS-1$
+ }
- @Override
- public void init(IWorkbench workbench) {
- }
+ @Override
+ public void createFieldEditors() {
+ addField(new BooleanFieldEditor(
+ IDEPreferenceConstants.P_STORED_TREE,
+ Localization.getString("IDEPreferencePage.UseStoredTapsetTree"), //$NON-NLS-1$
+ getFieldEditorParent()));
+ addField(new BooleanFieldEditor(
+ IDEPreferenceConstants.P_REMOTE_PROBES,
+ Localization.getString("IDEPreferencePage.RemoteProbes"), //$NON-NLS-1$
+ getFieldEditorParent()));
+ }
+
+ @Override
+ public void init(IWorkbench workbench) {
+ }
}
diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/preferences/ListEditor.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/preferences/ListEditor.java
index 9b47133022..a7c7397b06 100644
--- a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/preferences/ListEditor.java
+++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/preferences/ListEditor.java
@@ -29,14 +29,14 @@ public class ListEditor extends org.eclipse.jface.preference.ListEditor {
}
/**
- * Creates and populates a StringBuffer with the supplied items.
- *
- * @param items An array of strings to make the StringBuffer with.
- *
- * @return Returns the StringBuffer.
- */
- @Override
- protected String createList(String[] items) {
+ * Creates and populates a StringBuffer with the supplied items.
+ *
+ * @param items An array of strings to make the StringBuffer with.
+ *
+ * @return Returns the StringBuffer.
+ */
+ @Override
+ protected String createList(String[] items) {
StringBuffer path = new StringBuffer();
for (String item: items) {
@@ -47,22 +47,22 @@ public class ListEditor extends org.eclipse.jface.preference.ListEditor {
}
@Override
- protected String getNewInputObject() {
- InputDialog dialog = new InputDialog(getShell(), dialogTitle, null, initialVal, validator);
- dialog.open();
+ protected String getNewInputObject() {
+ InputDialog dialog = new InputDialog(getShell(), dialogTitle, null, initialVal, validator);
+ dialog.open();
return dialog.getValue();
}
/**
- * Parses the passed in string into an array of strings.
- *
- * @param stringList The string to pass parse.
- *
- * @return Returns the array of strings.
- */
- @Override
- protected String[] parseString(String stringList) {
+ * Parses the passed in string into an array of strings.
+ *
+ * @param stringList The string to pass parse.
+ *
+ * @return Returns the array of strings.
+ */
+ @Override
+ protected String[] parseString(String stringList) {
StringTokenizer st = new StringTokenizer(stringList, File.pathSeparator + "\n\r"); //$NON-NLS-1$
ArrayList<Object> v = new ArrayList<>();
while (st.hasMoreElements()) {
diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/preferences/LocalRemoteDirectoryEditor.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/preferences/LocalRemoteDirectoryEditor.java
index 3ca803ac05..bed12b7c0a 100644
--- a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/preferences/LocalRemoteDirectoryEditor.java
+++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/preferences/LocalRemoteDirectoryEditor.java
@@ -16,41 +16,41 @@ import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
public class LocalRemoteDirectoryEditor extends DirectoryFieldEditor {
- private boolean remote, isEnabled = true;
- public LocalRemoteDirectoryEditor(String name, String labelText, Composite parent, boolean remote) {
- super(name, labelText, parent);
- this.setRemote(remote, parent);
- }
-
- public boolean getRemote() {
- return this.remote;
- }
-
- public void setRemote(boolean remote, Composite parent) {
- this.remote = remote;
- Button b = getChangeControl(parent);
- if (isEnabled)
- b.setEnabled(!remote);
- }
-
- @Override
- public String changePressed() {
- if (this.remote)
- return ""; //$NON-NLS-1$
- return super.changePressed();
- }
-
- @Override
- protected boolean doCheckState() {
- if (this.remote)
- return true;
- return super.doCheckState();
- }
-
- @Override
- public void setEnabled(boolean enabled, Composite parent) {
- super.setEnabled(enabled, parent);
- isEnabled = enabled;
- this.setRemote(this.remote, parent);
- }
+ private boolean remote, isEnabled = true;
+ public LocalRemoteDirectoryEditor(String name, String labelText, Composite parent, boolean remote) {
+ super(name, labelText, parent);
+ this.setRemote(remote, parent);
+ }
+
+ public boolean getRemote() {
+ return this.remote;
+ }
+
+ public void setRemote(boolean remote, Composite parent) {
+ this.remote = remote;
+ Button b = getChangeControl(parent);
+ if (isEnabled)
+ b.setEnabled(!remote);
+ }
+
+ @Override
+ public String changePressed() {
+ if (this.remote)
+ return ""; //$NON-NLS-1$
+ return super.changePressed();
+ }
+
+ @Override
+ protected boolean doCheckState() {
+ if (this.remote)
+ return true;
+ return super.doCheckState();
+ }
+
+ @Override
+ public void setEnabled(boolean enabled, Composite parent) {
+ super.setEnabled(enabled, parent);
+ isEnabled = enabled;
+ this.setRemote(this.remote, parent);
+ }
}
diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/preferences/Messages.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/preferences/Messages.java
index 2ddf95b65a..6a175ed1d0 100644
--- a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/preferences/Messages.java
+++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/preferences/Messages.java
@@ -13,23 +13,23 @@ package org.eclipse.linuxtools.internal.systemtap.ui.ide.preferences;
import org.eclipse.osgi.util.NLS;
public class Messages extends NLS {
- private static final String BUNDLE_NAME = "org.eclipse.linuxtools.internal.systemtap.ui.ide.preferences.messages"; //$NON-NLS-1$
- public static String ConditionalExpressionValidator_MustContain;
- public static String ConditionalExpressionValidator_MustEndWith;
- public static String ConditionalExpressionValidator_MustEnterSomething;
- public static String ConditionalExpressionValidator_MustStartWith;
- public static String ConditionalExpressionValidator_NotNull;
- public static String DirectoryValidator_CanNotContain;
- public static String DirectoryValidator_FolderName;
- public static String DirectoryValidator_MustEnd;
- public static String DirectoryValidator_NotNull;
- public static String EnvironmentVariablesPreferencePage_Title;
- public static String SystemTapPreferencePageDescription;
- static {
- // initialize resource bundle
- NLS.initializeMessages(BUNDLE_NAME, Messages.class);
- }
+ private static final String BUNDLE_NAME = "org.eclipse.linuxtools.internal.systemtap.ui.ide.preferences.messages"; //$NON-NLS-1$
+ public static String ConditionalExpressionValidator_MustContain;
+ public static String ConditionalExpressionValidator_MustEndWith;
+ public static String ConditionalExpressionValidator_MustEnterSomething;
+ public static String ConditionalExpressionValidator_MustStartWith;
+ public static String ConditionalExpressionValidator_NotNull;
+ public static String DirectoryValidator_CanNotContain;
+ public static String DirectoryValidator_FolderName;
+ public static String DirectoryValidator_MustEnd;
+ public static String DirectoryValidator_NotNull;
+ public static String EnvironmentVariablesPreferencePage_Title;
+ public static String SystemTapPreferencePageDescription;
+ static {
+ // initialize resource bundle
+ NLS.initializeMessages(BUNDLE_NAME, Messages.class);
+ }
- private Messages() {
- }
+ private Messages() {
+ }
}
diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/preferences/PathPreferencePage.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/preferences/PathPreferencePage.java
index 99f1946d57..25da7767ab 100644
--- a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/preferences/PathPreferencePage.java
+++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/preferences/PathPreferencePage.java
@@ -22,55 +22,55 @@ import org.eclipse.ui.IWorkbenchPreferencePage;
public class PathPreferencePage extends FieldEditorPreferencePage implements IWorkbenchPreferencePage {
- public static final String REMOTE = "remote"; //$NON-NLS-1$
- public static final String LOCAL = "local"; //$NON-NLS-1$
- private LocalRemoteDirectoryEditor directoryEditor;
+ public static final String REMOTE = "remote"; //$NON-NLS-1$
+ public static final String LOCAL = "local"; //$NON-NLS-1$
+ private LocalRemoteDirectoryEditor directoryEditor;
- public PathPreferencePage() {
- super(GRID);
- setPreferenceStore(IDEPlugin.getDefault().getPreferenceStore());
- }
+ public PathPreferencePage() {
+ super(GRID);
+ setPreferenceStore(IDEPlugin.getDefault().getPreferenceStore());
+ }
- @Override
- public void createFieldEditors() {
- Composite parent = getFieldEditorParent();
- String labels[][] = {{Localization.getString("PathPreferencePage.LocalMachine"), LOCAL}, //$NON-NLS-1$
- {Localization.getString("PathPreferencePage.RemoteMachine"), REMOTE}}; //$NON-NLS-1$
- RadioGroupFieldEditor radioEditor = new RadioGroupFieldEditor(IDEPreferenceConstants.P_REMOTE_LOCAL_KERNEL_SOURCE,
- Localization.getString("PathPreferencePage.RemoteOrLocalRadio"), 1, labels, parent, true) { //$NON-NLS-1$
- @Override
- protected void fireValueChanged(String property,
- Object oldValue,
- Object newValue){
- super.fireValueChanged(property, oldValue, newValue);
- if (!oldValue.equals(newValue) && directoryEditor != null) {
- if (newValue.equals(REMOTE))
- directoryEditor.setRemote(true, getFieldEditorParent());
- else
- directoryEditor.setRemote(false, getFieldEditorParent());
- }
- }
- };
- addField(radioEditor);
+ @Override
+ public void createFieldEditors() {
+ Composite parent = getFieldEditorParent();
+ String labels[][] = {{Localization.getString("PathPreferencePage.LocalMachine"), LOCAL}, //$NON-NLS-1$
+ {Localization.getString("PathPreferencePage.RemoteMachine"), REMOTE}}; //$NON-NLS-1$
+ RadioGroupFieldEditor radioEditor = new RadioGroupFieldEditor(IDEPreferenceConstants.P_REMOTE_LOCAL_KERNEL_SOURCE,
+ Localization.getString("PathPreferencePage.RemoteOrLocalRadio"), 1, labels, parent, true) { //$NON-NLS-1$
+ @Override
+ protected void fireValueChanged(String property,
+ Object oldValue,
+ Object newValue){
+ super.fireValueChanged(property, oldValue, newValue);
+ if (!oldValue.equals(newValue) && directoryEditor != null) {
+ if (newValue.equals(REMOTE))
+ directoryEditor.setRemote(true, getFieldEditorParent());
+ else
+ directoryEditor.setRemote(false, getFieldEditorParent());
+ }
+ }
+ };
+ addField(radioEditor);
- IPreferenceStore p = IDEPlugin.getDefault().getPreferenceStore();
- String remoteOrLocal = p.getString(IDEPreferenceConstants.P_REMOTE_LOCAL_KERNEL_SOURCE);
- boolean remote;
- if (remoteOrLocal.equals(REMOTE))
- remote = true;
- else
- remote = false;
+ IPreferenceStore p = IDEPlugin.getDefault().getPreferenceStore();
+ String remoteOrLocal = p.getString(IDEPreferenceConstants.P_REMOTE_LOCAL_KERNEL_SOURCE);
+ boolean remote;
+ if (remoteOrLocal.equals(REMOTE))
+ remote = true;
+ else
+ remote = false;
- directoryEditor = new LocalRemoteDirectoryEditor(IDEPreferenceConstants.P_KERNEL_SOURCE,
- Localization.getString("PathPreferencePage.KernelSourceDirectory"), parent, remote); //$NON-NLS-1$
- addField(directoryEditor);
+ directoryEditor = new LocalRemoteDirectoryEditor(IDEPreferenceConstants.P_KERNEL_SOURCE,
+ Localization.getString("PathPreferencePage.KernelSourceDirectory"), parent, remote); //$NON-NLS-1$
+ addField(directoryEditor);
- addField(new ListEditor(IDEPreferenceConstants.P_EXCLUDED_KERNEL_SOURCE,
- Localization.getString("PathPreferencePage.ExcludedSourceFolders"), Localization.getString("PathPreferencePage.ExcludedDirectory"), "", new DirectoryValidator(), parent)); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ addField(new ListEditor(IDEPreferenceConstants.P_EXCLUDED_KERNEL_SOURCE,
+ Localization.getString("PathPreferencePage.ExcludedSourceFolders"), Localization.getString("PathPreferencePage.ExcludedDirectory"), "", new DirectoryValidator(), parent)); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
- }
+ }
- @Override
- public void init(IWorkbench workbench) {
- }
+ @Override
+ public void init(IWorkbench workbench) {
+ }
}
diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/preferences/PreferenceConstants.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/preferences/PreferenceConstants.java
index 2a4e151457..fc5a779515 100644
--- a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/preferences/PreferenceConstants.java
+++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/preferences/PreferenceConstants.java
@@ -16,12 +16,12 @@ package org.eclipse.linuxtools.internal.systemtap.ui.ide.preferences;
*/
public class PreferenceConstants {
- //environmentvariables
- public static final String[][] P_ENV = new String[][] {
- {"EnvLdLibraryPath", "LD_LIBRARY_PATH"}, //$NON-NLS-1$ //$NON-NLS-2$
- {"EnvPath", "PATH"}, //$NON-NLS-1$ //$NON-NLS-2$
- {"EnvSystemtapTapset", "SYSTEMTAP_TAPSET"}, //$NON-NLS-1$ //$NON-NLS-2$
- {"EnvSystemtapRuntime", "SYSTEMTAP_RUNTIME"}, //$NON-NLS-1$ //$NON-NLS-2$
- };
+ //environmentvariables
+ public static final String[][] P_ENV = new String[][] {
+ {"EnvLdLibraryPath", "LD_LIBRARY_PATH"}, //$NON-NLS-1$ //$NON-NLS-2$
+ {"EnvPath", "PATH"}, //$NON-NLS-1$ //$NON-NLS-2$
+ {"EnvSystemtapTapset", "SYSTEMTAP_TAPSET"}, //$NON-NLS-1$ //$NON-NLS-2$
+ {"EnvSystemtapRuntime", "SYSTEMTAP_RUNTIME"}, //$NON-NLS-1$ //$NON-NLS-2$
+ };
}
diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/preferences/PreferenceInitializer.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/preferences/PreferenceInitializer.java
index 740296bc8a..ad14abbb3d 100644
--- a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/preferences/PreferenceInitializer.java
+++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/preferences/PreferenceInitializer.java
@@ -25,92 +25,92 @@ import org.eclipse.swt.graphics.RGB;
public class PreferenceInitializer extends AbstractPreferenceInitializer {
- private static final String[] KERNEL_SOURCE_PATH = {"/usr/src/kernels/{kernel_version}", //$NON-NLS-1$
- "/usr/src/linux", //$NON-NLS-1$
- "/usr/src/linux-{kernel_version}" }; //$NON-NLS-1$
-
- @Override
- public void initializeDefaultPreferences() {
- IPreferenceStore store = IDEPlugin.getDefault().getPreferenceStore();
-
- //ide
- store.setDefault(IDEPreferenceConstants.P_STORED_TREE, false);
- store.setDefault(IDEPreferenceConstants.P_REMOTE_PROBES, false);
-
- //ide.path
- store.setDefault(IDEPreferenceConstants.P_KERNEL_SOURCE, getKernelSourceLocation());
- store.setDefault(IDEPreferenceConstants.P_EXCLUDED_KERNEL_SOURCE,
- "CVS/" + File.pathSeparator + //$NON-NLS-1$
- ".svn/" + File.pathSeparator + //$NON-NLS-1$
- "{arch}/" + File.pathSeparator + //$NON-NLS-1$
- ".arch-ids/" + File.pathSeparator + //$NON-NLS-1$
- ".bzr/" + File.pathSeparator + //$NON-NLS-1$
- "debian/" + File.pathSeparator + //$NON-NLS-1$
- ".git/"); //$NON-NLS-1$
- store.setDefault(IDEPreferenceConstants.P_REMOTE_LOCAL_KERNEL_SOURCE, PathPreferencePage.LOCAL);
-
- //ide.stap.tapsets
- store.setDefault(IDEPreferenceConstants.P_TAPSETS, ""); //$NON-NLS-1$
-
- //ide.editor
- PreferenceConverter.setDefault(store, IDEPreferenceConstants.P_EDITOR_BACKGROUND, new RGB(255,255,255));
- store.setDefault(IDEPreferenceConstants.P_SHOW_LINE_NUMBERS, false);
-
- //ide.editor.codeassist
- store.setDefault(IDEPreferenceConstants.P_USE_CODE_ASSIST, true);
- store.setDefault(IDEPreferenceConstants.P_COMPLETION, IDEPreferenceConstants.P_COMPLETION_INSERT);
- store.setDefault(IDEPreferenceConstants.P_ACTIVATION_DELAY, 200);
- store.setDefault(IDEPreferenceConstants.P_ACTIVATION_TRIGGER, "."); //$NON-NLS-1$
-
- //ide.editor.conditionalfilters
- store.setDefault(IDEPreferenceConstants.P_CONDITIONAL_FILTERS,
- "if(pid=currentpid)" + File.pathSeparator + //$NON-NLS-1$
- "if(execname=cmdname)" + File.pathSeparator + //$NON-NLS-1$
- "if(cpu=0)" + File.pathSeparator + //$NON-NLS-1$
- "if(caller=functionname)"); //$NON-NLS-1$
-
-
- //ide.stap.stapoptions
- for(int i=0; i<IDEPreferenceConstants.STAP_BOOLEAN_OPTIONS.length; i++) {
- store.setDefault(IDEPreferenceConstants.STAP_BOOLEAN_OPTIONS[i][IDEPreferenceConstants.KEY], false);
- }
-
- for(int i=0; i<IDEPreferenceConstants.STAP_STRING_OPTIONS.length; i++) {
- store.setDefault(IDEPreferenceConstants.STAP_STRING_OPTIONS[i][IDEPreferenceConstants.KEY], ""); //$NON-NLS-1$
- }
-
- //ide.editor.syntaxcoloring
- PreferenceConverter.setDefault(store, IDEPreferenceConstants.P_STP_DEFAULT_COLOR, STPColorConstants.DEFAULT);
- PreferenceConverter.setDefault(store, IDEPreferenceConstants.P_STP_KEYWORD_COLOR, STPColorConstants.KEYWORD);
- PreferenceConverter.setDefault(store, IDEPreferenceConstants.P_STP_EMBEDDED_C_COLOR, STPColorConstants.EMBEDDEDC);
- PreferenceConverter.setDefault(store, IDEPreferenceConstants.P_STP_EMBEDDED_COLOR, STPColorConstants.EMBEDDED);
- PreferenceConverter.setDefault(store, IDEPreferenceConstants.P_STP_COMMENT_COLOR, STPColorConstants.COMMENT);
- PreferenceConverter.setDefault(store, IDEPreferenceConstants.P_STP_TYPE_COLOR, STPColorConstants.TYPE);
- PreferenceConverter.setDefault(store, IDEPreferenceConstants.P_STP_STRING_COLOR, STPColorConstants.STP_STRING);
-
- }
-
- private String getKernelSourceLocation(){
- // Find out the version of the currently running kernel.
- String version = ""; //$NON-NLS-1$
- try {
- Process process = RuntimeProcessFactory.getFactory().exec("uname -r", null, null);//$NON-NLS-1$
- BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
- version = reader.readLine();
- } catch (IOException e) {
- // Could not run uname use an empty String
- }
-
- // Go over the search path looking for the file System.map
- for (String path : KERNEL_SOURCE_PATH) {
- path = path.replace("{kernel_version}", version); //$NON-NLS-1$
- File file = new File(path+ "/System.map"); //$NON-NLS-1$
- if (file.exists()){
- return path;
- }
- }
-
- return ""; //$NON-NLS-1$
- }
+ private static final String[] KERNEL_SOURCE_PATH = {"/usr/src/kernels/{kernel_version}", //$NON-NLS-1$
+ "/usr/src/linux", //$NON-NLS-1$
+ "/usr/src/linux-{kernel_version}" }; //$NON-NLS-1$
+
+ @Override
+ public void initializeDefaultPreferences() {
+ IPreferenceStore store = IDEPlugin.getDefault().getPreferenceStore();
+
+ //ide
+ store.setDefault(IDEPreferenceConstants.P_STORED_TREE, false);
+ store.setDefault(IDEPreferenceConstants.P_REMOTE_PROBES, false);
+
+ //ide.path
+ store.setDefault(IDEPreferenceConstants.P_KERNEL_SOURCE, getKernelSourceLocation());
+ store.setDefault(IDEPreferenceConstants.P_EXCLUDED_KERNEL_SOURCE,
+ "CVS/" + File.pathSeparator + //$NON-NLS-1$
+ ".svn/" + File.pathSeparator + //$NON-NLS-1$
+ "{arch}/" + File.pathSeparator + //$NON-NLS-1$
+ ".arch-ids/" + File.pathSeparator + //$NON-NLS-1$
+ ".bzr/" + File.pathSeparator + //$NON-NLS-1$
+ "debian/" + File.pathSeparator + //$NON-NLS-1$
+ ".git/"); //$NON-NLS-1$
+ store.setDefault(IDEPreferenceConstants.P_REMOTE_LOCAL_KERNEL_SOURCE, PathPreferencePage.LOCAL);
+
+ //ide.stap.tapsets
+ store.setDefault(IDEPreferenceConstants.P_TAPSETS, ""); //$NON-NLS-1$
+
+ //ide.editor
+ PreferenceConverter.setDefault(store, IDEPreferenceConstants.P_EDITOR_BACKGROUND, new RGB(255,255,255));
+ store.setDefault(IDEPreferenceConstants.P_SHOW_LINE_NUMBERS, false);
+
+ //ide.editor.codeassist
+ store.setDefault(IDEPreferenceConstants.P_USE_CODE_ASSIST, true);
+ store.setDefault(IDEPreferenceConstants.P_COMPLETION, IDEPreferenceConstants.P_COMPLETION_INSERT);
+ store.setDefault(IDEPreferenceConstants.P_ACTIVATION_DELAY, 200);
+ store.setDefault(IDEPreferenceConstants.P_ACTIVATION_TRIGGER, "."); //$NON-NLS-1$
+
+ //ide.editor.conditionalfilters
+ store.setDefault(IDEPreferenceConstants.P_CONDITIONAL_FILTERS,
+ "if(pid=currentpid)" + File.pathSeparator + //$NON-NLS-1$
+ "if(execname=cmdname)" + File.pathSeparator + //$NON-NLS-1$
+ "if(cpu=0)" + File.pathSeparator + //$NON-NLS-1$
+ "if(caller=functionname)"); //$NON-NLS-1$
+
+
+ //ide.stap.stapoptions
+ for(int i=0; i<IDEPreferenceConstants.STAP_BOOLEAN_OPTIONS.length; i++) {
+ store.setDefault(IDEPreferenceConstants.STAP_BOOLEAN_OPTIONS[i][IDEPreferenceConstants.KEY], false);
+ }
+
+ for(int i=0; i<IDEPreferenceConstants.STAP_STRING_OPTIONS.length; i++) {
+ store.setDefault(IDEPreferenceConstants.STAP_STRING_OPTIONS[i][IDEPreferenceConstants.KEY], ""); //$NON-NLS-1$
+ }
+
+ //ide.editor.syntaxcoloring
+ PreferenceConverter.setDefault(store, IDEPreferenceConstants.P_STP_DEFAULT_COLOR, STPColorConstants.DEFAULT);
+ PreferenceConverter.setDefault(store, IDEPreferenceConstants.P_STP_KEYWORD_COLOR, STPColorConstants.KEYWORD);
+ PreferenceConverter.setDefault(store, IDEPreferenceConstants.P_STP_EMBEDDED_C_COLOR, STPColorConstants.EMBEDDEDC);
+ PreferenceConverter.setDefault(store, IDEPreferenceConstants.P_STP_EMBEDDED_COLOR, STPColorConstants.EMBEDDED);
+ PreferenceConverter.setDefault(store, IDEPreferenceConstants.P_STP_COMMENT_COLOR, STPColorConstants.COMMENT);
+ PreferenceConverter.setDefault(store, IDEPreferenceConstants.P_STP_TYPE_COLOR, STPColorConstants.TYPE);
+ PreferenceConverter.setDefault(store, IDEPreferenceConstants.P_STP_STRING_COLOR, STPColorConstants.STP_STRING);
+
+ }
+
+ private String getKernelSourceLocation(){
+ // Find out the version of the currently running kernel.
+ String version = ""; //$NON-NLS-1$
+ try {
+ Process process = RuntimeProcessFactory.getFactory().exec("uname -r", null, null);//$NON-NLS-1$
+ BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
+ version = reader.readLine();
+ } catch (IOException e) {
+ // Could not run uname use an empty String
+ }
+
+ // Go over the search path looking for the file System.map
+ for (String path : KERNEL_SOURCE_PATH) {
+ path = path.replace("{kernel_version}", version); //$NON-NLS-1$
+ File file = new File(path+ "/System.map"); //$NON-NLS-1$
+ if (file.exists()){
+ return path;
+ }
+ }
+
+ return ""; //$NON-NLS-1$
+ }
}
diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/preferences/SyntaxColoringPreferencePage.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/preferences/SyntaxColoringPreferencePage.java
index af27220507..c2aec9723f 100644
--- a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/preferences/SyntaxColoringPreferencePage.java
+++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/preferences/SyntaxColoringPreferencePage.java
@@ -24,100 +24,100 @@ import org.eclipse.ui.IWorkbenchPreferencePage;
public class SyntaxColoringPreferencePage extends PreferencePage implements IWorkbenchPreferencePage {
- public SyntaxColoringPreferencePage() {
- super();
- setPreferenceStore(IDEPlugin.getDefault().getPreferenceStore());
- setDescription(Localization.getString("SyntaxColoringPreferencePage.SyntaxColoringOptions")); //$NON-NLS-1$
- }
-
- @Override
- public void init(IWorkbench workbench) {
- }
-
- @Override
- protected Control createContents(Composite parent) {
- //STP Editor
- Composite comp = new Composite(parent, SWT.NULL);
- comp.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
-
- stpDC = createColorFieldEditor(
- IDEPreferenceConstants.P_STP_DEFAULT_COLOR,
- Localization.getString("SyntaxColoringPreferencePage.DefaultColor"), comp); //$NON-NLS-1$
- stpKC = createColorFieldEditor(
- IDEPreferenceConstants.P_STP_KEYWORD_COLOR,
- Localization.getString("SyntaxColoringPreferencePage.KeywordColor"), comp); //$NON-NLS-1$
- stpEC = createColorFieldEditor(
- IDEPreferenceConstants.P_STP_EMBEDDED_C_COLOR,
- Localization.getString("SyntaxColoringPreferencePage.EmbeddedCColor"), comp); //$NON-NLS-1$
- stpEE = createColorFieldEditor(
- IDEPreferenceConstants.P_STP_EMBEDDED_COLOR,
- Localization.getString("SyntaxColoringPreferencePage.EmbeddedColor"), comp); //$NON-NLS-1$
- stpCC = createColorFieldEditor(
- IDEPreferenceConstants.P_STP_COMMENT_COLOR,
- Localization.getString("SyntaxColoringPreferencePage.CommentColor"), comp); //$NON-NLS-1$
- stpTC = createColorFieldEditor(
- IDEPreferenceConstants.P_STP_TYPE_COLOR,
- Localization.getString("SyntaxColoringPreferencePage.TypeColor"), comp); //$NON-NLS-1$
- stpSC = createColorFieldEditor(
- IDEPreferenceConstants.P_STP_STRING_COLOR,
- Localization.getString("SyntaxColoringPreferencePage.StringColor"), comp); //$NON-NLS-1$
-
- return comp;
- }
-
- private ColorFieldEditor createColorFieldEditor(String name, String lblText, Composite parent) {
- ColorFieldEditor cfe = new ColorFieldEditor(name, lblText, parent);
- cfe.setPage(this);
- cfe.setPreferenceStore(getPreferenceStore());
- cfe.load();
-
- return cfe;
- }
-
- @Override
- protected void performDefaults() {
- stpDC.loadDefault();
- stpKC.loadDefault();
- stpEC.loadDefault();
- stpEE.loadDefault();
- stpCC.loadDefault();
- stpTC.loadDefault();
- stpSC.loadDefault();
-
- super.performDefaults();
- }
-
- @Override
- public boolean performOk() {
- stpDC.store();
- stpKC.store();
- stpEC.store();
- stpEE.store();
- stpCC.store();
- stpTC.store();
- stpSC.store();
-
- return true;
- }
-
- @Override
- public void dispose() {
- super.dispose();
- stpDC.dispose();
- stpKC.dispose();
- stpEC.dispose();
- stpEE.dispose();
- stpCC.dispose();
- stpTC.dispose();
- stpSC.dispose();
- stpDC = null;
- stpKC = null;
- stpEC = null;
- stpEE = null;
- stpCC = null;
- stpTC = null;
- stpSC = null;
- }
-
- private ColorFieldEditor stpDC, stpKC, stpEC, stpEE, stpCC, stpTC, stpSC;
+ public SyntaxColoringPreferencePage() {
+ super();
+ setPreferenceStore(IDEPlugin.getDefault().getPreferenceStore());
+ setDescription(Localization.getString("SyntaxColoringPreferencePage.SyntaxColoringOptions")); //$NON-NLS-1$
+ }
+
+ @Override
+ public void init(IWorkbench workbench) {
+ }
+
+ @Override
+ protected Control createContents(Composite parent) {
+ //STP Editor
+ Composite comp = new Composite(parent, SWT.NULL);
+ comp.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
+
+ stpDC = createColorFieldEditor(
+ IDEPreferenceConstants.P_STP_DEFAULT_COLOR,
+ Localization.getString("SyntaxColoringPreferencePage.DefaultColor"), comp); //$NON-NLS-1$
+ stpKC = createColorFieldEditor(
+ IDEPreferenceConstants.P_STP_KEYWORD_COLOR,
+ Localization.getString("SyntaxColoringPreferencePage.KeywordColor"), comp); //$NON-NLS-1$
+ stpEC = createColorFieldEditor(
+ IDEPreferenceConstants.P_STP_EMBEDDED_C_COLOR,
+ Localization.getString("SyntaxColoringPreferencePage.EmbeddedCColor"), comp); //$NON-NLS-1$
+ stpEE = createColorFieldEditor(
+ IDEPreferenceConstants.P_STP_EMBEDDED_COLOR,
+ Localization.getString("SyntaxColoringPreferencePage.EmbeddedColor"), comp); //$NON-NLS-1$
+ stpCC = createColorFieldEditor(
+ IDEPreferenceConstants.P_STP_COMMENT_COLOR,
+ Localization.getString("SyntaxColoringPreferencePage.CommentColor"), comp); //$NON-NLS-1$
+ stpTC = createColorFieldEditor(
+ IDEPreferenceConstants.P_STP_TYPE_COLOR,
+ Localization.getString("SyntaxColoringPreferencePage.TypeColor"), comp); //$NON-NLS-1$
+ stpSC = createColorFieldEditor(
+ IDEPreferenceConstants.P_STP_STRING_COLOR,
+ Localization.getString("SyntaxColoringPreferencePage.StringColor"), comp); //$NON-NLS-1$
+
+ return comp;
+ }
+
+ private ColorFieldEditor createColorFieldEditor(String name, String lblText, Composite parent) {
+ ColorFieldEditor cfe = new ColorFieldEditor(name, lblText, parent);
+ cfe.setPage(this);
+ cfe.setPreferenceStore(getPreferenceStore());
+ cfe.load();
+
+ return cfe;
+ }
+
+ @Override
+ protected void performDefaults() {
+ stpDC.loadDefault();
+ stpKC.loadDefault();
+ stpEC.loadDefault();
+ stpEE.loadDefault();
+ stpCC.loadDefault();
+ stpTC.loadDefault();
+ stpSC.loadDefault();
+
+ super.performDefaults();
+ }
+
+ @Override
+ public boolean performOk() {
+ stpDC.store();
+ stpKC.store();
+ stpEC.store();
+ stpEE.store();
+ stpCC.store();
+ stpTC.store();
+ stpSC.store();
+
+ return true;
+ }
+
+ @Override
+ public void dispose() {
+ super.dispose();
+ stpDC.dispose();
+ stpKC.dispose();
+ stpEC.dispose();
+ stpEE.dispose();
+ stpCC.dispose();
+ stpTC.dispose();
+ stpSC.dispose();
+ stpDC = null;
+ stpKC = null;
+ stpEC = null;
+ stpEE = null;
+ stpCC = null;
+ stpTC = null;
+ stpSC = null;
+ }
+
+ private ColorFieldEditor stpDC, stpKC, stpEC, stpEE, stpCC, stpTC, stpSC;
}
diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/preferences/SystemTapPreferencePage.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/preferences/SystemTapPreferencePage.java
index a1cabed287..9589505a51 100644
--- a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/preferences/SystemTapPreferencePage.java
+++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/preferences/SystemTapPreferencePage.java
@@ -19,23 +19,23 @@ import org.eclipse.ui.IWorkbenchPreferencePage;
public class SystemTapPreferencePage extends FieldEditorPreferencePage implements IWorkbenchPreferencePage {
- /**
- * Get the current preferences.
- */
- public SystemTapPreferencePage() {
- super();
- setDescription(Messages.SystemTapPreferencePageDescription);
- }
-
- /**
- * Sets up the field editors for optional change by the user.
- */
- @Override
- public void createFieldEditors() {
- }
-
- @Override
- public void init(IWorkbench workbench) {
- }
+ /**
+ * Get the current preferences.
+ */
+ public SystemTapPreferencePage() {
+ super();
+ setDescription(Messages.SystemTapPreferencePageDescription);
+ }
+
+ /**
+ * Sets up the field editors for optional change by the user.
+ */
+ @Override
+ public void createFieldEditors() {
+ }
+
+ @Override
+ public void init(IWorkbench workbench) {
+ }
}
diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/preferences/TapsetsPreferencePage.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/preferences/TapsetsPreferencePage.java
index 29e62c93bf..37fe25dcba 100644
--- a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/preferences/TapsetsPreferencePage.java
+++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/preferences/TapsetsPreferencePage.java
@@ -20,25 +20,25 @@ import org.eclipse.ui.IWorkbenchPreferencePage;
public class TapsetsPreferencePage extends FieldEditorPreferencePage implements IWorkbenchPreferencePage {
- public TapsetsPreferencePage() {
- super(GRID);
- setPreferenceStore(IDEPlugin.getDefault().getPreferenceStore());
- setDescription(Localization.getString("TapsetsPreferencePage.AdditionalTapsetsCategory")); //$NON-NLS-1$
- }
-
- /**
- * Creates the field editors. Field editors are abstractions of
- * the common GUI blocks needed to manipulate various types
- * of preferences. Each field editor knows how to save and
- * restore itself.
- */
- @Override
- public void createFieldEditors() {
- addField(new PathEditor(IDEPreferenceConstants.P_TAPSETS,
- Localization.getString("TapsetsPreferencePage.AdditionalTapsets"), Localization.getString("TapsetsPreferencePage.TapsetDirectory"), getFieldEditorParent())); //$NON-NLS-1$ //$NON-NLS-2$
- }
+ public TapsetsPreferencePage() {
+ super(GRID);
+ setPreferenceStore(IDEPlugin.getDefault().getPreferenceStore());
+ setDescription(Localization.getString("TapsetsPreferencePage.AdditionalTapsetsCategory")); //$NON-NLS-1$
+ }
- @Override
- public void init(IWorkbench workbench) {
- }
+ /**
+ * Creates the field editors. Field editors are abstractions of
+ * the common GUI blocks needed to manipulate various types
+ * of preferences. Each field editor knows how to save and
+ * restore itself.
+ */
+ @Override
+ public void createFieldEditors() {
+ addField(new PathEditor(IDEPreferenceConstants.P_TAPSETS,
+ Localization.getString("TapsetsPreferencePage.AdditionalTapsets"), Localization.getString("TapsetsPreferencePage.TapsetDirectory"), getFieldEditorParent())); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+ @Override
+ public void init(IWorkbench workbench) {
+ }
}
diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/FuncparamNodeData.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/FuncparamNodeData.java
index f6212437dd..8733da589b 100644
--- a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/FuncparamNodeData.java
+++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/FuncparamNodeData.java
@@ -19,27 +19,27 @@ import org.eclipse.linuxtools.systemtap.structures.TreeNode;
*/
public class FuncparamNodeData implements ISingleTypedNode {
- private final String line;
- private final String type;
+ private final String line;
+ private final String type;
- @Override
- public String toString() {
- return line;
- }
+ @Override
+ public String toString() {
+ return line;
+ }
- @Override
- public String getType() {
- return type;
- }
+ @Override
+ public String getType() {
+ return type;
+ }
- /**
- * Create a new instance of function parameter information. (Note that the name of a function
- * or parameter is stored in a {@link TreeNode}, not here.)
- * @param line The <code>String</code> representation of the entire parameter.
- * @param type The <code>String</code> representation of only the parameter's type.
- */
- public FuncparamNodeData(String line, String type) {
- this.line = line;
- this.type = type == null ? FunctionParser.UNKNOWN_TYPE : type; // Parameters can't be void.
- }
+ /**
+ * Create a new instance of function parameter information. (Note that the name of a function
+ * or parameter is stored in a {@link TreeNode}, not here.)
+ * @param line The <code>String</code> representation of the entire parameter.
+ * @param type The <code>String</code> representation of only the parameter's type.
+ */
+ public FuncparamNodeData(String line, String type) {
+ this.line = line;
+ this.type = type == null ? FunctionParser.UNKNOWN_TYPE : type; // Parameters can't be void.
+ }
}
diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/FunctionNodeData.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/FunctionNodeData.java
index f18ed04680..6ae140a078 100644
--- a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/FunctionNodeData.java
+++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/FunctionNodeData.java
@@ -18,44 +18,44 @@ import org.eclipse.linuxtools.systemtap.structures.TreeNode;
* @since 3.0
*/
public class FunctionNodeData implements ISearchableNode, ISingleTypedNode {
- private final String line;
- private final String type;
-
- @Override
- public boolean isRegexSearch() {
- return false;
- }
-
- /**
- * @return the text to search a file with for the definition of this function.
- */
- @Override
- public String getSearchToken() {
- return line;
- }
-
- @Override
- public String toString() {
- return getSearchToken();
- }
-
- /**
- * @return the <code>String</code> representation of the return type of the
- * node's function (<code>null</code> for void functions).
- */
- @Override
- public String getType() {
- return type;
- }
-
- /**
- * Create a new instance of function node information. (Note that the name of a function
- * or parameter is stored in a {@link TreeNode}, not here.)
- * @param line Set this to the original script text that defines this function.
- * @param type The <code>String</code> representation of the return type of the function.
- */
- public FunctionNodeData(String line, String type) {
- this.line = line;
- this.type = type;
- }
+ private final String line;
+ private final String type;
+
+ @Override
+ public boolean isRegexSearch() {
+ return false;
+ }
+
+ /**
+ * @return the text to search a file with for the definition of this function.
+ */
+ @Override
+ public String getSearchToken() {
+ return line;
+ }
+
+ @Override
+ public String toString() {
+ return getSearchToken();
+ }
+
+ /**
+ * @return the <code>String</code> representation of the return type of the
+ * node's function (<code>null</code> for void functions).
+ */
+ @Override
+ public String getType() {
+ return type;
+ }
+
+ /**
+ * Create a new instance of function node information. (Note that the name of a function
+ * or parameter is stored in a {@link TreeNode}, not here.)
+ * @param line Set this to the original script text that defines this function.
+ * @param type The <code>String</code> representation of the return type of the function.
+ */
+ public FunctionNodeData(String line, String type) {
+ this.line = line;
+ this.type = type;
+ }
}
diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/FunctionParser.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/FunctionParser.java
index 904ac20c42..1c5961665d 100644
--- a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/FunctionParser.java
+++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/FunctionParser.java
@@ -34,154 +34,154 @@ import org.eclipse.linuxtools.systemtap.structures.TreeNode;
*/
public class FunctionParser extends TapsetParser {
- static FunctionParser parser = null;
- private TreeNode functions;
-
- /**
- * The descriptor used for unresolvable types.
- */
- public static final String UNKNOWN_TYPE = "unknown"; //$NON-NLS-1$
-
- private static final String functionRegex = "(?s)(?<!\\w)function\\s+{0}(?:\\s*:\\s*(\\w+))?\\s*\\(([^)]+?)?\\)"; //$NON-NLS-1$
- private static final Pattern pFunction = Pattern.compile("function (?!_)(\\w+) \\(.*?\\)"); //$NON-NLS-1$
- private static final Pattern pParams = Pattern.compile("(\\w+)(?:\\s*:\\s*(\\w+))?"); //$NON-NLS-1$
- private static final Pattern pAllCaps = Pattern.compile("[A-Z_1-9]*"); //$NON-NLS-1$
- private static final Pattern pReturn = Pattern.compile("\\sreturn\\W"); //$NON-NLS-1$
-
- public static FunctionParser getInstance(){
- if (parser != null) {
- return parser;
- }
- parser = new FunctionParser();
- return parser;
- }
-
- private FunctionParser() {
- super("Function Parser"); //$NON-NLS-1$
- }
-
- /**
- * Returns the root node of the tree of functions generated by
- * parseFiles. Functions are grouped by source file.
- * @return A tree of tapset functions grouped by file.
- */
- public synchronized TreeNode getFunctions() {
- return functions;
- }
-
- /**
- * This method will clean up everything from the run.
- */
- public void dispose() {
- functions.dispose();
- }
-
- @Override
- protected IStatus run(IProgressMonitor monitor) {
- boolean cancelled = runPass2Functions();
- functions.sortTree();
- fireUpdateEvent(); //Inform listeners that everything is done
- return new Status(!cancelled ? IStatus.OK : IStatus.CANCEL, IDEPlugin.PLUGIN_ID, ""); //$NON-NLS-1$
- }
-
- /**
- * This method is used to build up the list of functions that were found
- * during the first pass of stap. Stap is invoked by: $stap -v -p1 -e
- * 'probe begin{}' and parsing the output.
- *
- * FunctionTree organized as:
- * Root->Functions->Parameters
- *
- * @return <code>false</code> if a cancellation prevented all probes from being added;
- * <code>true</code> otherwise.
- */
- private boolean runPass2Functions() {
- String tapsetContents = SharedParser.getInstance().getTapsetContents();
- if (cancelRequested) {
- return false;
- }
- // Create a new function tree each time, so as to not add duplicates
- functions = new TreeNode("", false); //$NON-NLS-1$
- if (tapsetContents == null) {
- // Functions are only drawn from the tapset dump, so exit if it's empty.
- return true;
- }
- try (Scanner st = new Scanner(tapsetContents)) {
- String filename = null;
- String scriptText = null;
-
- SharedParser sparser = SharedParser.getInstance();
- while (st.hasNextLine()) {
- if (cancelRequested) {
- return false;
- }
- String tok = st.nextLine();
- Matcher mFilename = sparser.filePattern.matcher(tok);
- if (mFilename.matches()) {
- filename = mFilename.group(1).toString();
- scriptText = null;
- } else if (filename != null) {
- Matcher mFunction = pFunction.matcher(tok);
- if (mFunction.matches()) {
- String functionName = mFunction.group(1);
- if (pAllCaps.matcher(functionName).matches()) {
- // Ignore ALL_CAPS functions, since they are not meant for end-user use.
- continue;
- }
- if (scriptText == null) {
- // If this is the first time seeing this file, remove its comments.
- scriptText = CommentRemover.execWithFile(filename);
- }
- addFunctionFromScript(functionName, scriptText, filename);
- }
- }
- }
- return true;
- }
- }
-
- private void addFunctionFromScript(String functionName, String scriptText, String scriptFilename) {
- String regex = MessageFormat.format(functionRegex, functionName);
- Matcher mScript = Pattern.compile(regex).matcher(scriptText);
- if (mScript.find()) {
- String functionLine = mScript.group();
- String functionType = mScript.group(1);
- // If the function has no return type, look for a "return" statement to check
- // if it's really a void function, or if its return type is just unspecified
- if (functionType == null && getNextBlockContents(scriptText, mScript.end(), pReturn)) {
- functionType = UNKNOWN_TYPE;
- }
- TreeDefinitionNode function = new TreeDefinitionNode(
- new FunctionNodeData(functionLine, functionType),
- functionName, scriptFilename, true);
- functions.add(function);
- addParamsFromString(mScript.group(2), function);
- }
- }
-
- private boolean getNextBlockContents(String scriptText, int start, Pattern p) {
- int end, bcount = 1;
- start = scriptText.indexOf('{', start) + 1;
- for (end = start; end < scriptText.length(); end++) {
- char c = scriptText.charAt(end);
- if (c == '{') {
- bcount++;
- } else if (c == '}' && --bcount == 0) {
- break;
- }
- }
- return p.matcher(scriptText.substring(start, end)).find();
- }
-
- private void addParamsFromString(String params, TreeNode parentFunction) {
- if (params != null) {
- Matcher mParams = pParams.matcher(params);
- while (mParams.find()) {
- parentFunction.add(new TreeNode(
- new FuncparamNodeData(mParams.group(), mParams.group(2)),
- mParams.group(1), false));
- }
- }
- }
+ static FunctionParser parser = null;
+ private TreeNode functions;
+
+ /**
+ * The descriptor used for unresolvable types.
+ */
+ public static final String UNKNOWN_TYPE = "unknown"; //$NON-NLS-1$
+
+ private static final String functionRegex = "(?s)(?<!\\w)function\\s+{0}(?:\\s*:\\s*(\\w+))?\\s*\\(([^)]+?)?\\)"; //$NON-NLS-1$
+ private static final Pattern pFunction = Pattern.compile("function (?!_)(\\w+) \\(.*?\\)"); //$NON-NLS-1$
+ private static final Pattern pParams = Pattern.compile("(\\w+)(?:\\s*:\\s*(\\w+))?"); //$NON-NLS-1$
+ private static final Pattern pAllCaps = Pattern.compile("[A-Z_1-9]*"); //$NON-NLS-1$
+ private static final Pattern pReturn = Pattern.compile("\\sreturn\\W"); //$NON-NLS-1$
+
+ public static FunctionParser getInstance(){
+ if (parser != null) {
+ return parser;
+ }
+ parser = new FunctionParser();
+ return parser;
+ }
+
+ private FunctionParser() {
+ super("Function Parser"); //$NON-NLS-1$
+ }
+
+ /**
+ * Returns the root node of the tree of functions generated by
+ * parseFiles. Functions are grouped by source file.
+ * @return A tree of tapset functions grouped by file.
+ */
+ public synchronized TreeNode getFunctions() {
+ return functions;
+ }
+
+ /**
+ * This method will clean up everything from the run.
+ */
+ public void dispose() {
+ functions.dispose();
+ }
+
+ @Override
+ protected IStatus run(IProgressMonitor monitor) {
+ boolean cancelled = runPass2Functions();
+ functions.sortTree();
+ fireUpdateEvent(); //Inform listeners that everything is done
+ return new Status(!cancelled ? IStatus.OK : IStatus.CANCEL, IDEPlugin.PLUGIN_ID, ""); //$NON-NLS-1$
+ }
+
+ /**
+ * This method is used to build up the list of functions that were found
+ * during the first pass of stap. Stap is invoked by: $stap -v -p1 -e
+ * 'probe begin{}' and parsing the output.
+ *
+ * FunctionTree organized as:
+ * Root->Functions->Parameters
+ *
+ * @return <code>false</code> if a cancellation prevented all probes from being added;
+ * <code>true</code> otherwise.
+ */
+ private boolean runPass2Functions() {
+ String tapsetContents = SharedParser.getInstance().getTapsetContents();
+ if (cancelRequested) {
+ return false;
+ }
+ // Create a new function tree each time, so as to not add duplicates
+ functions = new TreeNode("", false); //$NON-NLS-1$
+ if (tapsetContents == null) {
+ // Functions are only drawn from the tapset dump, so exit if it's empty.
+ return true;
+ }
+ try (Scanner st = new Scanner(tapsetContents)) {
+ String filename = null;
+ String scriptText = null;
+
+ SharedParser sparser = SharedParser.getInstance();
+ while (st.hasNextLine()) {
+ if (cancelRequested) {
+ return false;
+ }
+ String tok = st.nextLine();
+ Matcher mFilename = sparser.filePattern.matcher(tok);
+ if (mFilename.matches()) {
+ filename = mFilename.group(1).toString();
+ scriptText = null;
+ } else if (filename != null) {
+ Matcher mFunction = pFunction.matcher(tok);
+ if (mFunction.matches()) {
+ String functionName = mFunction.group(1);
+ if (pAllCaps.matcher(functionName).matches()) {
+ // Ignore ALL_CAPS functions, since they are not meant for end-user use.
+ continue;
+ }
+ if (scriptText == null) {
+ // If this is the first time seeing this file, remove its comments.
+ scriptText = CommentRemover.execWithFile(filename);
+ }
+ addFunctionFromScript(functionName, scriptText, filename);
+ }
+ }
+ }
+ return true;
+ }
+ }
+
+ private void addFunctionFromScript(String functionName, String scriptText, String scriptFilename) {
+ String regex = MessageFormat.format(functionRegex, functionName);
+ Matcher mScript = Pattern.compile(regex).matcher(scriptText);
+ if (mScript.find()) {
+ String functionLine = mScript.group();
+ String functionType = mScript.group(1);
+ // If the function has no return type, look for a "return" statement to check
+ // if it's really a void function, or if its return type is just unspecified
+ if (functionType == null && getNextBlockContents(scriptText, mScript.end(), pReturn)) {
+ functionType = UNKNOWN_TYPE;
+ }
+ TreeDefinitionNode function = new TreeDefinitionNode(
+ new FunctionNodeData(functionLine, functionType),
+ functionName, scriptFilename, true);
+ functions.add(function);
+ addParamsFromString(mScript.group(2), function);
+ }
+ }
+
+ private boolean getNextBlockContents(String scriptText, int start, Pattern p) {
+ int end, bcount = 1;
+ start = scriptText.indexOf('{', start) + 1;
+ for (end = start; end < scriptText.length(); end++) {
+ char c = scriptText.charAt(end);
+ if (c == '{') {
+ bcount++;
+ } else if (c == '}' && --bcount == 0) {
+ break;
+ }
+ }
+ return p.matcher(scriptText.substring(start, end)).find();
+ }
+
+ private void addParamsFromString(String params, TreeNode parentFunction) {
+ if (params != null) {
+ Matcher mParams = pParams.matcher(params);
+ while (mParams.find()) {
+ parentFunction.add(new TreeNode(
+ new FuncparamNodeData(mParams.group(), mParams.group(2)),
+ mParams.group(1), false));
+ }
+ }
+ }
}
diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/ISearchableNode.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/ISearchableNode.java
index 3f4d38afad..e207e1e58a 100644
--- a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/ISearchableNode.java
+++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/ISearchableNode.java
@@ -12,6 +12,6 @@
package org.eclipse.linuxtools.internal.systemtap.ui.ide.structures;
public interface ISearchableNode {
- String getSearchToken();
- boolean isRegexSearch();
+ String getSearchToken();
+ boolean isRegexSearch();
}
diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/ISingleTypedNode.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/ISingleTypedNode.java
index de90470e71..94d5f7b161 100644
--- a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/ISingleTypedNode.java
+++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/ISingleTypedNode.java
@@ -12,5 +12,5 @@
package org.eclipse.linuxtools.internal.systemtap.ui.ide.structures;
public interface ISingleTypedNode {
- String getType();
+ String getType();
}
diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/Messages.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/Messages.java
index 7c1a611396..64e8b9a515 100644
--- a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/Messages.java
+++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/Messages.java
@@ -16,18 +16,18 @@ import org.eclipse.osgi.util.NLS;
* @since 2.0
*/
public class Messages extends NLS {
- private static final String BUNDLE_NAME = "org.eclipse.linuxtools.internal.systemtap.ui.ide.structures.messages"; //$NON-NLS-1$
- public static String ProbeParser_errorInitializingStaticProbes;
- public static String ProbeParser_staticProbes;
- public static String ProbeParser_aliasProbes;
- public static String TapsetParser_CannotRunStapMessage;
- public static String TapsetParser_CannotRunStapTitle;
- public static String TapsetParser_ErrorRunningSystemtap;
- static {
- // initialize resource bundle
- NLS.initializeMessages(BUNDLE_NAME, Messages.class);
- }
+ private static final String BUNDLE_NAME = "org.eclipse.linuxtools.internal.systemtap.ui.ide.structures.messages"; //$NON-NLS-1$
+ public static String ProbeParser_errorInitializingStaticProbes;
+ public static String ProbeParser_staticProbes;
+ public static String ProbeParser_aliasProbes;
+ public static String TapsetParser_CannotRunStapMessage;
+ public static String TapsetParser_CannotRunStapTitle;
+ public static String TapsetParser_ErrorRunningSystemtap;
+ static {
+ // initialize resource bundle
+ NLS.initializeMessages(BUNDLE_NAME, Messages.class);
+ }
- private Messages() {
- }
+ private Messages() {
+ }
}
diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/ProbeNodeData.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/ProbeNodeData.java
index 20e7f050cc..0fd3204b42 100644
--- a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/ProbeNodeData.java
+++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/ProbeNodeData.java
@@ -15,35 +15,35 @@ import java.text.MessageFormat;
public class ProbeNodeData implements ISearchableNode {
- private final String name;
-
- @Override
- public boolean isRegexSearch() {
- return true;
- }
-
- /**
- * @return a regex to search a file with for the definition of this probe.
- */
- @Override
- public String getSearchToken() {
- return MessageFormat.format(ProbeParser.probeRegex, name);
- }
-
- @Override
- public String toString() {
- return getSearchToken();
- }
-
- /**
- * Create a new instance of probe node information.
- * @param line A line of text generated by running "stap -L" which
- * provides all information pertaining to a probe point, or at least
- * the probe's name.
- */
- public ProbeNodeData(String line) {
- int spaceIndex = line.indexOf(' ');
- name = (spaceIndex != -1 ? line.substring(0, spaceIndex) : line).trim();
- }
+ private final String name;
+
+ @Override
+ public boolean isRegexSearch() {
+ return true;
+ }
+
+ /**
+ * @return a regex to search a file with for the definition of this probe.
+ */
+ @Override
+ public String getSearchToken() {
+ return MessageFormat.format(ProbeParser.probeRegex, name);
+ }
+
+ @Override
+ public String toString() {
+ return getSearchToken();
+ }
+
+ /**
+ * Create a new instance of probe node information.
+ * @param line A line of text generated by running "stap -L" which
+ * provides all information pertaining to a probe point, or at least
+ * the probe's name.
+ */
+ public ProbeNodeData(String line) {
+ int spaceIndex = line.indexOf(' ');
+ name = (spaceIndex != -1 ? line.substring(0, spaceIndex) : line).trim();
+ }
}
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 1ea2da3701..2acd6ba4e7 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
@@ -34,263 +34,263 @@ import org.eclipse.linuxtools.systemtap.structures.TreeNode;
*/
public class ProbeParser extends TapsetParser {
- static final String probeRegex = "(?s)(?<!\\w)probe\\s+{0}\\s*\\+?="; //$NON-NLS-1$
- private static final String tapsetProbeRegex = "probe {0} \\+?="; //$NON-NLS-1$
-
- private TreeNode probes;
- private TreeNode statics;
- private TreeNode aliases;
-
- static ProbeParser parser = null;
- public static ProbeParser getInstance(){
- if (parser != null) {
- return parser;
- }
- parser = new ProbeParser();
- return parser;
- }
-
- private ProbeParser() {
- super("Probe Parser"); //$NON-NLS-1$
- }
-
- /**
- * Returns the root node of the tree of the probe alias generated by
- * parseFiles. Probes are grouped by target location.
- * @return A tree of tapset probe aliases grouped by probe location.
- */
- public synchronized TreeNode getProbes() {
- return probes;
- }
-
- /**
- * This method will clean up everything from the run.
- */
- public void dispose() {
- probes.dispose();
- statics.dispose();
- aliases.dispose();
- }
-
- @Override
- protected IStatus run(IProgressMonitor monitor) {
- // Create a new function tree each time, so as to not add duplicates.
- reset();
-
- addStaticProbes();
- if (cancelRequested){
- return new Status(IStatus.CANCEL, IDEPlugin.PLUGIN_ID, ""); //$NON-NLS-1$
- }
- boolean cancelled = addProbeAliases(collect(null));
- constructRootTree();
- fireUpdateEvent(); //Inform listeners that everything is done
- return new Status(!cancelled ? IStatus.OK : IStatus.CANCEL, IDEPlugin.PLUGIN_ID, ""); //$NON-NLS-1$
- }
-
- private void reset() {
- probes = new TreeNode("", false); //$NON-NLS-1$
- statics = new TreeNode(Messages.ProbeParser_staticProbes, false);
- aliases = new TreeNode(Messages.ProbeParser_aliasProbes, false);
- }
-
- private void constructRootTree() {
- statics.sortTree();
- aliases.sortTree();
- probes.add(statics);
- probes.add(aliases);
- }
-
- /**
- * Returns a String containing all of the content from the probe
- * point list, including variables and their type.
- *
- * stap -L
- * Will list all available probe points
- * @return the probe points consolidated into a single string
- */
- private String collect(String script) {
- String[] options;
- if(null == script) {
- script = "**"; //$NON-NLS-1$
- options = new String[] {"-L"}; //$NON-NLS-1$
- } else {
- options = null;
- }
-
- String s = runStap(options, script, false);
- if (s == null) {
- return ""; //$NON-NLS-1$
- }
-
- return s;
- }
-
- private boolean addStaticProbes() {
- String s = runStap(new String[]{"--dump-probe-types"}, null, false); //$NON-NLS-1$
- TreeNode group = null;
- try (Scanner st = new Scanner(s)) {
- while(st.hasNextLine()) {
- if (cancelRequested) {
- return false;
- }
- String tokenString = st.nextLine();
- String probeName = (new StringTokenizer(tokenString)).nextToken();
- group = addOrFindProbeGroup(extractProbeGroupName(probeName), group, statics);
- group.add(makeStaticProbeNode(probeName));
- }
- return true;
- }
- }
-
- /**
- * Parses the output generated from running stap -L. Pulls out all functions
- * and probe aliases from the provided string. Populates the probe tree.
- *
- * ProbeTree organized as:
- * Root->Named Groups->ProbePoints->Variables
- *
- * @param probeDump A list of probe points with the same formatting used by stap -L.
- * @return <code>false</code> if a cancellation prevented all probes from being added;
- * <code>true</code> otherwise.
- */
- private boolean addProbeAliases(String probeDump) {
- TreeNode group = null;
- try (Scanner st = new Scanner(probeDump)) {
- while(st.hasNextLine()) {
- if (cancelRequested) {
- return false;
- }
- String tokenString = st.nextLine();
- // If the token starts with '_' or '__' it is a private probe so
- // skip it.
- if (tokenString.startsWith("_")) { //$NON-NLS-1$
- continue;
- }
-
- StringTokenizer probeTokenizer = new StringTokenizer(tokenString);
- String probeName = probeTokenizer.nextToken();
-
- String groupName = extractProbeGroupName(tokenString);
- if (!isStaticProbeGroup(groupName)) {
- TreeNode probeNode = makeProbeAliasNode(probeName);
- group = addOrFindProbeGroup(groupName, group, aliases);
- group.add(probeNode);
- addAllVarNodesToProbeNode(probeTokenizer, probeNode);
- }
- }
- return true;
- }
- }
-
- /**
- * Find 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 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.
- if(groupNode == null || !groupNode.toString().equals(groupName)) {
- groupNode = category.getChildByName(groupName);
- }
-
- // Create a new group and add it
- if(groupNode == null) {
- groupNode = new TreeNode(groupName, true);
- category.add(groupNode);
- }
- return groupNode;
- }
-
- /**
- * @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;
- }
-
- 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 boolean isStaticProbeGroup(String groupName) {
- return statics.getChildByName(groupName) != null;
- }
-
- /**
- * Search 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();
- Matcher probeMatcher = Pattern.compile(MessageFormat.format(tapsetProbeRegex, Pattern.quote(probeName))).matcher(tapsetContents);
- if (!probeMatcher.find()) {
- return null;
- }
- 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;
- }
- }
-
- /**
- * Extracts the local variables from a (partially examined) probe alias token, and
- * adds them as child tree entries of their parent probe.
- */
- private void addAllVarNodesToProbeNode(StringTokenizer varTokenizer, TreeNode probeNode) {
- StringBuilder prev = new StringBuilder(""); //$NON-NLS-1$
- // the remaining tokens are variable names and variable types name:type.
- while(varTokenizer.hasMoreTokens()){
- String token = varTokenizer.nextToken();
-
- // Because some variable types contain spaces (var2:struct task_struct)
- // the only way to know if we have the entire string representing a
- // variable is if we reach the next token containing a ':' or we reach
- // the end of the stream.
- if (token.contains(":") && prev.length() > 0){ //$NON-NLS-1$
- prev.setLength(prev.length() - 1); // Remove the trailing space.
- addVarNodeToProbeNode(prev.toString(), probeNode);
- prev.setLength(0);
- }
- prev.append(token + " "); //$NON-NLS-1$
- }
-
- // Add the last token if there is one
- if (prev.length() > 0){
- prev.setLength(prev.length() - 1); // Remove the trailing space.
- addVarNodeToProbeNode(prev.toString(), probeNode);
- }
- }
-
- private void addVarNodeToProbeNode(String info, TreeNode probeNode) {
- probeNode.add(new TreeNode(new ProbevarNodeData(info), info, false));
- }
+ static final String probeRegex = "(?s)(?<!\\w)probe\\s+{0}\\s*\\+?="; //$NON-NLS-1$
+ private static final String tapsetProbeRegex = "probe {0} \\+?="; //$NON-NLS-1$
+
+ private TreeNode probes;
+ private TreeNode statics;
+ private TreeNode aliases;
+
+ static ProbeParser parser = null;
+ public static ProbeParser getInstance(){
+ if (parser != null) {
+ return parser;
+ }
+ parser = new ProbeParser();
+ return parser;
+ }
+
+ private ProbeParser() {
+ super("Probe Parser"); //$NON-NLS-1$
+ }
+
+ /**
+ * Returns the root node of the tree of the probe alias generated by
+ * parseFiles. Probes are grouped by target location.
+ * @return A tree of tapset probe aliases grouped by probe location.
+ */
+ public synchronized TreeNode getProbes() {
+ return probes;
+ }
+
+ /**
+ * This method will clean up everything from the run.
+ */
+ public void dispose() {
+ probes.dispose();
+ statics.dispose();
+ aliases.dispose();
+ }
+
+ @Override
+ protected IStatus run(IProgressMonitor monitor) {
+ // Create a new function tree each time, so as to not add duplicates.
+ reset();
+
+ addStaticProbes();
+ if (cancelRequested){
+ return new Status(IStatus.CANCEL, IDEPlugin.PLUGIN_ID, ""); //$NON-NLS-1$
+ }
+ boolean cancelled = addProbeAliases(collect(null));
+ constructRootTree();
+ fireUpdateEvent(); //Inform listeners that everything is done
+ return new Status(!cancelled ? IStatus.OK : IStatus.CANCEL, IDEPlugin.PLUGIN_ID, ""); //$NON-NLS-1$
+ }
+
+ private void reset() {
+ probes = new TreeNode("", false); //$NON-NLS-1$
+ statics = new TreeNode(Messages.ProbeParser_staticProbes, false);
+ aliases = new TreeNode(Messages.ProbeParser_aliasProbes, false);
+ }
+
+ private void constructRootTree() {
+ statics.sortTree();
+ aliases.sortTree();
+ probes.add(statics);
+ probes.add(aliases);
+ }
+
+ /**
+ * Returns a String containing all of the content from the probe
+ * point list, including variables and their type.
+ *
+ * stap -L
+ * Will list all available probe points
+ * @return the probe points consolidated into a single string
+ */
+ private String collect(String script) {
+ String[] options;
+ if(null == script) {
+ script = "**"; //$NON-NLS-1$
+ options = new String[] {"-L"}; //$NON-NLS-1$
+ } else {
+ options = null;
+ }
+
+ String s = runStap(options, script, false);
+ if (s == null) {
+ return ""; //$NON-NLS-1$
+ }
+
+ return s;
+ }
+
+ private boolean addStaticProbes() {
+ String s = runStap(new String[]{"--dump-probe-types"}, null, false); //$NON-NLS-1$
+ TreeNode group = null;
+ try (Scanner st = new Scanner(s)) {
+ while(st.hasNextLine()) {
+ if (cancelRequested) {
+ return false;
+ }
+ String tokenString = st.nextLine();
+ String probeName = (new StringTokenizer(tokenString)).nextToken();
+ group = addOrFindProbeGroup(extractProbeGroupName(probeName), group, statics);
+ group.add(makeStaticProbeNode(probeName));
+ }
+ return true;
+ }
+ }
+
+ /**
+ * Parses the output generated from running stap -L. Pulls out all functions
+ * and probe aliases from the provided string. Populates the probe tree.
+ *
+ * ProbeTree organized as:
+ * Root->Named Groups->ProbePoints->Variables
+ *
+ * @param probeDump A list of probe points with the same formatting used by stap -L.
+ * @return <code>false</code> if a cancellation prevented all probes from being added;
+ * <code>true</code> otherwise.
+ */
+ private boolean addProbeAliases(String probeDump) {
+ TreeNode group = null;
+ try (Scanner st = new Scanner(probeDump)) {
+ while(st.hasNextLine()) {
+ if (cancelRequested) {
+ return false;
+ }
+ String tokenString = st.nextLine();
+ // If the token starts with '_' or '__' it is a private probe so
+ // skip it.
+ if (tokenString.startsWith("_")) { //$NON-NLS-1$
+ continue;
+ }
+
+ StringTokenizer probeTokenizer = new StringTokenizer(tokenString);
+ String probeName = probeTokenizer.nextToken();
+
+ String groupName = extractProbeGroupName(tokenString);
+ if (!isStaticProbeGroup(groupName)) {
+ TreeNode probeNode = makeProbeAliasNode(probeName);
+ group = addOrFindProbeGroup(groupName, group, aliases);
+ group.add(probeNode);
+ addAllVarNodesToProbeNode(probeTokenizer, probeNode);
+ }
+ }
+ return true;
+ }
+ }
+
+ /**
+ * Find 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 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.
+ if(groupNode == null || !groupNode.toString().equals(groupName)) {
+ groupNode = category.getChildByName(groupName);
+ }
+
+ // Create a new group and add it
+ if(groupNode == null) {
+ groupNode = new TreeNode(groupName, true);
+ category.add(groupNode);
+ }
+ return groupNode;
+ }
+
+ /**
+ * @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;
+ }
+
+ 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 boolean isStaticProbeGroup(String groupName) {
+ return statics.getChildByName(groupName) != null;
+ }
+
+ /**
+ * Search 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();
+ Matcher probeMatcher = Pattern.compile(MessageFormat.format(tapsetProbeRegex, Pattern.quote(probeName))).matcher(tapsetContents);
+ if (!probeMatcher.find()) {
+ return null;
+ }
+ 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;
+ }
+ }
+
+ /**
+ * Extracts the local variables from a (partially examined) probe alias token, and
+ * adds them as child tree entries of their parent probe.
+ */
+ private void addAllVarNodesToProbeNode(StringTokenizer varTokenizer, TreeNode probeNode) {
+ StringBuilder prev = new StringBuilder(""); //$NON-NLS-1$
+ // the remaining tokens are variable names and variable types name:type.
+ while(varTokenizer.hasMoreTokens()){
+ String token = varTokenizer.nextToken();
+
+ // Because some variable types contain spaces (var2:struct task_struct)
+ // the only way to know if we have the entire string representing a
+ // variable is if we reach the next token containing a ':' or we reach
+ // the end of the stream.
+ if (token.contains(":") && prev.length() > 0){ //$NON-NLS-1$
+ prev.setLength(prev.length() - 1); // Remove the trailing space.
+ addVarNodeToProbeNode(prev.toString(), probeNode);
+ prev.setLength(0);
+ }
+ prev.append(token + " "); //$NON-NLS-1$
+ }
+
+ // Add the last token if there is one
+ if (prev.length() > 0){
+ prev.setLength(prev.length() - 1); // Remove the trailing space.
+ addVarNodeToProbeNode(prev.toString(), probeNode);
+ }
+ }
+
+ private void addVarNodeToProbeNode(String info, TreeNode probeNode) {
+ probeNode.add(new TreeNode(new ProbevarNodeData(info), info, false));
+ }
}
diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/ProbevarNodeData.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/ProbevarNodeData.java
index cb3efdb36a..bcb0208ead 100644
--- a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/ProbevarNodeData.java
+++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/ProbevarNodeData.java
@@ -20,47 +20,47 @@ import java.util.List;
* @since 3.0
*/
public class ProbevarNodeData {
- private String text;
- private String name;
- private List<String> types;
+ private String text;
+ private String name;
+ private List<String> types;
- /**
- * @return The original line of text passed to this object, which contains the
- * variable's name and its full type.
- */
- @Override
- public String toString() {
- return text;
- }
+ /**
+ * @return The original line of text passed to this object, which contains the
+ * variable's name and its full type.
+ */
+ @Override
+ public String toString() {
+ return text;
+ }
- /**
- * @return The name of the variable.
- */
- public String getName() {
- return name;
- }
+ /**
+ * @return The name of the variable.
+ */
+ public String getName() {
+ return name;
+ }
- /**
- * @return A list of all tokens used to describe the variable's type.
- */
- public List<String> getTypes() {
- return types;
- }
+ /**
+ * @return A list of all tokens used to describe the variable's type.
+ */
+ public List<String> getTypes() {
+ return types;
+ }
- /**
- * Create a new instance of probe variable node information.
- * @param line A line of text generated by running "stap -L" which
- * provides all information pertaining to a probe point.
- */
- public ProbevarNodeData(String line) {
- text = line.trim();
- int colonIndex = text.indexOf(':');
- if (colonIndex == -1) {
- name = text;
- types = Collections.emptyList();
- } else {
- name = line.substring(0, colonIndex);
- types = Arrays.asList(text.substring(colonIndex+1).split(" ")); //$NON-NLS-1$
- }
- }
+ /**
+ * Create a new instance of probe variable node information.
+ * @param line A line of text generated by running "stap -L" which
+ * provides all information pertaining to a probe point.
+ */
+ public ProbevarNodeData(String line) {
+ text = line.trim();
+ int colonIndex = text.indexOf(':');
+ if (colonIndex == -1) {
+ name = text;
+ types = Collections.emptyList();
+ } else {
+ name = line.substring(0, colonIndex);
+ types = Arrays.asList(text.substring(colonIndex+1).split(" ")); //$NON-NLS-1$
+ }
+ }
}
diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/SharedParser.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/SharedParser.java
index 0571f39d09..4c4dfeffd8 100644
--- a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/SharedParser.java
+++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/SharedParser.java
@@ -20,57 +20,57 @@ import org.eclipse.linuxtools.internal.systemtap.ui.ide.IDEPlugin;
public class SharedParser extends TapsetParser {
- static final String TAG_FILE = "# file"; //$NON-NLS-1$
- /**
- * A pattern that can be used to locate file paths listed in stap tapset dumps.
- */
- final Pattern filePattern = Pattern.compile("# file (/.*\\.stp)"); //$NON-NLS-1$
+ static final String TAG_FILE = "# file"; //$NON-NLS-1$
+ /**
+ * A pattern that can be used to locate file paths listed in stap tapset dumps.
+ */
+ final Pattern filePattern = Pattern.compile("# file (/.*\\.stp)"); //$NON-NLS-1$
- private String tapsetContents = null;
+ private String tapsetContents = null;
- static SharedParser parser = null;
- public static SharedParser getInstance(){
- if (parser != null) {
- return parser;
- }
- parser = new SharedParser();
- return parser;
- }
+ static SharedParser parser = null;
+ public static SharedParser getInstance(){
+ if (parser != null) {
+ return parser;
+ }
+ parser = new SharedParser();
+ return parser;
+ }
- private SharedParser() {
- super("Shared Parser"); //$NON-NLS-1$
- }
+ private SharedParser() {
+ super("Shared Parser"); //$NON-NLS-1$
+ }
- /**
- * Clear the cached tapset contents, so that the next call to {@link #getTapsetContents()}
- * will be guaranteed to use a new call of stap to gather up-to-date tapset contents.
- */
- synchronized void clearTapsetContents() {
- tapsetContents = null;
- }
+ /**
+ * Clear the cached tapset contents, so that the next call to {@link #getTapsetContents()}
+ * will be guaranteed to use a new call of stap to gather up-to-date tapset contents.
+ */
+ synchronized void clearTapsetContents() {
+ tapsetContents = null;
+ }
- /**
- * Get the contents of default & all imported tapsets. When calling this method
- * for the first time (or after changing the list of tapset directories), this will
- * run a dummy stap script to obtain the tapset contents, which will be cached into
- * memory. Subsequent calls will simply read the saved contents.
- * @return The string contents of tapsets, or <code>null</code> if there was an
- * error in obtaining this information.
- */
- synchronized String getTapsetContents() {
- if (tapsetContents == null) {
- run(null);
- }
- return tapsetContents;
- }
+ /**
+ * Get the contents of default & all imported tapsets. When calling this method
+ * for the first time (or after changing the list of tapset directories), this will
+ * run a dummy stap script to obtain the tapset contents, which will be cached into
+ * memory. Subsequent calls will simply read the saved contents.
+ * @return The string contents of tapsets, or <code>null</code> if there was an
+ * error in obtaining this information.
+ */
+ synchronized String getTapsetContents() {
+ if (tapsetContents == null) {
+ run(null);
+ }
+ return tapsetContents;
+ }
- @Override
- protected IStatus run(IProgressMonitor monitor) {
- tapsetContents = runStap(new String[] {"-v", "-p1", "-e"}, "probe begin{}", false); //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$//$NON-NLS-4$
- // Exclude the dump of the test script by excluding everything before the second pathname
- // (which is the first actual tapset file, not the input script).
- tapsetContents = tapsetContents.substring(tapsetContents.indexOf(TAG_FILE, tapsetContents.indexOf(TAG_FILE)+1));
- return new Status(IStatus.OK, IDEPlugin.PLUGIN_ID, ""); //$NON-NLS-1$
- }
+ @Override
+ protected IStatus run(IProgressMonitor monitor) {
+ tapsetContents = runStap(new String[] {"-v", "-p1", "-e"}, "probe begin{}", false); //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$//$NON-NLS-4$
+ // Exclude the dump of the test script by excluding everything before the second pathname
+ // (which is the first actual tapset file, not the input script).
+ tapsetContents = tapsetContents.substring(tapsetContents.indexOf(TAG_FILE, tapsetContents.indexOf(TAG_FILE)+1));
+ return new Status(IStatus.OK, IDEPlugin.PLUGIN_ID, ""); //$NON-NLS-1$
+ }
}
diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/StapErrorParser.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/StapErrorParser.java
index f0de0199a1..c8771976b3 100644
--- a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/StapErrorParser.java
+++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/StapErrorParser.java
@@ -22,66 +22,66 @@ import org.eclipse.linuxtools.systemtap.ui.consolelog.structures.IErrorParser;
* @author Ryan Morse
*/
public final class StapErrorParser implements IErrorParser {
- /**
- * Parses the error log passed in into a table of strings.
- * @param output The output from the stderr StreamGobbler.
- * @return A table of strings in the proper format to be displayed in the error log.
- */
- @Override
- public String[][] parseOutput(String output) {
- String[][] sErrors = null;
- ArrayList<String[]> errors = new ArrayList<>();
- int errorType = TYPE;
+ /**
+ * Parses the error log passed in into a table of strings.
+ * @param output The output from the stderr StreamGobbler.
+ * @return A table of strings in the proper format to be displayed in the error log.
+ */
+ @Override
+ public String[][] parseOutput(String output) {
+ String[][] sErrors = null;
+ ArrayList<String[]> errors = new ArrayList<>();
+ int errorType = TYPE;
- if(null != output) {
- String[] tokens = output.split("\\s"); //$NON-NLS-1$
- String[] row = null;
+ if(null != output) {
+ String[] tokens = output.split("\\s"); //$NON-NLS-1$
+ String[] row = null;
- for(int i=0; i<tokens.length; i++) {
- if(tokens[i].equals("error:")) { //$NON-NLS-1$
- row = new String[] {"", "", "", ""}; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$//$NON-NLS-4$
- errors.add(row);
- row[TYPE] = tokens[i-1] + " " + tokens[i]; //$NON-NLS-1$
- errorType = ERROR;
- i++;
- } else if(tokens[i].equals("saw:")) { //$NON-NLS-1$
- errorType = SAW;
- i++;
- } else if(tokens[i].equals("at")) { //$NON-NLS-1$
- errorType = LOCATION;
- i++;
- } else if(tokens[i].equals("Pass")) { //$NON-NLS-1$
- errorType = PASS;
+ for(int i=0; i<tokens.length; i++) {
+ if(tokens[i].equals("error:")) { //$NON-NLS-1$
+ row = new String[] {"", "", "", ""}; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$//$NON-NLS-4$
+ errors.add(row);
+ row[TYPE] = tokens[i-1] + " " + tokens[i]; //$NON-NLS-1$
+ errorType = ERROR;
+ i++;
+ } else if(tokens[i].equals("saw:")) { //$NON-NLS-1$
+ errorType = SAW;
+ i++;
+ } else if(tokens[i].equals("at")) { //$NON-NLS-1$
+ errorType = LOCATION;
+ i++;
+ } else if(tokens[i].equals("Pass")) { //$NON-NLS-1$
+ errorType = PASS;
- }
+ }
- if (null != row && errorType != PASS) {
- row[errorType] += tokens[i] + " "; //$NON-NLS-1$
- }
- }
+ if (null != row && errorType != PASS) {
+ row[errorType] += tokens[i] + " "; //$NON-NLS-1$
+ }
+ }
- sErrors = new String[errors.size()][4];
- System.arraycopy(errors.toArray(), 0, sErrors, 0, errors.size());
+ sErrors = new String[errors.size()][4];
+ System.arraycopy(errors.toArray(), 0, sErrors, 0, errors.size());
- for(int i=0; i<sErrors.length; i++)
- sErrors[i][LOCATION] = fixLocation(sErrors[i][LOCATION]);
- }
+ for(int i=0; i<sErrors.length; i++)
+ sErrors[i][LOCATION] = fixLocation(sErrors[i][LOCATION]);
+ }
- return sErrors;
- }
+ return sErrors;
+ }
- private static String fixLocation(String loc) {
- if(loc.contains(":")) { //$NON-NLS-1$
- loc = loc.substring(loc.indexOf(':')+1, loc.lastIndexOf(':'));
- return loc;
- } else {
- return ""; //$NON-NLS-1$
- }
- }
+ private static String fixLocation(String loc) {
+ if(loc.contains(":")) { //$NON-NLS-1$
+ loc = loc.substring(loc.indexOf(':')+1, loc.lastIndexOf(':'));
+ return loc;
+ } else {
+ return ""; //$NON-NLS-1$
+ }
+ }
- private static final int TYPE = 0;
- private static final int ERROR = 1;
- private static final int SAW = 2;
- private static final int LOCATION = 3;
- private static final int PASS = 4;
+ private static final int TYPE = 0;
+ private static final int ERROR = 1;
+ private static final int SAW = 2;
+ private static final int LOCATION = 3;
+ private static final int PASS = 4;
}
diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/TapsetLibrary.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/TapsetLibrary.java
index d56b9f20ba..c89c9857ff 100644
--- a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/TapsetLibrary.java
+++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/TapsetLibrary.java
@@ -43,372 +43,372 @@ import org.eclipse.ui.PlatformUI;
*/
public final class TapsetLibrary {
- private static TreeNode functionTree = null;
- private static TreeNode probeTree = null;
-
- private static FunctionParser functionParser = null;
- private static ProbeParser probeParser = null;
-
- public static TreeNode getProbes() {
- return probeTree;
- }
-
- public static TreeNode getStaticProbes() {
- return probeTree == null ? null : probeTree.getChildByName(Messages.ProbeParser_staticProbes);
- }
-
- public static TreeNode getProbeAliases() {
- return probeTree == null ? null : probeTree.getChildByName(Messages.ProbeParser_aliasProbes);
- }
-
- public static TreeNode getFunctions() {
- return functionTree;
- }
-
- private static HashMap<String, String> pages = new HashMap<>();
-
- /**
- * Returns the documentation for the given probe, function, or tapset.
- * @since 2.0
- */
- public static synchronized String getDocumentation(String element) {
- String documentation = pages.get(element);
- if (documentation == null) {
-
- // If the requested element is a probe variable
- // fetch the documentation for the parent probe then check the map
- if (element.matches("probe::.*::.*")) { //$NON-NLS-1$
- String probe = element.split("::")[1]; //$NON-NLS-1$
- getDocumentation("probe::" + probe); //$NON-NLS-1$
- return pages.get(element);
- }
-
- // Otherwise, get the documentation for the requested element.
- documentation = (new ManPage(element)).getStrippedTextPage().toString();
-
- // If the requested element is a probe and a documentation page was
- // found for it, parse the documentation for the variables if present.
- if (!documentation.startsWith("No manual entry for") && //$NON-NLS-1$
- element.startsWith("probe::")) { //$NON-NLS-1$
- // If this is a probe parse out the variables
- String[] sections = documentation.split("VALUES"); //$NON-NLS-1$
- if (sections.length > 1) {
- // Discard any other sections
- String variablesString = sections[1].split("CONTEXT|DESCRIPTION|SystemTap Tapset Reference")[0].trim(); //$NON-NLS-1$
- String[] variables = variablesString.split("\n"); //$NON-NLS-1$
- int i = 0;
- if (!variables[0].equals("None")) { //$NON-NLS-1$
- while ( i < variables.length) {
- String variableName = variables[i].trim();
- StringBuilder variableDocumentation = new StringBuilder();
- i++;
- while (i < variables.length && !variables[i].isEmpty()) {
- variableDocumentation.append(variables[i].trim());
- variableDocumentation.append("\n"); //$NON-NLS-1$
- i++;
- }
-
- pages.put(element + "::" + variableName, variableDocumentation.toString().trim()); //$NON-NLS-1$
- i++;
- }
- }
- }
- }
- }
- return documentation;
- }
-
- /**
- * Returns the documentation for the given element and caches the result. Use this
- * function if the given element is known to be a probe, function, or tapset.
- * @param element
- * @return
- * @since 2.0
- */
- public static synchronized String getAndCacheDocumentation(String element) {
- String doc = pages.get(element);
- if (doc == null) {
- doc = getDocumentation(element);
- pages.put(element, doc);
- }
- return doc;
- }
-
- private static IPropertyChangeListener propertyChangeListener = new IPropertyChangeListener() {
- @Override
- public void propertyChange(PropertyChangeEvent event) {
- if (event.getProperty().equals(IDEPreferenceConstants.P_TAPSETS)) {
- runStapParser();
- }
- }
- };
-
- /**
- * This method will attempt to get the most up-to-date information.
- * However, if the TapsetParser is running already it will quit,
- * assuming that new information will be available soon. By registering
- * a listener at that point the class can be notified when an update is
- * available.
- */
- public static void init() {
- if (null != functionParser && null != probeParser) {
- return;
- }
-
- IPreferenceStore preferenceStore = IDEPlugin.getDefault().getPreferenceStore();
- preferenceStore.addPropertyChangeListener(propertyChangeListener);
-
- if (preferenceStore.contains(IDEPreferenceConstants.P_STORED_TREE)
- && preferenceStore.getBoolean(IDEPreferenceConstants.P_STORED_TREE)
- && isTreeFileCurrent()) {
- readTreeFile();
- } else {
- runStapParser();
- }
- }
-
- /**
- * This method will create a new instance of the TapsetParser in order
- * to get the information directly from the files.
- */
- private static void runStapParser() {
- SharedParser.getInstance().clearTapsetContents();
-
- functionParser = FunctionParser.getInstance();
- functionParser.addListener(functionCompletionListener);
- functionParser.schedule();
-
- probeParser = ProbeParser.getInstance();
- probeParser.addListener(probeCompletionListener);
- probeParser.schedule();
- }
-
- /**
- * This method will get all of the tree information from
- * the TreeSettings xml file.
- */
- private static void readTreeFile() {
- functionTree = TreeSettings.getFunctionTree();
- probeTree = TreeSettings.getProbeTree();
- }
-
- /**
- * This method checks to see if the tapsets have changed
- * at all since the TreeSettings.xml file was created.
- * @return boolean indicating whether or not the TreeSettings.xml file has the most up-to-date version
- */
- private static boolean isTreeFileCurrent() {
- long treesDate = TreeSettings.getTreeFileDate();
-
- IPreferenceStore p = IDEPlugin.getDefault().getPreferenceStore();
- String[] tapsets = p.getString(IDEPreferenceConstants.P_TAPSETS).split(File.pathSeparator);
-
- File f = getTapsetLocation(p);
-
- if (!checkIsCurrentFolder(treesDate, f)) {
- return false;
- }
-
- for(int i=0; i<tapsets.length; i++) {
- f = new File(tapsets[i]);
- if (f.lastModified() > treesDate) {
- return false;
- }
- if (f.canRead() && !checkIsCurrentFolder(treesDate, f)) {
- return false;
- }
- }
- return true;
- }
-
- /**
- * This method attempts to locate the default tapset directory.
- * @param p Preference store where the tapset location might be stored
- * @return File representing the default tapset location.
- */
- public static File getTapsetLocation(IPreferenceStore p) {
- File f;
- String path = p.getString(PreferenceConstants.P_ENV[2][0]);
- if(path.trim().isEmpty()) {
- f = new File("/usr/share/systemtap/tapset"); //$NON-NLS-1$
- if(!f.exists()) {
- f = new File("/usr/local/share/systemtap/tapset"); //$NON-NLS-1$
- if(!f.exists()) {
- InputDialog i = new InputDialog(
- PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(),
- Localization.getString("TapsetBrowserView.TapsetLocation"), Localization.getString("TapsetBrowserView.WhereDefaultTapset"), "", null); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
- i.open();
- p.setValue(PreferenceConstants.P_ENV[2][0], i.getValue());
- f = new File( i.getValue() );
- }
- }
- } else {
- f = new File( p.getString(path) );
- }
- IDESessionSettings.tapsetLocation = f.getAbsolutePath();
- return f;
- }
-
- /**
- * This method checks the provided time stap against the folders
- * time stamp. This is to see if the folder may have new data in it
- * @param time The current time stamp
- * @param folder The folder to check if it is newer the then time stamp
- * @return boolean indicating whether the time stamp is newer then the folder
- */
- private static boolean checkIsCurrentFolder(long time, File folder) {
- File[] fs = folder.listFiles();
-
- for(int i=0; i<fs.length; i++) {
- if (fs[i].lastModified() > time) {
- return false;
- }
-
- if (fs[i].isDirectory() && fs[i].canRead()
- && !checkIsCurrentFolder(time, fs[i])) {
- return false;
- }
- }
- return true;
- }
-
- /**
- * Adds a new listener to the TapsetParser
- * @param listener the listener to be added
- * @return boolean indicating whether or not the listener was added
- * @since 2.0
- */
- public static boolean addFunctionListener(IUpdateListener listener) {
- if(null == functionParser) {
- return false;
- }
- functionParser.addListener(listener);
- return true;
- }
-
- /**
- * @since 2.0
- */
- public static boolean addProbeListener(IUpdateListener listener) {
- if(null == probeParser) {
- return false;
- }
- probeParser.addListener(listener);
- return true;
- }
-
- private static Job cacheFunctionManpages = new Job(Localization.getString("TapsetLibrary.0")) { //$NON-NLS-1$
- private boolean cancelled;
-
- @Override
- protected IStatus run(IProgressMonitor monitor) {
- TreeNode node = functionParser.getFunctions();
- int n = node.getChildCount();
- for (int i = 0; i < n && !this.cancelled; i++) {
- getAndCacheDocumentation("function::" + (node.getChildAt(i).toString())); //$NON-NLS-1$
- }
-
- return new Status(IStatus.OK, IDEPlugin.PLUGIN_ID, ""); //$NON-NLS-1$;
- }
-
- @Override
- protected void canceling() {
- this.cancelled = true;
- }
-
- };
-
- private static Job cacheProbeManpages = new Job(Localization.getString("TapsetLibrary.1")) { //$NON-NLS-1$
- @Override
- protected IStatus run(IProgressMonitor monitor) {
- TreeNode node = probeParser.getProbes();
- int n = node.getChildCount();
- for (int i = 0; i < n; i++) {
- getAndCacheDocumentation("tapset::" + (node.getChildAt(i).toString())); //$NON-NLS-1$
- // No need to pre-cache probes; they can be fetched pretty quickly.
- }
-
- return new Status(IStatus.OK, IDEPlugin.PLUGIN_ID, ""); //$NON-NLS-1$;
- }
- };
-
- private static final IUpdateListener functionCompletionListener = new IUpdateListener() {
- @Override
- public void handleUpdateEvent() {
- functionTree = functionParser.getFunctions();
- cacheFunctionManpages.schedule();
- TreeSettings.setTrees(functionTree, probeTree);
- synchronized (functionParser) {
- functionParser.notifyAll();
- }
- }
- };
-
- private static final IUpdateListener probeCompletionListener = new IUpdateListener() {
- @Override
- public void handleUpdateEvent() {
- probeTree = probeParser.getProbes();
- cacheProbeManpages.schedule();
- synchronized (probeParser) {
- probeParser.notifyAll();
- }
- }
- };
-
- /**
- * Blocks the current thread until the parser has finished
- * parsing probes and functions.
- * @since 2.0
- */
- public static void waitForInitialization() {
- while (functionParser.getResult() == null) {
- try {
- synchronized (functionParser) {
- functionParser.wait(5000);
- }
- } catch (InterruptedException e) {
- break;
- }
- }
- while (probeParser.getResult() == null) {
- try {
- synchronized (probeParser) {
- probeParser.wait(5000);
- }
- } catch (InterruptedException e) {
- break;
- }
- }
- }
-
- /**
- * This method will stop services started by
- * {@link TapsetLibrary#init()} such as the {@link TapsetParser}
- * @since 1.2
- */
- public static void stop() {
- if(null != functionParser) {
- functionParser.cancel();
- cacheFunctionManpages.cancel();
- try {
- functionParser.join();
- } catch (InterruptedException e) {
- // The current thread was interrupted while waiting
- // for the parser thread to exit. Nothing to do
- // continue stopping.
- }
- }
- if(probeParser != null) {
- probeParser.cancel();
- cacheProbeManpages.cancel();
- try {
- probeParser.join();
- } catch (InterruptedException e) {
- // The current thread was interrupted while waiting
- // for the parser thread to exit. Nothing to do
- // continue stopping.
- }
- }
-
- }
+ private static TreeNode functionTree = null;
+ private static TreeNode probeTree = null;
+
+ private static FunctionParser functionParser = null;
+ private static ProbeParser probeParser = null;
+
+ public static TreeNode getProbes() {
+ return probeTree;
+ }
+
+ public static TreeNode getStaticProbes() {
+ return probeTree == null ? null : probeTree.getChildByName(Messages.ProbeParser_staticProbes);
+ }
+
+ public static TreeNode getProbeAliases() {
+ return probeTree == null ? null : probeTree.getChildByName(Messages.ProbeParser_aliasProbes);
+ }
+
+ public static TreeNode getFunctions() {
+ return functionTree;
+ }
+
+ private static HashMap<String, String> pages = new HashMap<>();
+
+ /**
+ * Returns the documentation for the given probe, function, or tapset.
+ * @since 2.0
+ */
+ public static synchronized String getDocumentation(String element) {
+ String documentation = pages.get(element);
+ if (documentation == null) {
+
+ // If the requested element is a probe variable
+ // fetch the documentation for the parent probe then check the map
+ if (element.matches("probe::.*::.*")) { //$NON-NLS-1$
+ String probe = element.split("::")[1]; //$NON-NLS-1$
+ getDocumentation("probe::" + probe); //$NON-NLS-1$
+ return pages.get(element);
+ }
+
+ // Otherwise, get the documentation for the requested element.
+ documentation = (new ManPage(element)).getStrippedTextPage().toString();
+
+ // If the requested element is a probe and a documentation page was
+ // found for it, parse the documentation for the variables if present.
+ if (!documentation.startsWith("No manual entry for") && //$NON-NLS-1$
+ element.startsWith("probe::")) { //$NON-NLS-1$
+ // If this is a probe parse out the variables
+ String[] sections = documentation.split("VALUES"); //$NON-NLS-1$
+ if (sections.length > 1) {
+ // Discard any other sections
+ String variablesString = sections[1].split("CONTEXT|DESCRIPTION|SystemTap Tapset Reference")[0].trim(); //$NON-NLS-1$
+ String[] variables = variablesString.split("\n"); //$NON-NLS-1$
+ int i = 0;
+ if (!variables[0].equals("None")) { //$NON-NLS-1$
+ while ( i < variables.length) {
+ String variableName = variables[i].trim();
+ StringBuilder variableDocumentation = new StringBuilder();
+ i++;
+ while (i < variables.length && !variables[i].isEmpty()) {
+ variableDocumentation.append(variables[i].trim());
+ variableDocumentation.append("\n"); //$NON-NLS-1$
+ i++;
+ }
+
+ pages.put(element + "::" + variableName, variableDocumentation.toString().trim()); //$NON-NLS-1$
+ i++;
+ }
+ }
+ }
+ }
+ }
+ return documentation;
+ }
+
+ /**
+ * Returns the documentation for the given element and caches the result. Use this
+ * function if the given element is known to be a probe, function, or tapset.
+ * @param element
+ * @return
+ * @since 2.0
+ */
+ public static synchronized String getAndCacheDocumentation(String element) {
+ String doc = pages.get(element);
+ if (doc == null) {
+ doc = getDocumentation(element);
+ pages.put(element, doc);
+ }
+ return doc;
+ }
+
+ private static IPropertyChangeListener propertyChangeListener = new IPropertyChangeListener() {
+ @Override
+ public void propertyChange(PropertyChangeEvent event) {
+ if (event.getProperty().equals(IDEPreferenceConstants.P_TAPSETS)) {
+ runStapParser();
+ }
+ }
+ };
+
+ /**
+ * This method will attempt to get the most up-to-date information.
+ * However, if the TapsetParser is running already it will quit,
+ * assuming that new information will be available soon. By registering
+ * a listener at that point the class can be notified when an update is
+ * available.
+ */
+ public static void init() {
+ if (null != functionParser && null != probeParser) {
+ return;
+ }
+
+ IPreferenceStore preferenceStore = IDEPlugin.getDefault().getPreferenceStore();
+ preferenceStore.addPropertyChangeListener(propertyChangeListener);
+
+ if (preferenceStore.contains(IDEPreferenceConstants.P_STORED_TREE)
+ && preferenceStore.getBoolean(IDEPreferenceConstants.P_STORED_TREE)
+ && isTreeFileCurrent()) {
+ readTreeFile();
+ } else {
+ runStapParser();
+ }
+ }
+
+ /**
+ * This method will create a new instance of the TapsetParser in order
+ * to get the information directly from the files.
+ */
+ private static void runStapParser() {
+ SharedParser.getInstance().clearTapsetContents();
+
+ functionParser = FunctionParser.getInstance();
+ functionParser.addListener(functionCompletionListener);
+ functionParser.schedule();
+
+ probeParser = ProbeParser.getInstance();
+ probeParser.addListener(probeCompletionListener);
+ probeParser.schedule();
+ }
+
+ /**
+ * This method will get all of the tree information from
+ * the TreeSettings xml file.
+ */
+ private static void readTreeFile() {
+ functionTree = TreeSettings.getFunctionTree();
+ probeTree = TreeSettings.getProbeTree();
+ }
+
+ /**
+ * This method checks to see if the tapsets have changed
+ * at all since the TreeSettings.xml file was created.
+ * @return boolean indicating whether or not the TreeSettings.xml file has the most up-to-date version
+ */
+ private static boolean isTreeFileCurrent() {
+ long treesDate = TreeSettings.getTreeFileDate();
+
+ IPreferenceStore p = IDEPlugin.getDefault().getPreferenceStore();
+ String[] tapsets = p.getString(IDEPreferenceConstants.P_TAPSETS).split(File.pathSeparator);
+
+ File f = getTapsetLocation(p);
+
+ if (!checkIsCurrentFolder(treesDate, f)) {
+ return false;
+ }
+
+ for(int i=0; i<tapsets.length; i++) {
+ f = new File(tapsets[i]);
+ if (f.lastModified() > treesDate) {
+ return false;
+ }
+ if (f.canRead() && !checkIsCurrentFolder(treesDate, f)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * This method attempts to locate the default tapset directory.
+ * @param p Preference store where the tapset location might be stored
+ * @return File representing the default tapset location.
+ */
+ public static File getTapsetLocation(IPreferenceStore p) {
+ File f;
+ String path = p.getString(PreferenceConstants.P_ENV[2][0]);
+ if(path.trim().isEmpty()) {
+ f = new File("/usr/share/systemtap/tapset"); //$NON-NLS-1$
+ if(!f.exists()) {
+ f = new File("/usr/local/share/systemtap/tapset"); //$NON-NLS-1$
+ if(!f.exists()) {
+ InputDialog i = new InputDialog(
+ PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(),
+ Localization.getString("TapsetBrowserView.TapsetLocation"), Localization.getString("TapsetBrowserView.WhereDefaultTapset"), "", null); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ i.open();
+ p.setValue(PreferenceConstants.P_ENV[2][0], i.getValue());
+ f = new File( i.getValue() );
+ }
+ }
+ } else {
+ f = new File( p.getString(path) );
+ }
+ IDESessionSettings.tapsetLocation = f.getAbsolutePath();
+ return f;
+ }
+
+ /**
+ * This method checks the provided time stap against the folders
+ * time stamp. This is to see if the folder may have new data in it
+ * @param time The current time stamp
+ * @param folder The folder to check if it is newer the then time stamp
+ * @return boolean indicating whether the time stamp is newer then the folder
+ */
+ private static boolean checkIsCurrentFolder(long time, File folder) {
+ File[] fs = folder.listFiles();
+
+ for(int i=0; i<fs.length; i++) {
+ if (fs[i].lastModified() > time) {
+ return false;
+ }
+
+ if (fs[i].isDirectory() && fs[i].canRead()
+ && !checkIsCurrentFolder(time, fs[i])) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Adds a new listener to the TapsetParser
+ * @param listener the listener to be added
+ * @return boolean indicating whether or not the listener was added
+ * @since 2.0
+ */
+ public static boolean addFunctionListener(IUpdateListener listener) {
+ if(null == functionParser) {
+ return false;
+ }
+ functionParser.addListener(listener);
+ return true;
+ }
+
+ /**
+ * @since 2.0
+ */
+ public static boolean addProbeListener(IUpdateListener listener) {
+ if(null == probeParser) {
+ return false;
+ }
+ probeParser.addListener(listener);
+ return true;
+ }
+
+ private static Job cacheFunctionManpages = new Job(Localization.getString("TapsetLibrary.0")) { //$NON-NLS-1$
+ private boolean cancelled;
+
+ @Override
+ protected IStatus run(IProgressMonitor monitor) {
+ TreeNode node = functionParser.getFunctions();
+ int n = node.getChildCount();
+ for (int i = 0; i < n && !this.cancelled; i++) {
+ getAndCacheDocumentation("function::" + (node.getChildAt(i).toString())); //$NON-NLS-1$
+ }
+
+ return new Status(IStatus.OK, IDEPlugin.PLUGIN_ID, ""); //$NON-NLS-1$;
+ }
+
+ @Override
+ protected void canceling() {
+ this.cancelled = true;
+ }
+
+ };
+
+ private static Job cacheProbeManpages = new Job(Localization.getString("TapsetLibrary.1")) { //$NON-NLS-1$
+ @Override
+ protected IStatus run(IProgressMonitor monitor) {
+ TreeNode node = probeParser.getProbes();
+ int n = node.getChildCount();
+ for (int i = 0; i < n; i++) {
+ getAndCacheDocumentation("tapset::" + (node.getChildAt(i).toString())); //$NON-NLS-1$
+ // No need to pre-cache probes; they can be fetched pretty quickly.
+ }
+
+ return new Status(IStatus.OK, IDEPlugin.PLUGIN_ID, ""); //$NON-NLS-1$;
+ }
+ };
+
+ private static final IUpdateListener functionCompletionListener = new IUpdateListener() {
+ @Override
+ public void handleUpdateEvent() {
+ functionTree = functionParser.getFunctions();
+ cacheFunctionManpages.schedule();
+ TreeSettings.setTrees(functionTree, probeTree);
+ synchronized (functionParser) {
+ functionParser.notifyAll();
+ }
+ }
+ };
+
+ private static final IUpdateListener probeCompletionListener = new IUpdateListener() {
+ @Override
+ public void handleUpdateEvent() {
+ probeTree = probeParser.getProbes();
+ cacheProbeManpages.schedule();
+ synchronized (probeParser) {
+ probeParser.notifyAll();
+ }
+ }
+ };
+
+ /**
+ * Blocks the current thread until the parser has finished
+ * parsing probes and functions.
+ * @since 2.0
+ */
+ public static void waitForInitialization() {
+ while (functionParser.getResult() == null) {
+ try {
+ synchronized (functionParser) {
+ functionParser.wait(5000);
+ }
+ } catch (InterruptedException e) {
+ break;
+ }
+ }
+ while (probeParser.getResult() == null) {
+ try {
+ synchronized (probeParser) {
+ probeParser.wait(5000);
+ }
+ } catch (InterruptedException e) {
+ break;
+ }
+ }
+ }
+
+ /**
+ * This method will stop services started by
+ * {@link TapsetLibrary#init()} such as the {@link TapsetParser}
+ * @since 1.2
+ */
+ public static void stop() {
+ if(null != functionParser) {
+ functionParser.cancel();
+ cacheFunctionManpages.cancel();
+ try {
+ functionParser.join();
+ } catch (InterruptedException e) {
+ // The current thread was interrupted while waiting
+ // for the parser thread to exit. Nothing to do
+ // continue stopping.
+ }
+ }
+ if(probeParser != null) {
+ probeParser.cancel();
+ cacheProbeManpages.cancel();
+ try {
+ probeParser.join();
+ } catch (InterruptedException e) {
+ // The current thread was interrupted while waiting
+ // for the parser thread to exit. Nothing to do
+ // continue stopping.
+ }
+ }
+
+ }
}
diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/TapsetParser.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/TapsetParser.java
index 5c291d9510..2675b32e12 100644
--- a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/TapsetParser.java
+++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/TapsetParser.java
@@ -48,151 +48,151 @@ import com.jcraft.jsch.JSchException;
*/
public abstract class TapsetParser extends Job {
- private ArrayList<IUpdateListener> listeners;
-
- protected boolean cancelRequested;
-
- protected TapsetParser(String jobTitle) {
- super(jobTitle);
- listeners = new ArrayList<>();
- cancelRequested = false;
- }
-
- @Override
- protected void canceling() {
- super.canceling();
- this.cancelRequested = true;
- }
-
- /**
- * This method will register a new listener with the parser
- * @param listener The listener that will receive updateEvents
- */
- public void addListener(IUpdateListener listener) {
- if (null != listener) {
- listeners.add(listener);
- }
- }
-
- /**
- * This method will unregister the listener with the parser
- * @param listener The listener that no longer wants to recieve update events
- */
- public void removeListener(IUpdateListener listener) {
- if (null != listener) {
- listeners.remove(listener);
- }
- }
-
- /**
- * This method will fire an updateEvent to all listeners.
- */
- protected void fireUpdateEvent() {
- for (IUpdateListener listener : listeners) {
- listener.handleUpdateEvent();
- }
- }
-
- /**
- * Runs the stap with the given options and returns the output generated
- * @param options String[] of any optional parameters to pass to stap
- * @param probe String containing the script to run stap on,
- * or <code>null</code> for scriptless commands
- * @param getErrors Set this to <code>true</code> if the script's error
- * stream contents should be returned instead of its standard output
- */
- protected String runStap(String[] options, String probe, boolean getErrors) {
- String[] args = null;
- String[] tapsets = IDEPlugin.getDefault().getPreferenceStore()
- .getString(IDEPreferenceConstants.P_TAPSETS).split(File.pathSeparator);
- boolean noTapsets = tapsets[0].trim().length() == 0;
- boolean noOptions = options[0].trim().length() == 0;
-
- int size = probe != null ? 2 : 1;
- if (tapsets.length > 0 && !noTapsets) {
- size += tapsets.length<<1;
- }
- if (options.length > 0 && !noOptions) {
- size += options.length;
- }
-
- args = new String[size];
- args[0] = "stap"; //$NON-NLS-1$
- if (probe != null) {
- args[size-1] = probe;
- }
-
- //Add extra tapset directories
- if (tapsets.length > 0 && !noTapsets) {
- for (int i = 0; i < tapsets.length; i++) {
- args[1 + 2*i] = "-I"; //$NON-NLS-1$
- args[2 + 2*i] = tapsets[i];
- }
- }
- if (options.length > 0 && !noOptions) {
- for (int i = 0, s = noTapsets ? 1 : 1 + tapsets.length*2; i<options.length; i++) {
- args[s + i] = options[i];
- }
- }
-
- try {
- if (IDEPlugin.getDefault().getPreferenceStore().getBoolean(IDEPreferenceConstants.P_REMOTE_PROBES)) {
- StringOutputStream str = new StringOutputStream();
- StringOutputStream strErr = new StringOutputStream();
-
- IPreferenceStore p = ConsoleLogPlugin.getDefault().getPreferenceStore();
- String user = p.getString(ConsoleLogPreferenceConstants.SCP_USER);
- String host = p.getString(ConsoleLogPreferenceConstants.HOST_NAME);
- String password = p.getString(ConsoleLogPreferenceConstants.SCP_PASSWORD);
-
- Channel channel = SystemtapProcessFactory.execRemoteAndWait(args,str, strErr, user, host, password);
- if (channel == null) {
- displayError(Messages.TapsetParser_CannotRunStapTitle, Messages.TapsetParser_CannotRunStapMessage);
- }
-
- return (!getErrors ? str : strErr).toString();
- } else {
- Process process = RuntimeProcessFactory.getFactory().exec(args, null, null);
- if(process == null){
- displayError(Messages.TapsetParser_CannotRunStapTitle, Messages.TapsetParser_CannotRunStapMessage);
- return null;
- }
-
- StringStreamGobbler gobbler = new StringStreamGobbler(process.getInputStream());
- StringStreamGobbler egobbler = null;
- gobbler.start();
- if (getErrors) {
- egobbler = new StringStreamGobbler(process.getErrorStream());
- egobbler.start();
- }
- process.waitFor();
- gobbler.stop();
- if (egobbler == null) {
- return gobbler.getOutput().toString();
- } else {
- egobbler.stop();
- return egobbler.getOutput().toString();
- }
- }
-
- } catch (JSchException|IOException e) {
- ExceptionErrorDialog.openError(Messages.TapsetParser_ErrorRunningSystemtap, e);
- } catch (InterruptedException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
-
- return null;
- }
-
- private void displayError(final String title, final String error) {
- Display.getDefault().asyncExec(new Runnable() {
- @Override
- public void run() {
- IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
- MessageDialog.openWarning(window.getShell(), title, error);
- }
- });
- }
+ private ArrayList<IUpdateListener> listeners;
+
+ protected boolean cancelRequested;
+
+ protected TapsetParser(String jobTitle) {
+ super(jobTitle);
+ listeners = new ArrayList<>();
+ cancelRequested = false;
+ }
+
+ @Override
+ protected void canceling() {
+ super.canceling();
+ this.cancelRequested = true;
+ }
+
+ /**
+ * This method will register a new listener with the parser
+ * @param listener The listener that will receive updateEvents
+ */
+ public void addListener(IUpdateListener listener) {
+ if (null != listener) {
+ listeners.add(listener);
+ }
+ }
+
+ /**
+ * This method will unregister the listener with the parser
+ * @param listener The listener that no longer wants to recieve update events
+ */
+ public void removeListener(IUpdateListener listener) {
+ if (null != listener) {
+ listeners.remove(listener);
+ }
+ }
+
+ /**
+ * This method will fire an updateEvent to all listeners.
+ */
+ protected void fireUpdateEvent() {
+ for (IUpdateListener listener : listeners) {
+ listener.handleUpdateEvent();
+ }
+ }
+
+ /**
+ * Runs the stap with the given options and returns the output generated
+ * @param options String[] of any optional parameters to pass to stap
+ * @param probe String containing the script to run stap on,
+ * or <code>null</code> for scriptless commands
+ * @param getErrors Set this to <code>true</code> if the script's error
+ * stream contents should be returned instead of its standard output
+ */
+ protected String runStap(String[] options, String probe, boolean getErrors) {
+ String[] args = null;
+ String[] tapsets = IDEPlugin.getDefault().getPreferenceStore()
+ .getString(IDEPreferenceConstants.P_TAPSETS).split(File.pathSeparator);
+ boolean noTapsets = tapsets[0].trim().length() == 0;
+ boolean noOptions = options[0].trim().length() == 0;
+
+ int size = probe != null ? 2 : 1;
+ if (tapsets.length > 0 && !noTapsets) {
+ size += tapsets.length<<1;
+ }
+ if (options.length > 0 && !noOptions) {
+ size += options.length;
+ }
+
+ args = new String[size];
+ args[0] = "stap"; //$NON-NLS-1$
+ if (probe != null) {
+ args[size-1] = probe;
+ }
+
+ //Add extra tapset directories
+ if (tapsets.length > 0 && !noTapsets) {
+ for (int i = 0; i < tapsets.length; i++) {
+ args[1 + 2*i] = "-I"; //$NON-NLS-1$
+ args[2 + 2*i] = tapsets[i];
+ }
+ }
+ if (options.length > 0 && !noOptions) {
+ for (int i = 0, s = noTapsets ? 1 : 1 + tapsets.length*2; i<options.length; i++) {
+ args[s + i] = options[i];
+ }
+ }
+
+ try {
+ if (IDEPlugin.getDefault().getPreferenceStore().getBoolean(IDEPreferenceConstants.P_REMOTE_PROBES)) {
+ StringOutputStream str = new StringOutputStream();
+ StringOutputStream strErr = new StringOutputStream();
+
+ IPreferenceStore p = ConsoleLogPlugin.getDefault().getPreferenceStore();
+ String user = p.getString(ConsoleLogPreferenceConstants.SCP_USER);
+ String host = p.getString(ConsoleLogPreferenceConstants.HOST_NAME);
+ String password = p.getString(ConsoleLogPreferenceConstants.SCP_PASSWORD);
+
+ Channel channel = SystemtapProcessFactory.execRemoteAndWait(args,str, strErr, user, host, password);
+ if (channel == null) {
+ displayError(Messages.TapsetParser_CannotRunStapTitle, Messages.TapsetParser_CannotRunStapMessage);
+ }
+
+ return (!getErrors ? str : strErr).toString();
+ } else {
+ Process process = RuntimeProcessFactory.getFactory().exec(args, null, null);
+ if(process == null){
+ displayError(Messages.TapsetParser_CannotRunStapTitle, Messages.TapsetParser_CannotRunStapMessage);
+ return null;
+ }
+
+ StringStreamGobbler gobbler = new StringStreamGobbler(process.getInputStream());
+ StringStreamGobbler egobbler = null;
+ gobbler.start();
+ if (getErrors) {
+ egobbler = new StringStreamGobbler(process.getErrorStream());
+ egobbler.start();
+ }
+ process.waitFor();
+ gobbler.stop();
+ if (egobbler == null) {
+ return gobbler.getOutput().toString();
+ } else {
+ egobbler.stop();
+ return egobbler.getOutput().toString();
+ }
+ }
+
+ } catch (JSchException|IOException e) {
+ ExceptionErrorDialog.openError(Messages.TapsetParser_ErrorRunningSystemtap, e);
+ } catch (InterruptedException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+
+ return null;
+ }
+
+ private void displayError(final String title, final String error) {
+ Display.getDefault().asyncExec(new Runnable() {
+ @Override
+ public void run() {
+ IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
+ MessageDialog.openWarning(window.getShell(), title, error);
+ }
+ });
+ }
}
diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/TreeSettings.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/TreeSettings.java
index a7b03ba281..6053ae9051 100644
--- a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/TreeSettings.java
+++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/TreeSettings.java
@@ -33,244 +33,244 @@ import org.eclipse.ui.XMLMemento;
* @author Ryan Morse
*/
public final class TreeSettings {
- private TreeSettings() {
- }
- /**
- * Returns the modification date for the Tree File. Used to make sure that the cache is not out of
- * date.
- * @return The datestamp for the Tree file.
- */
- public static long getTreeFileDate() {
- if (!readData()) {
- return -1;
- }
- return treeFileDate;
- }
-
- /**
- * Allows access to the Tapset Function tree, which contains information about all
- * functions stored in the tapset library.
- * @return The <code>TreeNode</code> root of the Function tree.
- * @since 2.0
- */
- public static TreeNode getFunctionTree() {
- if (!readData()) {
- return null;
- }
- return functions;
- }
-
- /**
- * Allows access to the Tapset Probe Alias tree, which contains a list of all probe aliases
- * in the tapset library.
- * @return The <code>TreeNode</code> root of the Probe Alias tree.
- * @since 2.0
- */
- public static TreeNode getProbeTree() {
- if (!readData()) {
- return null;
- }
- return probes;
- }
-
- /**
- * Sets the Probe Alias and Function trees that are being cached to the trees given as arguments.
- * @param func The Function tree to store in cache.
- * @param probe The Probe Alias tree to store in cache.
- * @return True if the caching is successful.
- * @since 2.0
- */
- public static boolean setTrees(TreeNode func, TreeNode probe) {
- if (null == func || null == probe) {
- return false;
- }
- functions = func;
- probes = probe;
- return writeData();
- }
-
- /**
- * Reads the contents of the cache file into memory.
- * @return True if the read is successful.
- */
- private static boolean readData() {
- if (null == settingsFile && !openFile()) {
- return false;
- }
-
- try (FileReader reader = new FileReader(settingsFile)) {
- if(!reader.ready()) {
- reader.close();
- return false;
- }
-
- XMLMemento data = XMLMemento.createReadRoot(reader, "TreeSettings"); //$NON-NLS-1$
-
- IMemento child = data.getChild("functionTree"); //$NON-NLS-1$
- String s = child.getString("string"); //$NON-NLS-1$
- if ("<null>".equals(s)) { //$NON-NLS-1$
- s = null;
- }
- String d = child.getString("data"); //$NON-NLS-1$
- if ("<null>".equals(d)) { //$NON-NLS-1$
- d = null;
- }
-
- functions = new TreeNode(d, s, false);
- readTree(child, functions, 0);
-
- child = data.getChild("probeTree"); //$NON-NLS-1$
- s = child.getString("string"); //$NON-NLS-1$
- if ("<null>".equals(s)) { //$NON-NLS-1$
- s = null;
- }
- d = child.getString("data"); //$NON-NLS-1$
- if ("<null>".equals(d)) { //$NON-NLS-1$
- d = null;
- }
- probes = new TreeNode(d, s, false);
- readTree(child, probes, 0);
-
- child = data.getChild("modifiedDate"); //$NON-NLS-1$
- treeFileDate = Long.parseLong(child.getString("date")); //$NON-NLS-1$
- } catch(IOException|WorkbenchException fnfe) {
- return false;
- }
-
- return true;
- }
-
- /**
- * Writes the tree data currently stored by this class to disk for later access.
- * @return True if the write is successful.
- */
- private static boolean writeData() {
- if (null == settingsFile && !openFile()) {
- return false;
- }
-
- try {
- XMLMemento data = XMLMemento.createWriteRoot("TreeSettings"); //$NON-NLS-1$
-
- IMemento child = data.createChild("functionTree"); //$NON-NLS-1$
- writeTree(child, functions, 0);
-
- child = data.createChild("probeTree"); //$NON-NLS-1$
- writeTree(child, probes, 0);
-
- child = data.createChild("modifiedDate"); //$NON-NLS-1$
- child.putString("date", (Long.valueOf(Calendar.getInstance().getTimeInMillis())).toString()); //$NON-NLS-1$
-
- FileWriter writer = new FileWriter(settingsFile);
- data.save(writer);
- } catch(FileNotFoundException fnfe) {
- return false;
- } catch(IOException e) {
- return false;
- }
-
- return true;
- }
-
- /**
- * Writes the tree passed in to the <code>IMemento</code> argument, up to the specified depth.
- * @param child The <code>IMemento</code> to store the tree to.
- * @param tree The <code>TreeNode</code> to store.
- * @param depth The maximum depth level to write out.
- */
- private static void writeTree(IMemento child, TreeNode tree, int depth) {
- if (null == tree.toString()) {
- child.putString("string", "<null>"); //$NON-NLS-1$ //$NON-NLS-2$
- } else {
- child.putString("string", tree.toString()); //$NON-NLS-1$
- }
-
- if (null == tree.getData()) {
- child.putString("data", "<null>"); //$NON-NLS-1$ //$NON-NLS-2$
- } else {
- child.putString("data", tree.getData().toString()); //$NON-NLS-1$
- }
-
- if (tree instanceof TreeDefinitionNode) {
- if (null == ((TreeDefinitionNode) tree).getDefinition()) {
- child.putString("definition", "<null>"); //$NON-NLS-1$ //$NON-NLS-2$
- } else {
- child.putString(
- "definition", ((TreeDefinitionNode) tree).getDefinition()); //$NON-NLS-1$
- }
- }
-
- child.putInteger("click", (tree.isClickable()?1:0)); //$NON-NLS-1$
- for(int i=0; i<tree.getChildCount(); i++) {
- writeTree(child.createChild("level" + depth), tree.getChildAt(i), depth+1); //$NON-NLS-1$
- }
- }
-
- /**
- * Opposite action as writeTree. Reads the <code>IMemento</code> passed in into the <code>TreeNode</code>
- * up to the requested maximum depth.
- * @param data The <code>IMemento</code> to read the tree out of.
- * @param parent The <code>TreeNode</code> to store the tree in.
- * @param depth The maximum depth to read.
- */
- private static void readTree(IMemento data, TreeNode parent, int depth) {
- IMemento[] children = data.getChildren("level" + depth); //$NON-NLS-1$
-
- try {
- if(null != children) {
- for(int i=0; i<children.length; i++) {
- String s = children[i].getString("string"); //$NON-NLS-1$
- String d = children[i].getString("data"); //$NON-NLS-1$
- String def = children[i].getString("definition"); //$NON-NLS-1$
-
- boolean c = ((0==children[i].getInteger("click").intValue())?false:true); //$NON-NLS-1$
-
- if ("<null>".equals(s)) { //$NON-NLS-1$
- s = null;
- }
- if ("<null>".equals(d)) { //$NON-NLS-1$
- d = null;
- }
-
- TreeNode t;
- if(null == def) {
- t = new TreeNode(d, s, c);
- } else {
- if ("<null>".equals(def)) { //$NON-NLS-1$
- def = null;
- }
-
- t = new TreeDefinitionNode(d, s, def, c);
- }
- parent.add(t);
-
- readTree(children[i], t, depth+1);
- }
- }
- } catch(NullPointerException e) {
- }
- }
-
- private static boolean openFile() {
- settingsFile = new File(System.getenv("HOME") + "/.systemtapgui/" + fileName); //$NON-NLS-1$ //$NON-NLS-2$
-
- try {
- if (!settingsFile.exists()){
- // Create a new settings file-and its parent
- // directories- if one does not exist.
- settingsFile.getParentFile().mkdirs();
- settingsFile.createNewFile();
- }
- } catch(IOException ioe) {
- return false;
- }
-
- return true;
- }
-
- private static long treeFileDate;
- private static TreeNode functions;
- private static TreeNode probes;
- private static final String fileName = "/TreeSettings.xml"; //$NON-NLS-1$
- private static File settingsFile = null;
+ private TreeSettings() {
+ }
+ /**
+ * Returns the modification date for the Tree File. Used to make sure that the cache is not out of
+ * date.
+ * @return The datestamp for the Tree file.
+ */
+ public static long getTreeFileDate() {
+ if (!readData()) {
+ return -1;
+ }
+ return treeFileDate;
+ }
+
+ /**
+ * Allows access to the Tapset Function tree, which contains information about all
+ * functions stored in the tapset library.
+ * @return The <code>TreeNode</code> root of the Function tree.
+ * @since 2.0
+ */
+ public static TreeNode getFunctionTree() {
+ if (!readData()) {
+ return null;
+ }
+ return functions;
+ }
+
+ /**
+ * Allows access to the Tapset Probe Alias tree, which contains a list of all probe aliases
+ * in the tapset library.
+ * @return The <code>TreeNode</code> root of the Probe Alias tree.
+ * @since 2.0
+ */
+ public static TreeNode getProbeTree() {
+ if (!readData()) {
+ return null;
+ }
+ return probes;
+ }
+
+ /**
+ * Sets the Probe Alias and Function trees that are being cached to the trees given as arguments.
+ * @param func The Function tree to store in cache.
+ * @param probe The Probe Alias tree to store in cache.
+ * @return True if the caching is successful.
+ * @since 2.0
+ */
+ public static boolean setTrees(TreeNode func, TreeNode probe) {
+ if (null == func || null == probe) {
+ return false;
+ }
+ functions = func;
+ probes = probe;
+ return writeData();
+ }
+
+ /**
+ * Reads the contents of the cache file into memory.
+ * @return True if the read is successful.
+ */
+ private static boolean readData() {
+ if (null == settingsFile && !openFile()) {
+ return false;
+ }
+
+ try (FileReader reader = new FileReader(settingsFile)) {
+ if(!reader.ready()) {
+ reader.close();
+ return false;
+ }
+
+ XMLMemento data = XMLMemento.createReadRoot(reader, "TreeSettings"); //$NON-NLS-1$
+
+ IMemento child = data.getChild("functionTree"); //$NON-NLS-1$
+ String s = child.getString("string"); //$NON-NLS-1$
+ if ("<null>".equals(s)) { //$NON-NLS-1$
+ s = null;
+ }
+ String d = child.getString("data"); //$NON-NLS-1$
+ if ("<null>".equals(d)) { //$NON-NLS-1$
+ d = null;
+ }
+
+ functions = new TreeNode(d, s, false);
+ readTree(child, functions, 0);
+
+ child = data.getChild("probeTree"); //$NON-NLS-1$
+ s = child.getString("string"); //$NON-NLS-1$
+ if ("<null>".equals(s)) { //$NON-NLS-1$
+ s = null;
+ }
+ d = child.getString("data"); //$NON-NLS-1$
+ if ("<null>".equals(d)) { //$NON-NLS-1$
+ d = null;
+ }
+ probes = new TreeNode(d, s, false);
+ readTree(child, probes, 0);
+
+ child = data.getChild("modifiedDate"); //$NON-NLS-1$
+ treeFileDate = Long.parseLong(child.getString("date")); //$NON-NLS-1$
+ } catch(IOException|WorkbenchException fnfe) {
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Writes the tree data currently stored by this class to disk for later access.
+ * @return True if the write is successful.
+ */
+ private static boolean writeData() {
+ if (null == settingsFile && !openFile()) {
+ return false;
+ }
+
+ try {
+ XMLMemento data = XMLMemento.createWriteRoot("TreeSettings"); //$NON-NLS-1$
+
+ IMemento child = data.createChild("functionTree"); //$NON-NLS-1$
+ writeTree(child, functions, 0);
+
+ child = data.createChild("probeTree"); //$NON-NLS-1$
+ writeTree(child, probes, 0);
+
+ child = data.createChild("modifiedDate"); //$NON-NLS-1$
+ child.putString("date", (Long.valueOf(Calendar.getInstance().getTimeInMillis())).toString()); //$NON-NLS-1$
+
+ FileWriter writer = new FileWriter(settingsFile);
+ data.save(writer);
+ } catch(FileNotFoundException fnfe) {
+ return false;
+ } catch(IOException e) {
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Writes the tree passed in to the <code>IMemento</code> argument, up to the specified depth.
+ * @param child The <code>IMemento</code> to store the tree to.
+ * @param tree The <code>TreeNode</code> to store.
+ * @param depth The maximum depth level to write out.
+ */
+ private static void writeTree(IMemento child, TreeNode tree, int depth) {
+ if (null == tree.toString()) {
+ child.putString("string", "<null>"); //$NON-NLS-1$ //$NON-NLS-2$
+ } else {
+ child.putString("string", tree.toString()); //$NON-NLS-1$
+ }
+
+ if (null == tree.getData()) {
+ child.putString("data", "<null>"); //$NON-NLS-1$ //$NON-NLS-2$
+ } else {
+ child.putString("data", tree.getData().toString()); //$NON-NLS-1$
+ }
+
+ if (tree instanceof TreeDefinitionNode) {
+ if (null == ((TreeDefinitionNode) tree).getDefinition()) {
+ child.putString("definition", "<null>"); //$NON-NLS-1$ //$NON-NLS-2$
+ } else {
+ child.putString(
+ "definition", ((TreeDefinitionNode) tree).getDefinition()); //$NON-NLS-1$
+ }
+ }
+
+ child.putInteger("click", (tree.isClickable()?1:0)); //$NON-NLS-1$
+ for(int i=0; i<tree.getChildCount(); i++) {
+ writeTree(child.createChild("level" + depth), tree.getChildAt(i), depth+1); //$NON-NLS-1$
+ }
+ }
+
+ /**
+ * Opposite action as writeTree. Reads the <code>IMemento</code> passed in into the <code>TreeNode</code>
+ * up to the requested maximum depth.
+ * @param data The <code>IMemento</code> to read the tree out of.
+ * @param parent The <code>TreeNode</code> to store the tree in.
+ * @param depth The maximum depth to read.
+ */
+ private static void readTree(IMemento data, TreeNode parent, int depth) {
+ IMemento[] children = data.getChildren("level" + depth); //$NON-NLS-1$
+
+ try {
+ if(null != children) {
+ for(int i=0; i<children.length; i++) {
+ String s = children[i].getString("string"); //$NON-NLS-1$
+ String d = children[i].getString("data"); //$NON-NLS-1$
+ String def = children[i].getString("definition"); //$NON-NLS-1$
+
+ boolean c = ((0==children[i].getInteger("click").intValue())?false:true); //$NON-NLS-1$
+
+ if ("<null>".equals(s)) { //$NON-NLS-1$
+ s = null;
+ }
+ if ("<null>".equals(d)) { //$NON-NLS-1$
+ d = null;
+ }
+
+ TreeNode t;
+ if(null == def) {
+ t = new TreeNode(d, s, c);
+ } else {
+ if ("<null>".equals(def)) { //$NON-NLS-1$
+ def = null;
+ }
+
+ t = new TreeDefinitionNode(d, s, def, c);
+ }
+ parent.add(t);
+
+ readTree(children[i], t, depth+1);
+ }
+ }
+ } catch(NullPointerException e) {
+ }
+ }
+
+ private static boolean openFile() {
+ settingsFile = new File(System.getenv("HOME") + "/.systemtapgui/" + fileName); //$NON-NLS-1$ //$NON-NLS-2$
+
+ try {
+ if (!settingsFile.exists()){
+ // Create a new settings file-and its parent
+ // directories- if one does not exist.
+ settingsFile.getParentFile().mkdirs();
+ settingsFile.createNewFile();
+ }
+ } catch(IOException ioe) {
+ return false;
+ }
+
+ return true;
+ }
+
+ private static long treeFileDate;
+ private static TreeNode functions;
+ private static TreeNode probes;
+ private static final String fileName = "/TreeSettings.xml"; //$NON-NLS-1$
+ private static File settingsFile = null;
}
diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/views/BrowserView.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/views/BrowserView.java
index 7f67b04a24..dca0101c54 100644
--- a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/views/BrowserView.java
+++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/views/BrowserView.java
@@ -46,135 +46,135 @@ import org.eclipse.ui.part.ViewPart;
* @see org.eclipse.linuxtools.internal.systemtap.ui.ide.views.ProbeAliasBrowserView
*/
public abstract class BrowserView extends ViewPart {
- protected TreeViewer viewer;
-
- private CollapseAllHandler collapseHandler;
-
- public BrowserView() {
- super();
- }
-
- /**
- * Provides an interface for the TreeViewer to interact with the internal TreeNode data structure.
- * @author Ryan Morse
- *
- */
- static class ViewContentProvider implements ITreeContentProvider {
- @Override
- public void inputChanged(Viewer v, Object oldInput, Object newInput) {}
-
- @Override
- public void dispose() {}
-
- @Override
- public Object[] getElements(Object parent) {
- return getChildren(parent);
- }
-
- @Override
- public Object getParent(Object child) {
- return null;
- }
-
- @Override
- public Object[] getChildren(Object par) {
- TreeNode parent = ((TreeNode)par);
-
- Object[] children = new Object[parent.getChildCount()];
-
- for(int i=0; i<children.length; i++) {
- children[i] = parent.getChildAt(i);
- }
-
- return children;
- }
-
- @Override
- public boolean hasChildren(Object parent) {
- return ((TreeNode)parent).getChildCount() > 0;
- }
- }
-
- protected abstract Image getEntryImage(TreeNode treeObj);
-
- protected Image getGenericImage(TreeNode treeObj) {
- if (treeObj.getChildCount() == 0) {
- return IDEPlugin.getImageDescriptor("icons/vars/var_unk.gif").createImage(); //$NON-NLS-1$
- } else {
- return PlatformUI.getWorkbench().getSharedImages().getImage(ISharedImages.IMG_OBJ_FOLDER);
- }
- }
-
- /**
- * Provides the icon and text for each entry in the tapset tree.
- * @author Ryan Morse
- */
- protected class ViewLabelProvider extends LabelProvider {
- @Override
- public String getText(Object obj) {
- return obj.toString();
- }
-
- @Override
- public Image getImage(Object obj) {
- return getEntryImage((TreeNode) obj);
- }
- }
-
- @Override
- public void createPartControl(Composite parent) {
- parent.getShell().setCursor(parent.getShell().getDisplay().getSystemCursor(SWT.CURSOR_WAIT));
- PatternFilter filter = new PatternFilter();
- FilteredTree filteredTree = new FilteredTree(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL, filter, true);
- viewer = filteredTree.getViewer();
- viewer.setContentProvider(new ViewContentProvider());
- viewer.setLabelProvider(new ViewLabelProvider());
- IHandlerService handlerService = (IHandlerService) getSite().getService(IHandlerService.class);
- collapseHandler = new CollapseAllHandler(getViewer());
- handlerService.activateHandler(CollapseAllHandler.COMMAND_ID, collapseHandler);
- }
-
- protected void registerContextMenu(String menuName) {
- Control control = this.viewer.getControl();
- MenuManager manager = new MenuManager(menuName);
- manager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS));
- Menu menu = manager.createContextMenu(control);
- viewer.getControl().setMenu(menu);
-
- IWorkbenchPartSite partSite = getSite();
- partSite.registerContextMenu(manager, viewer);
- partSite.setSelectionProvider(viewer);
- }
-
- public TreeViewer getViewer() {
- return viewer;
- }
-
- @Override
- public void setFocus() {
- viewer.getControl().setFocus();
- }
-
- @Override
- public void dispose() {
- super.dispose();
- viewer = null;
- if(collapseHandler != null) {
- collapseHandler.dispose();
- }
- }
-
- abstract void refresh();
-
- protected class ViewUpdater implements IUpdateListener {
- @Override
- public void handleUpdateEvent() {
- viewer.getControl().getDisplay().asyncExec(new Runnable() {
- @Override
- public void run() {
- refresh();
- }
- });
- }
- }
+ protected TreeViewer viewer;
+
+ private CollapseAllHandler collapseHandler;
+
+ public BrowserView() {
+ super();
+ }
+
+ /**
+ * Provides an interface for the TreeViewer to interact with the internal TreeNode data structure.
+ * @author Ryan Morse
+ *
+ */
+ static class ViewContentProvider implements ITreeContentProvider {
+ @Override
+ public void inputChanged(Viewer v, Object oldInput, Object newInput) {}
+
+ @Override
+ public void dispose() {}
+
+ @Override
+ public Object[] getElements(Object parent) {
+ return getChildren(parent);
+ }
+
+ @Override
+ public Object getParent(Object child) {
+ return null;
+ }
+
+ @Override
+ public Object[] getChildren(Object par) {
+ TreeNode parent = ((TreeNode)par);
+
+ Object[] children = new Object[parent.getChildCount()];
+
+ for(int i=0; i<children.length; i++) {
+ children[i] = parent.getChildAt(i);
+ }
+
+ return children;
+ }
+
+ @Override
+ public boolean hasChildren(Object parent) {
+ return ((TreeNode)parent).getChildCount() > 0;
+ }
+ }
+
+ protected abstract Image getEntryImage(TreeNode treeObj);
+
+ protected Image getGenericImage(TreeNode treeObj) {
+ if (treeObj.getChildCount() == 0) {
+ return IDEPlugin.getImageDescriptor("icons/vars/var_unk.gif").createImage(); //$NON-NLS-1$
+ } else {
+ return PlatformUI.getWorkbench().getSharedImages().getImage(ISharedImages.IMG_OBJ_FOLDER);
+ }
+ }
+
+ /**
+ * Provides the icon and text for each entry in the tapset tree.
+ * @author Ryan Morse
+ */
+ protected class ViewLabelProvider extends LabelProvider {
+ @Override
+ public String getText(Object obj) {
+ return obj.toString();
+ }
+
+ @Override
+ public Image getImage(Object obj) {
+ return getEntryImage((TreeNode) obj);
+ }
+ }
+
+ @Override
+ public void createPartControl(Composite parent) {
+ parent.getShell().setCursor(parent.getShell().getDisplay().getSystemCursor(SWT.CURSOR_WAIT));
+ PatternFilter filter = new PatternFilter();
+ FilteredTree filteredTree = new FilteredTree(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL, filter, true);
+ viewer = filteredTree.getViewer();
+ viewer.setContentProvider(new ViewContentProvider());
+ viewer.setLabelProvider(new ViewLabelProvider());
+ IHandlerService handlerService = (IHandlerService) getSite().getService(IHandlerService.class);
+ collapseHandler = new CollapseAllHandler(getViewer());
+ handlerService.activateHandler(CollapseAllHandler.COMMAND_ID, collapseHandler);
+ }
+
+ protected void registerContextMenu(String menuName) {
+ Control control = this.viewer.getControl();
+ MenuManager manager = new MenuManager(menuName);
+ manager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS));
+ Menu menu = manager.createContextMenu(control);
+ viewer.getControl().setMenu(menu);
+
+ IWorkbenchPartSite partSite = getSite();
+ partSite.registerContextMenu(manager, viewer);
+ partSite.setSelectionProvider(viewer);
+ }
+
+ public TreeViewer getViewer() {
+ return viewer;
+ }
+
+ @Override
+ public void setFocus() {
+ viewer.getControl().setFocus();
+ }
+
+ @Override
+ public void dispose() {
+ super.dispose();
+ viewer = null;
+ if(collapseHandler != null) {
+ collapseHandler.dispose();
+ }
+ }
+
+ abstract void refresh();
+
+ protected class ViewUpdater implements IUpdateListener {
+ @Override
+ public void handleUpdateEvent() {
+ viewer.getControl().getDisplay().asyncExec(new Runnable() {
+ @Override
+ public void run() {
+ refresh();
+ }
+ });
+ }
+ }
} \ No newline at end of file
diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/views/FunctionBrowserView.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/views/FunctionBrowserView.java
index 2943bcd0de..fd7722247a 100644
--- a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/views/FunctionBrowserView.java
+++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/views/FunctionBrowserView.java
@@ -28,99 +28,99 @@ import org.eclipse.swt.widgets.Composite;
* @author Henry Hughes
*/
public class FunctionBrowserView extends BrowserView {
- public static final String ID = "org.eclipse.linuxtools.internal.systemtap.ui.ide.views.FunctionBrowserView"; //$NON-NLS-1$
- private FunctionBrowserAction doubleClickAction;
- private TreeNode functions;
- private TreeNode localFunctions;
+ public static final String ID = "org.eclipse.linuxtools.internal.systemtap.ui.ide.views.FunctionBrowserView"; //$NON-NLS-1$
+ private FunctionBrowserAction doubleClickAction;
+ private TreeNode functions;
+ private TreeNode localFunctions;
- /**
- * Creates the UI on the given <code>Composite</code>
- */
- @Override
- public void createPartControl(Composite parent) {
- super.createPartControl(parent);
- TapsetLibrary.init();
- TapsetLibrary.addFunctionListener(new ViewUpdater());
- refresh();
- makeActions();
- }
+ /**
+ * Creates the UI on the given <code>Composite</code>
+ */
+ @Override
+ public void createPartControl(Composite parent) {
+ super.createPartControl(parent);
+ TapsetLibrary.init();
+ TapsetLibrary.addFunctionListener(new ViewUpdater());
+ refresh();
+ makeActions();
+ }
- @Override
- protected Image getEntryImage(TreeNode treeObj) {
- if (!(treeObj.getData() instanceof ISingleTypedNode)) {
- return IDEPlugin.getImageDescriptor("icons/vars/var_unk.gif").createImage(); //$NON-NLS-1$
- }
- String type = ((ISingleTypedNode) treeObj.getData()).getType();
- if (type == null) {
- return IDEPlugin.getImageDescriptor("icons/vars/var_void.gif").createImage(); //$NON-NLS-1$
- } else if (type.equals("long")) {//$NON-NLS-1$
- return IDEPlugin.getImageDescriptor("icons/vars/var_long.gif").createImage(); //$NON-NLS-1$
- } else if (type.equals("string")) {//$NON-NLS-1$
- return IDEPlugin.getImageDescriptor("icons/vars/var_str.gif").createImage(); //$NON-NLS-1$
- } else {
- return IDEPlugin.getImageDescriptor("icons/vars/var_unk.gif").createImage(); //$NON-NLS-1$
- }
- }
+ @Override
+ protected Image getEntryImage(TreeNode treeObj) {
+ if (!(treeObj.getData() instanceof ISingleTypedNode)) {
+ return IDEPlugin.getImageDescriptor("icons/vars/var_unk.gif").createImage(); //$NON-NLS-1$
+ }
+ String type = ((ISingleTypedNode) treeObj.getData()).getType();
+ if (type == null) {
+ return IDEPlugin.getImageDescriptor("icons/vars/var_void.gif").createImage(); //$NON-NLS-1$
+ } else if (type.equals("long")) {//$NON-NLS-1$
+ return IDEPlugin.getImageDescriptor("icons/vars/var_long.gif").createImage(); //$NON-NLS-1$
+ } else if (type.equals("string")) {//$NON-NLS-1$
+ return IDEPlugin.getImageDescriptor("icons/vars/var_str.gif").createImage(); //$NON-NLS-1$
+ } else {
+ return IDEPlugin.getImageDescriptor("icons/vars/var_unk.gif").createImage(); //$NON-NLS-1$
+ }
+ }
- /**
- * Refreshes the list of functions in the viewer.
- */
- @Override
- public void refresh() {
- functions = TapsetLibrary.getFunctions();
- if (functions != null){
- addLocalFunctions(localFunctions);
- }
- }
+ /**
+ * Refreshes the list of functions in the viewer.
+ */
+ @Override
+ public void refresh() {
+ functions = TapsetLibrary.getFunctions();
+ if (functions != null){
+ addLocalFunctions(localFunctions);
+ }
+ }
- /**
- * Adds the local functions specified in the argument to the viewer.
- * @param localFunctionTree A tree of the local functions.
- */
- public void addLocalFunctions(TreeNode localFunctionTree) {
- if(functions.getChildCount() > 0) {
- TreeNode localFuncs = functions.getChildAt(0);
+ /**
+ * Adds the local functions specified in the argument to the viewer.
+ * @param localFunctionTree A tree of the local functions.
+ */
+ public void addLocalFunctions(TreeNode localFunctionTree) {
+ if(functions.getChildCount() > 0) {
+ TreeNode localFuncs = functions.getChildAt(0);
- if("<local>".equals(localFuncs.toString())) { //$NON-NLS-1$
- functions.remove(0);
- }
+ if("<local>".equals(localFuncs.toString())) { //$NON-NLS-1$
+ functions.remove(0);
+ }
- if(null != localFunctions) {
- localFunctions = localFunctionTree;
- localFunctions.setDisplay("<local>"); //$NON-NLS-1$
- functions.addAt(localFunctions, 0);
- }
- }
- viewer.setInput(functions);
- }
+ if(null != localFunctions) {
+ localFunctions = localFunctionTree;
+ localFunctions.setDisplay("<local>"); //$NON-NLS-1$
+ functions.addAt(localFunctions, 0);
+ }
+ }
+ viewer.setInput(functions);
+ }
- /**
- * Wires up all of the actions for this browser, such as double and right click handlers.
- */
- private void makeActions() {
- doubleClickAction = new FunctionBrowserAction(getSite().getWorkbenchWindow(), this);
- viewer.addDoubleClickListener(doubleClickAction);
- registerContextMenu("functionPopup"); //$NON-NLS-1$
- }
+ /**
+ * Wires up all of the actions for this browser, such as double and right click handlers.
+ */
+ private void makeActions() {
+ doubleClickAction = new FunctionBrowserAction(getSite().getWorkbenchWindow(), this);
+ viewer.addDoubleClickListener(doubleClickAction);
+ registerContextMenu("functionPopup"); //$NON-NLS-1$
+ }
- @Override
- public void dispose() {
- super.dispose();
- if(null != viewer) {
- viewer.removeDoubleClickListener(doubleClickAction);
- }
- if(null != doubleClickAction) {
- doubleClickAction.dispose();
- }
- doubleClickAction = null;
- if(null != localFunctions) {
- localFunctions.dispose();
- }
- localFunctions = null;
- if(null != functions) {
- functions.dispose();
- }
- functions = null;
- TapsetLibrary.stop();
- }
+ @Override
+ public void dispose() {
+ super.dispose();
+ if(null != viewer) {
+ viewer.removeDoubleClickListener(doubleClickAction);
+ }
+ if(null != doubleClickAction) {
+ doubleClickAction.dispose();
+ }
+ doubleClickAction = null;
+ if(null != localFunctions) {
+ localFunctions.dispose();
+ }
+ localFunctions = null;
+ if(null != functions) {
+ functions.dispose();
+ }
+ functions = null;
+ TapsetLibrary.stop();
+ }
}
diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/views/KernelBrowserView.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/views/KernelBrowserView.java
index 4780864e39..5e191fdf9a 100644
--- a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/views/KernelBrowserView.java
+++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/views/KernelBrowserView.java
@@ -46,192 +46,192 @@ import org.eclipse.ui.progress.UIJob;
*/
public class KernelBrowserView extends BrowserView {
- private class KernelRefreshJob extends Job {
- private boolean remote;
- private URI kernelLocationURI;
- private IRemoteFileProxy proxy;
- private String kernelSource;
-
- public KernelRefreshJob(boolean remote, URI kernelLocationURI, IRemoteFileProxy proxy, String kernelSource) {
- super(Localization.getString("KernelBrowserView.RefreshingKernelSource")); //$NON-NLS-1$
- this.remote = remote;
- this.kernelLocationURI = kernelLocationURI;
- this.proxy = proxy;
- this.kernelSource = kernelSource;
- }
-
- @Override
- public IStatus run(IProgressMonitor monitor) {
- IPreferenceStore p = IDEPlugin.getDefault().getPreferenceStore();
- KernelSourceTree kst = new KernelSourceTree();
- String excluded[] = p.getString(IDEPreferenceConstants.P_EXCLUDED_KERNEL_SOURCE).split(File.pathSeparator);
- if (remote) {
- try {
- kst.buildKernelTree(kernelLocationURI, excluded, proxy, monitor);
- } catch (CoreException e) {
- ExceptionErrorDialog.openError(Localization.getString("KernelBrowserView.CouldNotInitializeTree"), e); //$NON-NLS-1$
- }
- } else {
- kst.buildKernelTree(kernelSource, excluded);
- }
- if (monitor.isCanceled()) {
- return Status.CANCEL_STATUS;
- }
- UpdateKernelBrowserJob job = new UpdateKernelBrowserJob(kst);
- job.schedule();
- monitor.done();
- return Status.OK_STATUS;
- }
- }
-
- private class UpdateKernelBrowserJob extends UIJob {
- KernelSourceTree kst;
- public UpdateKernelBrowserJob(KernelSourceTree kst) {
- super(Localization.getString("KernelBrowserView.UpdateKernelBrowser")); //$NON-NLS-1$
- this.kst = kst;
- }
-
- @Override
- public IStatus runInUIThread(IProgressMonitor monitor) {
- monitor.beginTask(Localization.getString("KernelBrowserView.UpdateKernelBrowser"), 100); //$NON-NLS-1$
- if (kst == null) {
- return Status.OK_STATUS;
- }
- viewer.setInput(kst.getTree());
- kst.dispose();
- monitor.done();
- return Status.OK_STATUS;
- }
- }
-
- public static final String ID = "org.eclipse.linuxtools.internal.systemtap.ui.ide.views.KernelBrowserView"; //$NON-NLS-1$
- private KernelSourceAction doubleClickAction;
-
- /**
- * Creates the UI on the given <code>Composite</code>
- */
- @Override
- public void createPartControl(Composite parent) {
- super.createPartControl(parent);
- refresh();
- makeActions();
- }
-
- /**
- * Wires up all of the actions for this browser, such as double and right click handlers.
- */
- private void makeActions() {
- doubleClickAction = new KernelSourceAction(getSite().getWorkbenchWindow(), this);
- viewer.addDoubleClickListener(doubleClickAction);
- IDEPlugin.getDefault().getPreferenceStore().addPropertyChangeListener(propertyChangeListener);
- }
-
- @Override
- protected Image getEntryImage(TreeNode treeObj) {
- String item = treeObj.getData().toString();
- if(item.endsWith(".c")) { //$NON-NLS-1$
- return IDEPlugin.getImageDescriptor("icons/files/file_c.gif").createImage(); //$NON-NLS-1$
- }
- if(item.endsWith(".h")) { //$NON-NLS-1$
- return IDEPlugin.getImageDescriptor("icons/files/file_h.gif").createImage(); //$NON-NLS-1$
- }
- return getGenericImage(treeObj);
- }
-
- /**
- * Updates the kernel source displayed to the user with the new kernel source tree. Usually
- * a response to the user changing the preferences related to the kernel source location, requiring
- * that the application update the kernel source information.
- */
- @Override
- public void refresh() {
- IPreferenceStore p = IDEPlugin.getDefault().getPreferenceStore();
- String kernelSource = p.getString(IDEPreferenceConstants.P_KERNEL_SOURCE);
- if(null == kernelSource || kernelSource.length() < 1) {
- showBrowserErrorMessage(Localization.getString("KernelBrowserView.NoKernelSourceFound")); //$NON-NLS-1$
- return;
- }
-
- String localOrRemote = p.getString(IDEPreferenceConstants.P_REMOTE_LOCAL_KERNEL_SOURCE);
- URI kernelLocationURI = null;
- IRemoteFileProxy proxy = null;
- boolean remote = localOrRemote.equals(PathPreferencePage.REMOTE);
- if (remote) {
- boolean error = false;
- try {
- kernelLocationURI = IDEPlugin.getDefault().createRemoteUri(kernelSource);
- if (kernelLocationURI == null) {
- error = true;
- } else {
- proxy = RemoteProxyManager.getInstance().getFileProxy(kernelLocationURI);
- if (!validateProxy(proxy, kernelSource)) {
- error = true;
- }
- }
- } catch (CoreException e2) {
- error = true;
- }
- if (error) {
- showBrowserErrorMessage(Localization.getString("KernelBrowserView.KernelSourceDirNotFound")); //$NON-NLS-1$
- return;
- }
- }
-
- KernelRefreshJob refreshJob = new KernelRefreshJob(remote, kernelLocationURI, proxy, kernelSource);
- refreshJob.setUser(true);
- refreshJob.setPriority(Job.SHORT);
- refreshJob.schedule();
- }
-
- private boolean validateProxy(IRemoteFileProxy proxy, String kernelSource) {
- if (proxy == null) {
- return false;
- }
- IFileStore fs = proxy.getResource(kernelSource);
- if (fs == null) {
- return false;
- }
- IFileInfo info = fs.fetchInfo();
- if (info == null) {
- return false;
- }
- if (!info.exists()) {
- return false;
- }
- return true;
- }
-
- private void showBrowserErrorMessage(String message) {
- TreeNode t = new TreeNode("", "", false); //$NON-NLS-1$ //$NON-NLS-2$
- t.add(new TreeNode("", message, false)); //$NON-NLS-1$
- viewer.setInput(t);
- }
-
- /**
- * A <code>IPropertyChangeListener</code> that detects changes to the Kernel Source location
- * and runs the <code>updateKernelSourceTree</code> method.
- */
- private final IPropertyChangeListener propertyChangeListener = new IPropertyChangeListener() {
- @Override
- public void propertyChange(PropertyChangeEvent event) {
- if(event.getProperty().equals(IDEPreferenceConstants.P_KERNEL_SOURCE) ||
- event.getProperty().equals(IDEPreferenceConstants.P_REMOTE_LOCAL_KERNEL_SOURCE) ||
- event.getProperty().equals(IDEPreferenceConstants.P_EXCLUDED_KERNEL_SOURCE)) {
- refresh();
- }
- }
- };
-
- @Override
- public void dispose() {
- super.dispose();
- IDEPlugin.getDefault().getPreferenceStore().removePropertyChangeListener(propertyChangeListener);
- if(null != viewer) {
- viewer.removeDoubleClickListener(doubleClickAction);
- }
- if(null != doubleClickAction) {
- doubleClickAction.dispose();
- }
- doubleClickAction = null;
- }
+ private class KernelRefreshJob extends Job {
+ private boolean remote;
+ private URI kernelLocationURI;
+ private IRemoteFileProxy proxy;
+ private String kernelSource;
+
+ public KernelRefreshJob(boolean remote, URI kernelLocationURI, IRemoteFileProxy proxy, String kernelSource) {
+ super(Localization.getString("KernelBrowserView.RefreshingKernelSource")); //$NON-NLS-1$
+ this.remote = remote;
+ this.kernelLocationURI = kernelLocationURI;
+ this.proxy = proxy;
+ this.kernelSource = kernelSource;
+ }
+
+ @Override
+ public IStatus run(IProgressMonitor monitor) {
+ IPreferenceStore p = IDEPlugin.getDefault().getPreferenceStore();
+ KernelSourceTree kst = new KernelSourceTree();
+ String excluded[] = p.getString(IDEPreferenceConstants.P_EXCLUDED_KERNEL_SOURCE).split(File.pathSeparator);
+ if (remote) {
+ try {
+ kst.buildKernelTree(kernelLocationURI, excluded, proxy, monitor);
+ } catch (CoreException e) {
+ ExceptionErrorDialog.openError(Localization.getString("KernelBrowserView.CouldNotInitializeTree"), e); //$NON-NLS-1$
+ }
+ } else {
+ kst.buildKernelTree(kernelSource, excluded);
+ }
+ if (monitor.isCanceled()) {
+ return Status.CANCEL_STATUS;
+ }
+ UpdateKernelBrowserJob job = new UpdateKernelBrowserJob(kst);
+ job.schedule();
+ monitor.done();
+ return Status.OK_STATUS;
+ }
+ }
+
+ private class UpdateKernelBrowserJob extends UIJob {
+ KernelSourceTree kst;
+ public UpdateKernelBrowserJob(KernelSourceTree kst) {
+ super(Localization.getString("KernelBrowserView.UpdateKernelBrowser")); //$NON-NLS-1$
+ this.kst = kst;
+ }
+
+ @Override
+ public IStatus runInUIThread(IProgressMonitor monitor) {
+ monitor.beginTask(Localization.getString("KernelBrowserView.UpdateKernelBrowser"), 100); //$NON-NLS-1$
+ if (kst == null) {
+ return Status.OK_STATUS;
+ }
+ viewer.setInput(kst.getTree());
+ kst.dispose();
+ monitor.done();
+ return Status.OK_STATUS;
+ }
+ }
+
+ public static final String ID = "org.eclipse.linuxtools.internal.systemtap.ui.ide.views.KernelBrowserView"; //$NON-NLS-1$
+ private KernelSourceAction doubleClickAction;
+
+ /**
+ * Creates the UI on the given <code>Composite</code>
+ */
+ @Override
+ public void createPartControl(Composite parent) {
+ super.createPartControl(parent);
+ refresh();
+ makeActions();
+ }
+
+ /**
+ * Wires up all of the actions for this browser, such as double and right click handlers.
+ */
+ private void makeActions() {
+ doubleClickAction = new KernelSourceAction(getSite().getWorkbenchWindow(), this);
+ viewer.addDoubleClickListener(doubleClickAction);
+ IDEPlugin.getDefault().getPreferenceStore().addPropertyChangeListener(propertyChangeListener);
+ }
+
+ @Override
+ protected Image getEntryImage(TreeNode treeObj) {
+ String item = treeObj.getData().toString();
+ if(item.endsWith(".c")) { //$NON-NLS-1$
+ return IDEPlugin.getImageDescriptor("icons/files/file_c.gif").createImage(); //$NON-NLS-1$
+ }
+ if(item.endsWith(".h")) { //$NON-NLS-1$
+ return IDEPlugin.getImageDescriptor("icons/files/file_h.gif").createImage(); //$NON-NLS-1$
+ }
+ return getGenericImage(treeObj);
+ }
+
+ /**
+ * Updates the kernel source displayed to the user with the new kernel source tree. Usually
+ * a response to the user changing the preferences related to the kernel source location, requiring
+ * that the application update the kernel source information.
+ */
+ @Override
+ public void refresh() {
+ IPreferenceStore p = IDEPlugin.getDefault().getPreferenceStore();
+ String kernelSource = p.getString(IDEPreferenceConstants.P_KERNEL_SOURCE);
+ if(null == kernelSource || kernelSource.length() < 1) {
+ showBrowserErrorMessage(Localization.getString("KernelBrowserView.NoKernelSourceFound")); //$NON-NLS-1$
+ return;
+ }
+
+ String localOrRemote = p.getString(IDEPreferenceConstants.P_REMOTE_LOCAL_KERNEL_SOURCE);
+ URI kernelLocationURI = null;
+ IRemoteFileProxy proxy = null;
+ boolean remote = localOrRemote.equals(PathPreferencePage.REMOTE);
+ if (remote) {
+ boolean error = false;
+ try {
+ kernelLocationURI = IDEPlugin.getDefault().createRemoteUri(kernelSource);
+ if (kernelLocationURI == null) {
+ error = true;
+ } else {
+ proxy = RemoteProxyManager.getInstance().getFileProxy(kernelLocationURI);
+ if (!validateProxy(proxy, kernelSource)) {
+ error = true;
+ }
+ }
+ } catch (CoreException e2) {
+ error = true;
+ }
+ if (error) {
+ showBrowserErrorMessage(Localization.getString("KernelBrowserView.KernelSourceDirNotFound")); //$NON-NLS-1$
+ return;
+ }
+ }
+
+ KernelRefreshJob refreshJob = new KernelRefreshJob(remote, kernelLocationURI, proxy, kernelSource);
+ refreshJob.setUser(true);
+ refreshJob.setPriority(Job.SHORT);
+ refreshJob.schedule();
+ }
+
+ private boolean validateProxy(IRemoteFileProxy proxy, String kernelSource) {
+ if (proxy == null) {
+ return false;
+ }
+ IFileStore fs = proxy.getResource(kernelSource);
+ if (fs == null) {
+ return false;
+ }
+ IFileInfo info = fs.fetchInfo();
+ if (info == null) {
+ return false;
+ }
+ if (!info.exists()) {
+ return false;
+ }
+ return true;
+ }
+
+ private void showBrowserErrorMessage(String message) {
+ TreeNode t = new TreeNode("", "", false); //$NON-NLS-1$ //$NON-NLS-2$
+ t.add(new TreeNode("", message, false)); //$NON-NLS-1$
+ viewer.setInput(t);
+ }
+
+ /**
+ * A <code>IPropertyChangeListener</code> that detects changes to the Kernel Source location
+ * and runs the <code>updateKernelSourceTree</code> method.
+ */
+ private final IPropertyChangeListener propertyChangeListener = new IPropertyChangeListener() {
+ @Override
+ public void propertyChange(PropertyChangeEvent event) {
+ if(event.getProperty().equals(IDEPreferenceConstants.P_KERNEL_SOURCE) ||
+ event.getProperty().equals(IDEPreferenceConstants.P_REMOTE_LOCAL_KERNEL_SOURCE) ||
+ event.getProperty().equals(IDEPreferenceConstants.P_EXCLUDED_KERNEL_SOURCE)) {
+ refresh();
+ }
+ }
+ };
+
+ @Override
+ public void dispose() {
+ super.dispose();
+ IDEPlugin.getDefault().getPreferenceStore().removePropertyChangeListener(propertyChangeListener);
+ if(null != viewer) {
+ viewer.removeDoubleClickListener(doubleClickAction);
+ }
+ if(null != doubleClickAction) {
+ doubleClickAction.dispose();
+ }
+ doubleClickAction = null;
+ }
}
diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/views/ProbeAliasBrowserView.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/views/ProbeAliasBrowserView.java
index 8ce45b93c3..fe8e358255 100644
--- a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/views/ProbeAliasBrowserView.java
+++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/views/ProbeAliasBrowserView.java
@@ -31,78 +31,78 @@ import org.eclipse.swt.widgets.Composite;
* @author Ryan Morse
*/
public class ProbeAliasBrowserView extends BrowserView {
- public static final String ID = "org.eclipse.linuxtools.internal.systemtap.ui.ide.views.ProbeAliasBrowserView"; //$NON-NLS-1$
- private ProbeAliasAction doubleClickAction;
+ public static final String ID = "org.eclipse.linuxtools.internal.systemtap.ui.ide.views.ProbeAliasBrowserView"; //$NON-NLS-1$
+ private ProbeAliasAction doubleClickAction;
- /**
- * Creates the UI on the given <code>Composite</code>
- */
- @Override
- public void createPartControl(Composite parent) {
- super.createPartControl(parent);
- TapsetLibrary.init();
- TapsetLibrary.addProbeListener(new ViewUpdater());
- refresh();
- makeActions();
- }
+ /**
+ * Creates the UI on the given <code>Composite</code>
+ */
+ @Override
+ public void createPartControl(Composite parent) {
+ super.createPartControl(parent);
+ TapsetLibrary.init();
+ TapsetLibrary.addProbeListener(new ViewUpdater());
+ refresh();
+ makeActions();
+ }
- @Override
- protected Image getEntryImage(TreeNode treeObj) {
- //Probe variables
- if (treeObj.getData() instanceof ProbevarNodeData) {
- List<String> varTypes = ((ProbevarNodeData) treeObj.getData()).getTypes();
- if (varTypes.get(varTypes.size()-1).endsWith("*")) { //Pointers //$NON-NLS-1$
- return IDEPlugin.getImageDescriptor("icons/vars/var_long.gif").createImage(); //$NON-NLS-1$
- }
- if (varTypes.contains("struct")) {//$NON-NLS-1$
- return IDEPlugin.getImageDescriptor("icons/vars/var_struct.gif").createImage(); //$NON-NLS-1$
- }
- if (varTypes.contains("string")) {//$NON-NLS-1$
- return IDEPlugin.getImageDescriptor("icons/vars/var_str.gif").createImage(); //$NON-NLS-1$
- }
- if (varTypes.contains("unknown")) {//$NON-NLS-1$
- return IDEPlugin.getImageDescriptor("icons/vars/var_unk.gif").createImage(); //$NON-NLS-1$
- }
- // All other types are displayed as long
- return IDEPlugin.getImageDescriptor("icons/vars/var_long.gif").createImage(); //$NON-NLS-1$
- }
+ @Override
+ protected Image getEntryImage(TreeNode treeObj) {
+ //Probe variables
+ if (treeObj.getData() instanceof ProbevarNodeData) {
+ List<String> varTypes = ((ProbevarNodeData) treeObj.getData()).getTypes();
+ if (varTypes.get(varTypes.size()-1).endsWith("*")) { //Pointers //$NON-NLS-1$
+ return IDEPlugin.getImageDescriptor("icons/vars/var_long.gif").createImage(); //$NON-NLS-1$
+ }
+ if (varTypes.contains("struct")) {//$NON-NLS-1$
+ return IDEPlugin.getImageDescriptor("icons/vars/var_struct.gif").createImage(); //$NON-NLS-1$
+ }
+ if (varTypes.contains("string")) {//$NON-NLS-1$
+ return IDEPlugin.getImageDescriptor("icons/vars/var_str.gif").createImage(); //$NON-NLS-1$
+ }
+ if (varTypes.contains("unknown")) {//$NON-NLS-1$
+ return IDEPlugin.getImageDescriptor("icons/vars/var_unk.gif").createImage(); //$NON-NLS-1$
+ }
+ // All other types are displayed as long
+ return IDEPlugin.getImageDescriptor("icons/vars/var_long.gif").createImage(); //$NON-NLS-1$
+ }
- //Non-variable icons
- if (treeObj.getData() instanceof ProbeNodeData) {
- return IDEPlugin.getImageDescriptor("icons/misc/probe_obj.gif").createImage(); //$NON-NLS-1$
- }
- return getGenericImage(treeObj);
- }
+ //Non-variable icons
+ if (treeObj.getData() instanceof ProbeNodeData) {
+ return IDEPlugin.getImageDescriptor("icons/misc/probe_obj.gif").createImage(); //$NON-NLS-1$
+ }
+ return getGenericImage(treeObj);
+ }
- /**
- * Refreshes the list of probe aliases in the viewer.
- */
- @Override
- public void refresh() {
- TreeNode probes = TapsetLibrary.getProbes();
- if (probes != null){
- super.viewer.setInput(probes);
- }
- }
+ /**
+ * Refreshes the list of probe aliases in the viewer.
+ */
+ @Override
+ public void refresh() {
+ TreeNode probes = TapsetLibrary.getProbes();
+ if (probes != null){
+ super.viewer.setInput(probes);
+ }
+ }
- /**
- * Wires up all of the actions for this browser, such as double and right click handlers.
- */
- private void makeActions() {
- doubleClickAction = new ProbeAliasAction(getSite().getWorkbenchWindow(), this);
- viewer.addDoubleClickListener(doubleClickAction);
- registerContextMenu("probePopup"); //$NON-NLS-1$
- }
+ /**
+ * Wires up all of the actions for this browser, such as double and right click handlers.
+ */
+ private void makeActions() {
+ doubleClickAction = new ProbeAliasAction(getSite().getWorkbenchWindow(), this);
+ viewer.addDoubleClickListener(doubleClickAction);
+ registerContextMenu("probePopup"); //$NON-NLS-1$
+ }
- @Override
- public void dispose() {
- super.dispose();
- if (null != viewer) {
- viewer.removeDoubleClickListener(doubleClickAction);
- }
- if (null != doubleClickAction) {
- doubleClickAction.dispose();
- }
- doubleClickAction = null;
- }
+ @Override
+ public void dispose() {
+ super.dispose();
+ if (null != viewer) {
+ viewer.removeDoubleClickListener(doubleClickAction);
+ }
+ if (null != doubleClickAction) {
+ doubleClickAction.dispose();
+ }
+ doubleClickAction = null;
+ }
}
diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/wizards/StapNewWizard.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/wizards/StapNewWizard.java
index 0de1de2566..4c220dcdbc 100644
--- a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/wizards/StapNewWizard.java
+++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/wizards/StapNewWizard.java
@@ -45,100 +45,100 @@ import org.eclipse.ui.ide.IDE;
*/
public class StapNewWizard extends Wizard implements INewWizard {
- private StapNewWizardPage page;
- private ISelection selection;
- private static final ResourceBundle resourceBundle = ResourceBundle.getBundle("org.eclipse.linuxtools.internal.systemtap.ui.ide.wizards.stap_strings"); //$NON-NLS-1$
+ private StapNewWizardPage page;
+ private ISelection selection;
+ private static final ResourceBundle resourceBundle = ResourceBundle.getBundle("org.eclipse.linuxtools.internal.systemtap.ui.ide.wizards.stap_strings"); //$NON-NLS-1$
- /**
- * Constructor for StapNewWizard.
- */
- public StapNewWizard() {
- super();
- setNeedsProgressMonitor(true);
- }
+ /**
+ * Constructor for StapNewWizard.
+ */
+ public StapNewWizard() {
+ super();
+ setNeedsProgressMonitor(true);
+ }
- /**
- * Adding the page to the wizard.
- */
+ /**
+ * Adding the page to the wizard.
+ */
- @Override
- public void addPages() {
- page = new StapNewWizardPage(selection);
- addPage(page);
- }
+ @Override
+ public void addPages() {
+ page = new StapNewWizardPage(selection);
+ addPage(page);
+ }
- /**
- * This method is called when 'Finish' button is pressed in
- * the wizard. We will create an operation and run it
- * using wizard as execution context.
- */
- @Override
- public boolean performFinish() {
- final String containerName = page.getContainerName();
- final String fileName = page.getFileName();
- IRunnableWithProgress op = new IRunnableWithProgress() {
- @Override
- public void run(IProgressMonitor monitor) throws InvocationTargetException {
- try {
- doFinish(containerName, fileName, monitor);
- } catch (CoreException e) {
- throw new InvocationTargetException(e);
- } finally {
- monitor.done();
- }
- }
- };
- try {
- getContainer().run(true, false, op);
- } catch (InterruptedException e) {
- MessageDialog.openError(getShell(), "Error", e.getLocalizedMessage()); //$NON-NLS-1$
- return false;
- } catch (InvocationTargetException e) {
- Throwable realException = e.getTargetException();
- MessageDialog.openError(getShell(), "Error", realException.getMessage()); //$NON-NLS-1$
- return false;
- }
- return true;
- }
+ /**
+ * This method is called when 'Finish' button is pressed in
+ * the wizard. We will create an operation and run it
+ * using wizard as execution context.
+ */
+ @Override
+ public boolean performFinish() {
+ final String containerName = page.getContainerName();
+ final String fileName = page.getFileName();
+ IRunnableWithProgress op = new IRunnableWithProgress() {
+ @Override
+ public void run(IProgressMonitor monitor) throws InvocationTargetException {
+ try {
+ doFinish(containerName, fileName, monitor);
+ } catch (CoreException e) {
+ throw new InvocationTargetException(e);
+ } finally {
+ monitor.done();
+ }
+ }
+ };
+ try {
+ getContainer().run(true, false, op);
+ } catch (InterruptedException e) {
+ MessageDialog.openError(getShell(), "Error", e.getLocalizedMessage()); //$NON-NLS-1$
+ return false;
+ } catch (InvocationTargetException e) {
+ Throwable realException = e.getTargetException();
+ MessageDialog.openError(getShell(), "Error", realException.getMessage()); //$NON-NLS-1$
+ return false;
+ }
+ return true;
+ }
- /**
- * The worker method. It will find the container, create the
- * file if missing or just replace its contents, and open
- * the editor on the newly created file.
- */
+ /**
+ * The worker method. It will find the container, create the
+ * file if missing or just replace its contents, and open
+ * the editor on the newly created file.
+ */
- private void doFinish(String containerName, String fileName, IProgressMonitor monitor) throws CoreException {
- // create a .stp file
+ private void doFinish(String containerName, String fileName, IProgressMonitor monitor) throws CoreException {
+ // create a .stp file
- monitor.beginTask(resourceBundle.getString("StapNewWizard.BeginTask") + fileName, 2); //$NON-NLS-1$
- final IContainer newResource = (IContainer) ResourcesPlugin.getWorkspace().getRoot().findMember(containerName);
- final IFile newFile = newResource.getFile(new Path(fileName));
- String envString = "#!/usr/bin/env stap"; //$NON-NLS-1$
- newFile.create(new ByteArrayInputStream(envString.getBytes()) , true, monitor);
- monitor.worked(1);
- monitor.setTaskName(resourceBundle.getString("StapNewWizard.SetTask")); //$NON-NLS-1$
- getShell().getDisplay().asyncExec(new Runnable() {
- @Override
- public void run() {
- try {
- IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getWorkbench()
- .showPerspective(IDEPerspective.ID, PlatformUI.getWorkbench().getActiveWorkbenchWindow());
- IDE.openEditor(page, newFile);
- } catch (WorkbenchException e1) {
- // ignore, the file is created but opening the editor failed
- }
- }
- });
- monitor.worked(1);
- }
+ monitor.beginTask(resourceBundle.getString("StapNewWizard.BeginTask") + fileName, 2); //$NON-NLS-1$
+ final IContainer newResource = (IContainer) ResourcesPlugin.getWorkspace().getRoot().findMember(containerName);
+ final IFile newFile = newResource.getFile(new Path(fileName));
+ String envString = "#!/usr/bin/env stap"; //$NON-NLS-1$
+ newFile.create(new ByteArrayInputStream(envString.getBytes()) , true, monitor);
+ monitor.worked(1);
+ monitor.setTaskName(resourceBundle.getString("StapNewWizard.SetTask")); //$NON-NLS-1$
+ getShell().getDisplay().asyncExec(new Runnable() {
+ @Override
+ public void run() {
+ try {
+ IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getWorkbench()
+ .showPerspective(IDEPerspective.ID, PlatformUI.getWorkbench().getActiveWorkbenchWindow());
+ IDE.openEditor(page, newFile);
+ } catch (WorkbenchException e1) {
+ // ignore, the file is created but opening the editor failed
+ }
+ }
+ });
+ monitor.worked(1);
+ }
- /**
- * We will accept the selection in the workbench to see if
- * we can initialize from it.
- * @see INewWizard#init(IWorkbench, IStructuredSelection)
- */
- @Override
- public void init(IWorkbench workbench, IStructuredSelection selection) {
- this.selection = selection;
- }
+ /**
+ * We will accept the selection in the workbench to see if
+ * we can initialize from it.
+ * @see INewWizard#init(IWorkbench, IStructuredSelection)
+ */
+ @Override
+ public void init(IWorkbench workbench, IStructuredSelection selection) {
+ this.selection = selection;
+ }
}
diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/wizards/StapNewWizardPage.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/wizards/StapNewWizardPage.java
index d71aa13eb6..986a884d5c 100644
--- a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/wizards/StapNewWizardPage.java
+++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/wizards/StapNewWizardPage.java
@@ -41,162 +41,162 @@ import org.eclipse.ui.dialogs.ContainerSelectionDialog;
*/
public class StapNewWizardPage extends WizardPage {
- private Text fileText;
-
- private Text containerText;
-
- private ISelection selection;
-
- private static final ResourceBundle resourceBundle = ResourceBundle.getBundle("org.eclipse.linuxtools.internal.systemtap.ui.ide.wizards.stap_strings"); //$NON-NLS-1$
-
- /**
- * Constructor for StapNewWizardPage.
- *
- * @param pageName
- */
- public StapNewWizardPage(ISelection selection) {
- super(resourceBundle.getString("StapNewWizardPage.WizardPage")); //$NON-NLS-1$
- setTitle(resourceBundle.getString("StapNewWizardPage.Title")); //$NON-NLS-1$
- setDescription(resourceBundle.getString("StapNewWizardPage.setDescription")); //$NON-NLS-1$
- this.selection = selection;
- }
-
- /**
- * @see WizardPage#createControl(Composite)
- */
- @Override
- public void createControl(Composite parent) {
- Composite container = new Composite(parent, SWT.NULL);
- GridLayout layout = new GridLayout();
- container.setLayout(layout);
- layout.numColumns = 3;
- layout.verticalSpacing = 9;
-
- Label label = new Label(container, SWT.NULL);
- label.setText(resourceBundle.getString("StapNewWizardPage.ScriptName")); //$NON-NLS-1$
-
- fileText = new Text(container, SWT.BORDER | SWT.SINGLE);
- GridData gd = new GridData(GridData.FILL_HORIZONTAL);
- fileText.setLayoutData(gd);
- fileText.addModifyListener(new ModifyListener() {
- @Override
- public void modifyText(ModifyEvent e) {
- dialogChanged();
- }
- });
- new Label(container, SWT.NULL); // XXX just create a new layout with different width
-
- label = new Label(container, SWT.NULL);
- label.setText(resourceBundle.getString("StapNewWizardPage.Project")); //$NON-NLS-1$
-
- containerText = new Text(container, SWT.BORDER | SWT.SINGLE);
- gd = new GridData(GridData.FILL_HORIZONTAL);
- containerText.setLayoutData(gd);
- containerText.addModifyListener(new ModifyListener() {
- @Override
- public void modifyText(ModifyEvent e) {
- dialogChanged();
- }
- });
-
- Button button = new Button(container, SWT.PUSH);
- button.setText(resourceBundle.getString("StapNewWizardPage.Browse")); //$NON-NLS-1$
- button.addSelectionListener(new SelectionAdapter() {
- @Override
- public void widgetSelected(SelectionEvent e) {
- handleBrowse();
- }
- });
- initialize();
- dialogChanged();
- setControl(container);
- }
-
- /**
- * Tests if the current workbench selection is a suitable container to use.
- */
-
- private void initialize() {
- if (selection != null && selection.isEmpty() == false
- && selection instanceof IStructuredSelection) {
- IStructuredSelection ssel = (IStructuredSelection) selection;
- if (ssel.size() > 1) {
- return;
- }
- Object obj = ssel.getFirstElement();
- if (obj instanceof IResource) {
- IContainer container;
- if (obj instanceof IContainer) {
- container = (IContainer) obj;
- } else {
- container = ((IResource) obj).getParent();
- }
- containerText.setText(container.getFullPath().toString());
- }
- }
- fileText.setText(".stp"); //$NON-NLS-1$
- }
-
- /**
- * Uses the standard container selection dialog to choose the new value for
- * the container field.
- */
- private void handleBrowse() {
- ContainerSelectionDialog dialog = new ContainerSelectionDialog(
- getShell(), ResourcesPlugin.getWorkspace().getRoot(), false, resourceBundle.getString("StapNewWizardPage.SelectProjectMessage")); //$NON-NLS-1$
- if (dialog.open() == Window.OK) {
- Object[] result = dialog.getResult();
- if (result.length == 1) {
- containerText.setText(((Path) result[0]).toString());
- }
- }
- }
-
- /**
- * Ensures that both text fields are set.
- */
-
- private void dialogChanged() {
- IPath container = Path.fromOSString(getContainerName());
- String fileName = getFileName();
- if (fileName.length() == 0 || fileName.equals(".stp")) { //$NON-NLS-1$
- updateStatus(resourceBundle.getString("StapNewWizardPage.UpdateStatus1")); //$NON-NLS-1$
- return;
- }
- if (getContainerName().length() == 0) {
- updateStatus(resourceBundle.getString("StapNewWizardPage.UpdateStatus2")); //$NON-NLS-1$
- return;
- }
- if (container == null
- || !container.isValidPath(getContainerName())) {
- updateStatus(resourceBundle.getString("StapNewWizardPage.UpdateStatus3")); //$NON-NLS-1$
- return;
- }
- if (fileName.replace('\\', '/').indexOf('/', 1) > 0) {
- updateStatus(resourceBundle.getString("StapNewWizardPage.UpdateStatus4")); //$NON-NLS-1$
- return;
- }
- int dotLoc = fileName.lastIndexOf('.');
- if (dotLoc != -1) {
- String ext = fileName.substring(dotLoc + 1);
- if (ext.equalsIgnoreCase("stp") == false) { //$NON-NLS-1$
- updateStatus(resourceBundle.getString("StapNewWizardPage.UpdateStatus.5")); //$NON-NLS-1$
- return;
- }
- }
- updateStatus(null);
- }
-
- private void updateStatus(String message) {
- setErrorMessage(message);
- setPageComplete(message == null);
- }
-
- public String getContainerName() {
- return containerText.getText();
- }
-
- public String getFileName() {
- return fileText.getText();
- }
+ private Text fileText;
+
+ private Text containerText;
+
+ private ISelection selection;
+
+ private static final ResourceBundle resourceBundle = ResourceBundle.getBundle("org.eclipse.linuxtools.internal.systemtap.ui.ide.wizards.stap_strings"); //$NON-NLS-1$
+
+ /**
+ * Constructor for StapNewWizardPage.
+ *
+ * @param pageName
+ */
+ public StapNewWizardPage(ISelection selection) {
+ super(resourceBundle.getString("StapNewWizardPage.WizardPage")); //$NON-NLS-1$
+ setTitle(resourceBundle.getString("StapNewWizardPage.Title")); //$NON-NLS-1$
+ setDescription(resourceBundle.getString("StapNewWizardPage.setDescription")); //$NON-NLS-1$
+ this.selection = selection;
+ }
+
+ /**
+ * @see WizardPage#createControl(Composite)
+ */
+ @Override
+ public void createControl(Composite parent) {
+ Composite container = new Composite(parent, SWT.NULL);
+ GridLayout layout = new GridLayout();
+ container.setLayout(layout);
+ layout.numColumns = 3;
+ layout.verticalSpacing = 9;
+
+ Label label = new Label(container, SWT.NULL);
+ label.setText(resourceBundle.getString("StapNewWizardPage.ScriptName")); //$NON-NLS-1$
+
+ fileText = new Text(container, SWT.BORDER | SWT.SINGLE);
+ GridData gd = new GridData(GridData.FILL_HORIZONTAL);
+ fileText.setLayoutData(gd);
+ fileText.addModifyListener(new ModifyListener() {
+ @Override
+ public void modifyText(ModifyEvent e) {
+ dialogChanged();
+ }
+ });
+ new Label(container, SWT.NULL); // XXX just create a new layout with different width
+
+ label = new Label(container, SWT.NULL);
+ label.setText(resourceBundle.getString("StapNewWizardPage.Project")); //$NON-NLS-1$
+
+ containerText = new Text(container, SWT.BORDER | SWT.SINGLE);
+ gd = new GridData(GridData.FILL_HORIZONTAL);
+ containerText.setLayoutData(gd);
+ containerText.addModifyListener(new ModifyListener() {
+ @Override
+ public void modifyText(ModifyEvent e) {
+ dialogChanged();
+ }
+ });
+
+ Button button = new Button(container, SWT.PUSH);
+ button.setText(resourceBundle.getString("StapNewWizardPage.Browse")); //$NON-NLS-1$
+ button.addSelectionListener(new SelectionAdapter() {
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ handleBrowse();
+ }
+ });
+ initialize();
+ dialogChanged();
+ setControl(container);
+ }
+
+ /**
+ * Tests if the current workbench selection is a suitable container to use.
+ */
+
+ private void initialize() {
+ if (selection != null && selection.isEmpty() == false
+ && selection instanceof IStructuredSelection) {
+ IStructuredSelection ssel = (IStructuredSelection) selection;
+ if (ssel.size() > 1) {
+ return;
+ }
+ Object obj = ssel.getFirstElement();
+ if (obj instanceof IResource) {
+ IContainer container;
+ if (obj instanceof IContainer) {
+ container = (IContainer) obj;
+ } else {
+ container = ((IResource) obj).getParent();
+ }
+ containerText.setText(container.getFullPath().toString());
+ }
+ }
+ fileText.setText(".stp"); //$NON-NLS-1$
+ }
+
+ /**
+ * Uses the standard container selection dialog to choose the new value for
+ * the container field.
+ */
+ private void handleBrowse() {
+ ContainerSelectionDialog dialog = new ContainerSelectionDialog(
+ getShell(), ResourcesPlugin.getWorkspace().getRoot(), false, resourceBundle.getString("StapNewWizardPage.SelectProjectMessage")); //$NON-NLS-1$
+ if (dialog.open() == Window.OK) {
+ Object[] result = dialog.getResult();
+ if (result.length == 1) {
+ containerText.setText(((Path) result[0]).toString());
+ }
+ }
+ }
+
+ /**
+ * Ensures that both text fields are set.
+ */
+
+ private void dialogChanged() {
+ IPath container = Path.fromOSString(getContainerName());
+ String fileName = getFileName();
+ if (fileName.length() == 0 || fileName.equals(".stp")) { //$NON-NLS-1$
+ updateStatus(resourceBundle.getString("StapNewWizardPage.UpdateStatus1")); //$NON-NLS-1$
+ return;
+ }
+ if (getContainerName().length() == 0) {
+ updateStatus(resourceBundle.getString("StapNewWizardPage.UpdateStatus2")); //$NON-NLS-1$
+ return;
+ }
+ if (container == null
+ || !container.isValidPath(getContainerName())) {
+ updateStatus(resourceBundle.getString("StapNewWizardPage.UpdateStatus3")); //$NON-NLS-1$
+ return;
+ }
+ if (fileName.replace('\\', '/').indexOf('/', 1) > 0) {
+ updateStatus(resourceBundle.getString("StapNewWizardPage.UpdateStatus4")); //$NON-NLS-1$
+ return;
+ }
+ int dotLoc = fileName.lastIndexOf('.');
+ if (dotLoc != -1) {
+ String ext = fileName.substring(dotLoc + 1);
+ if (ext.equalsIgnoreCase("stp") == false) { //$NON-NLS-1$
+ updateStatus(resourceBundle.getString("StapNewWizardPage.UpdateStatus.5")); //$NON-NLS-1$
+ return;
+ }
+ }
+ updateStatus(null);
+ }
+
+ private void updateStatus(String message) {
+ setErrorMessage(message);
+ setPageComplete(message == null);
+ }
+
+ public String getContainerName() {
+ return containerText.getText();
+ }
+
+ public String getFileName() {
+ return fileText.getText();
+ }
}

Back to the top