From 0e1e5f99ae313baf039e16b403158bd4f7292e1e Mon Sep 17 00:00:00 2001 From: Marc Khouzam Date: Thu, 30 Jul 2009 17:11:10 +0000 Subject: [PATCH] [285170] Output secondary prompt (">") ourselves if we are not properly getting it from the backend. Also, add a space after the secondary prompt for readability. --- .../service/command/AbstractCLIProcess.java | 80 ++++++++++++++++--- 1 file changed, 69 insertions(+), 11 deletions(-) diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/command/AbstractCLIProcess.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/command/AbstractCLIProcess.java index d96257bdf69..5b4e5f26b4f 100644 --- a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/command/AbstractCLIProcess.java +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/command/AbstractCLIProcess.java @@ -32,6 +32,7 @@ import org.eclipse.cdt.dsf.debug.service.command.ICommandToken; import org.eclipse.cdt.dsf.debug.service.command.IEventListener; import org.eclipse.cdt.dsf.gdb.internal.GdbPlugin; import org.eclipse.cdt.dsf.mi.service.command.commands.CLICommand; +import org.eclipse.cdt.dsf.mi.service.command.commands.MICommand; import org.eclipse.cdt.dsf.mi.service.command.commands.MIInterpreterExecConsole; import org.eclipse.cdt.dsf.mi.service.command.commands.RawCommand; import org.eclipse.cdt.dsf.mi.service.command.output.MIConsoleStreamOutput; @@ -57,6 +58,9 @@ public abstract class AbstractCLIProcess extends Process { public static final String PRIMARY_PROMPT = "(gdb)"; //$NON-NLS-1$ public static final String SECONDARY_PROMPT = ">"; //$NON-NLS-1$ + + // This is the command that will end a secondary prompt + private static final String SECONDARY_PROMPT_END_COMMAND = "end"; //$NON-NLS-1$ private final DsfSession fSession; private final ICommandControlService fCommandControl; @@ -83,8 +87,13 @@ public abstract class AbstractCLIProcess extends Process * the console output. */ private int fSuppressConsoleOutputCounter = 0; - - private int fPrompt = 1; // 1 --> Primary prompt "(gdb)"; 2 --> Secondary Prompt ">" + + // Primary prompt == "(gdb)" + // Secondary Prompt == ">" + // Secondary_prompt_missing means that the backend should be sending the secondary + // prompt but it isn't. So we do it ourselves. + private enum PromptType { IN_PRIMARY_PROMPT, IN_SECONDARY_PROMPT, IN_SECONDARY_PROMPT_MISSING }; + private PromptType fPrompt = PromptType.IN_PRIMARY_PROMPT; /** * @since 1.1 @@ -188,7 +197,20 @@ public abstract class AbstractCLIProcess extends Process { MIConsoleStreamOutput out = (MIConsoleStreamOutput) oobr; String str = out.getString(); - // Process the console stream too. + + if (str.trim().equals(SECONDARY_PROMPT)) { + // Make sure to skip any secondary prompt that we + // have already printed ourselves. This would happen + // when a new version of the backend starts sending + // the secondary prompt for a command that it didn't + // use to. In this case, we still send it ourselves. + if (inMissingSecondaryPrompt()) { + return; + } + // Add a space for readability + str = SECONDARY_PROMPT + ' '; + } + setPrompt(str); try { fMIOutConsolePipe.write(str.getBytes()); @@ -228,10 +250,14 @@ public abstract class AbstractCLIProcess extends Process // Bug 285170 // Deal with missing secondary prompt, if needed. - checkMissingSecondaryPrompt(command); + // The only two types we care about are ProcessMIInterpreterExecConsole + // and RawCommand, both of which are MICommands + if (command instanceof MICommand) { + checkMissingSecondaryPrompt((MICommand)command); + } } - private void checkMissingSecondaryPrompt(ICommand command) { + private void checkMissingSecondaryPrompt(MICommand command) { // If the command send is one of ours, check if it is one that is missing a secondary prompt if (command instanceof ProcessMIInterpreterExecConsole) { String[] operations = ((ProcessMIInterpreterExecConsole)command).getParameters(); @@ -251,10 +277,35 @@ public abstract class AbstractCLIProcess extends Process // a commandDone() call. // This logic will still work when a new version of the backend // fixes this lack of secondary prompt. - fPrompt = 2; + fPrompt = PromptType.IN_SECONDARY_PROMPT_MISSING; } } } + + // Even if the previous check didn't kick in, we may already be in the missing + // secondary prompt case. If so, we'll print the prompt ourselves. + // Just make sure that this command is not ending the secondary prompt. + if (fPrompt == PromptType.IN_SECONDARY_PROMPT_MISSING) { + String operation = command.getOperation(); + if (operation != null) { + int indx = operation.indexOf(' '); + if (indx != -1) { + operation = operation.substring(0, indx).trim(); + } else { + operation = operation.trim(); + } + + if (!operation.equals(SECONDARY_PROMPT_END_COMMAND)) { + // Add a space for readability + String str = SECONDARY_PROMPT + ' '; + try { + fMIOutConsolePipe.write(str.getBytes()); + fMIOutConsolePipe.flush(); + } catch (IOException e) { + } + } + } + } } /** @@ -274,7 +325,7 @@ public abstract class AbstractCLIProcess extends Process public void commandDone(ICommandToken token, ICommandResult result) { // Whenever we get a command that is completed, we know we must be in the primary prompt - fPrompt = 1; + fPrompt = PromptType.IN_PRIMARY_PROMPT; ICommand command = token.getCommand(); if (token.getCommand() instanceof CLICommand && @@ -285,24 +336,31 @@ public abstract class AbstractCLIProcess extends Process } void setPrompt(String line) { - fPrompt = 1; + fPrompt = PromptType.IN_PRIMARY_PROMPT; // See https://bugs.eclipse.org/bugs/show_bug.cgi?id=109733 if (line == null) return; line = line.trim(); if (line.equals(SECONDARY_PROMPT)) { - fPrompt = 2; + fPrompt = PromptType.IN_SECONDARY_PROMPT; } } public boolean inPrimaryPrompt() { - return fPrompt == 1; + return fPrompt == PromptType.IN_PRIMARY_PROMPT; } public boolean inSecondaryPrompt() { - return fPrompt == 2; + return fPrompt == PromptType.IN_SECONDARY_PROMPT || fPrompt == PromptType.IN_SECONDARY_PROMPT_MISSING; } + /** + * @since 2.1 + */ + public boolean inMissingSecondaryPrompt() { + return fPrompt == PromptType.IN_SECONDARY_PROMPT_MISSING; + } + private boolean isMIOperation(String operation) { // The definition of an MI command states that it starts with // [ token ] "-"