Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'debug/org.eclipse.cdt.debug.mi.core/mi/org/eclipse/cdt/debug/mi/core/output/MIParser.java')
-rw-r--r--debug/org.eclipse.cdt.debug.mi.core/mi/org/eclipse/cdt/debug/mi/core/output/MIParser.java564
1 files changed, 0 insertions, 564 deletions
diff --git a/debug/org.eclipse.cdt.debug.mi.core/mi/org/eclipse/cdt/debug/mi/core/output/MIParser.java b/debug/org.eclipse.cdt.debug.mi.core/mi/org/eclipse/cdt/debug/mi/core/output/MIParser.java
deleted file mode 100644
index dbb778bc151..00000000000
--- a/debug/org.eclipse.cdt.debug.mi.core/mi/org/eclipse/cdt/debug/mi/core/output/MIParser.java
+++ /dev/null
@@ -1,564 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2000, 2006 QNX Software Systems and others.
- * 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:
- * QNX Software Systems - Initial API and implementation
- *******************************************************************************/
-package org.eclipse.cdt.debug.mi.core.output;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.StringTokenizer;
-
-/**
-<pre>
-`OUTPUT :'
- `( OUT-OF-BAND-RECORD )* [ RESULT-RECORD ] "(gdb)" NL'
-
-`RESULT-RECORD :'
- ` [ TOKEN ] "^" RESULT-CLASS ( "," RESULT )* NL'
-
-`OUT-OF-BAND-RECORD :'
- `ASYNC-RECORD | STREAM-RECORD'
-
-`ASYNC-RECORD :'
- `EXEC-ASYNC-OUTPUT | STATUS-ASYNC-OUTPUT | NOTIFY-ASYNC-OUTPUT'
-
-`EXEC-ASYNC-OUTPUT :'
- `[ TOKEN ] "*" ASYNC-OUTPUT'
-
-`STATUS-ASYNC-OUTPUT :'
- `[ TOKEN ] "+" ASYNC-OUTPUT'
-
-`NOTIFY-ASYNC-OUTPUT :'
- `[ TOKEN ] "=" ASYNC-OUTPUT'
-
-`ASYNC-OUTPUT :'
- `ASYNC-CLASS ( "," RESULT )* NL'
-
-`RESULT-CLASS :'
- `"done" | "running" | "connected" | "error" | "exit"'
-
-`ASYNC-CLASS :'
- `"stopped" | OTHERS' (where OTHERS will be added depending on the
- needs--this is still in development).
-
-`RESULT :'
- ` VARIABLE "=" VALUE'
-
-`VARIABLE :'
- ` STRING '
-
-`VALUE :'
- ` CONST | TUPLE | LIST '
-
-`CONST :'
- `C-STRING'
-
-`TUPLE :'
- ` "{}" | "{" RESULT ( "," RESULT )* "}" '
-
-`LIST :'
- ` "[]" | "[" VALUE ( "," VALUE )* "]" | "[" RESULT ( "," RESULT )*
- "]" '
-
-`STREAM-RECORD :'
- `CONSOLE-STREAM-OUTPUT | TARGET-STREAM-OUTPUT | LOG-STREAM-OUTPUT'
-
-`CONSOLE-STREAM-OUTPUT :'
- `"~" C-STRING'
-
-`TARGET-STREAM-OUTPUT :'
- `"@" C-STRING'
-
-`LOG-STREAM-OUTPUT :'
- `"&" C-STRING'
-
-`NL :'
- `CR | CR-LF'
-
-`TOKEN :'
- _any sequence of digits_.
-
-`C-STRING :'
- `""" SEVEN-BIT-ISO-C-STRING-CONTENT """'
-</pre>
- */
-public class MIParser {
-
- public String primaryPrompt = "(gdb)"; //$NON-NLS-1$
- public String cliPrompt = primaryPrompt;
- public String secondaryPrompt = ">"; //$NON-NLS-1$
-
- /**
- * Point of entry to create an AST for MI.
- *
- * @param buffer Output from MI Channel.
- * @return MIOutput
- * @see MIOutput
- */
- public MIOutput parse(String buffer) {
- MIOutput mi = new MIOutput();
- MIResultRecord rr = null;
- List oobs = new ArrayList(1);
- int id = -1;
-
- StringTokenizer st = new StringTokenizer(buffer, "\n"); //$NON-NLS-1$
- while (st.hasMoreTokens()) {
- StringBuffer token = new StringBuffer(st.nextToken());
-
- // Fetch the Token/Id
- if (token.length() > 0 && Character.isDigit(token.charAt(0))) {
- int i = 1;
- while (i < token.length() && Character.isDigit(token.charAt(i))) {
- i++;
- }
- String numbers = token.substring(0, i);
- try {
- id = Integer.parseInt(numbers);
- } catch (NumberFormatException e) {
- }
- // Consume the token.
- token.delete(0, i);
- }
-
- // ResultRecord ||| Out-Of-Band Records
- if (token.length() > 0) {
- if (token.charAt(0) == '^') {
- token.deleteCharAt(0);
- rr = processMIResultRecord(token, id);
- } else if (startsWith(token, primaryPrompt)) {
- //break; // Do nothing.
- } else {
- MIOOBRecord band = processMIOOBRecord(token, id);
- if (band != null) {
- oobs.add(band);
- }
- }
- }
- }
- MIOOBRecord[] bands = (MIOOBRecord[]) oobs.toArray(new MIOOBRecord[oobs.size()]);
- mi.setMIOOBRecords(bands);
- mi.setMIResultRecord(rr);
- return mi;
- }
-
- /**
- * Assuming '^' was deleted from the Result Record.
- */
- private MIResultRecord processMIResultRecord(StringBuffer buffer, int id) {
- MIResultRecord rr = new MIResultRecord();
- rr.setToken(id);
- if (buffer.toString().startsWith(MIResultRecord.DONE)) {
- rr.setResultClass(MIResultRecord.DONE);
- buffer.delete(0, MIResultRecord.DONE.length());
- } else if (buffer.toString().startsWith(MIResultRecord.ERROR)) {
- rr.setResultClass(MIResultRecord.ERROR);
- buffer.delete(0, MIResultRecord.ERROR.length());
- } else if (buffer.toString().startsWith(MIResultRecord.EXIT)) {
- rr.setResultClass(MIResultRecord.EXIT);
- buffer.delete(0, MIResultRecord.EXIT.length());
- } else if (buffer.toString().startsWith(MIResultRecord.RUNNING)) {
- rr.setResultClass(MIResultRecord.RUNNING);
- buffer.delete(0, MIResultRecord.RUNNING.length());
- } else if (buffer.toString().startsWith(MIResultRecord.CONNECTED)) {
- rr.setResultClass(MIResultRecord.CONNECTED);
- buffer.delete(0, MIResultRecord.CONNECTED.length());
- } else {
- // FIXME:
- // Error throw an exception?
- }
-
- // Results are separated by commas.
- if (buffer.length() > 0 && buffer.charAt(0) == ',') {
- buffer.deleteCharAt(0);
- MIResult[] res = processMIResults(new FSB(buffer));
- rr.setMIResults(res);
- }
- return rr;
- }
-
- /**
- * Find OutOfBand Records depending on the starting token.
- */
- private MIOOBRecord processMIOOBRecord(StringBuffer buffer, int id) {
- MIOOBRecord oob = null;
- char c = buffer.charAt(0);
- if (c == '*' || c == '+' || c == '=') {
- // Consume the first char
- buffer.deleteCharAt(0);
- MIAsyncRecord async = null;
- switch (c) {
- case '*' :
- async = new MIExecAsyncOutput();
- break;
-
- case '+' :
- async = new MIStatusAsyncOutput();
- break;
-
- case '=' :
- async = new MINotifyAsyncOutput();
- break;
- }
- async.setToken(id);
- // Extract the Async-Class
- int i = buffer.toString().indexOf(',');
- if (i != -1) {
- String asyncClass = buffer.substring(0, i);
- async.setAsyncClass(asyncClass);
- // Consume the async-class and the comma
- buffer.delete(0, i + 1);
- } else {
- async.setAsyncClass(buffer.toString().trim());
- buffer.setLength(0);
- }
- MIResult[] res = processMIResults(new FSB(buffer));
- async.setMIResults(res);
- oob = async;
- } else if (c == '~' || c == '@' || c == '&') {
- // Consume the first char
- buffer.deleteCharAt(0);
- MIStreamRecord stream = null;
- switch (c) {
- case '~' :
- stream = new MIConsoleStreamOutput();
- break;
-
- case '@' :
- stream = new MITargetStreamOutput();
- break;
-
- case '&' :
- stream = new MILogStreamOutput();
- break;
- }
- // translateCString() assumes that the leading " is deleted
- if (buffer.length() > 0 && buffer.charAt(0) == '"') {
- buffer.deleteCharAt(0);
- }
- stream.setCString(translateCString(new FSB(buffer)));
- oob = stream;
- } else {
- // Badly format MI line, just pass it to the user as target stream
- MIStreamRecord stream = new MITargetStreamOutput();
- stream.setCString(buffer.toString() + "\n"); //$NON-NLS-1$
- oob = stream;
- }
- return oob;
- }
-
- /**
- * Assuming that the usual leading comma was consumed.
- * Extract the MI Result comma seperated responses.
- */
- private MIResult[] processMIResults(FSB buffer) {
- List aList = new ArrayList();
- MIResult result = processMIResult(buffer);
- if (result != null) {
- aList.add(result);
- }
- while (buffer.length() > 0 && buffer.charAt(0) == ',') {
- buffer.deleteCharAt(0);
- result = processMIResult(buffer);
- if (result != null) {
- aList.add(result);
- }
- }
- return (MIResult[]) aList.toArray(new MIResult[aList.size()]);
- }
-
- /**
- * Construct the MIResult. Characters will be consume/delete
- * moving forward constructing the AST.
- */
- private MIResult processMIResult(FSB buffer) {
- MIResult result = new MIResult();
- int equal;
- if (buffer.length() > 0 && Character.isLetter(buffer.charAt(0)) && (equal = buffer.indexOf('=')) != -1) {
- String variable = buffer.substring(0, equal);
- result.setVariable(variable);
- buffer.delete(0, equal + 1);
- MIValue value = processMIValue(buffer);
- result.setMIValue(value);
- } else if(buffer.length()>0 && buffer.charAt(0)=='"') {
- // This an error but we just swallow it and move on.
- MIValue value = processMIValue(buffer);
- result.setMIValue(value);
- } else {
- result.setVariable(buffer.toString());
- result.setMIValue(new MIConst()); // Empty string:???
- buffer.setLength(0);
- }
- return result;
- }
-
- /**
- * Find a MIValue implementation or return null.
- */
- private MIValue processMIValue(FSB buffer) {
- MIValue value = null;
- if (buffer.length() > 0) {
- if (buffer.charAt(0) == '{') {
- buffer.deleteCharAt(0);
- value = processMITuple(buffer);
- } else if (buffer.charAt(0) == '[') {
- buffer.deleteCharAt(0);
- value = processMIList(buffer);
- } else if (buffer.charAt(0) == '"') {
- buffer.deleteCharAt(0);
- MIConst cnst = new MIConst();
- cnst.setCString(translateCString(buffer));
- value = cnst;
- }
- }
- return value;
- }
-
- /**
- * Assuming the starting '{' was deleted form the StringBuffer,
- * go to the closing '}' consuming/deleting all the characters.
- * This is usually call by processMIvalue();
- */
- private MIValue processMITuple(FSB buffer) {
- MITuple tuple = new MITuple();
- List valueList = new ArrayList();
- List resultList = new ArrayList();
- // Catch closing '}'
- while (buffer.length() > 0 && buffer.charAt(0) != '}') {
- // Try for the MIValue first
- MIValue value = processMIValue(buffer);
- if (value != null) {
- valueList.add(value);
- } else {
- MIResult result = processMIResult(buffer);
- if (result != null) {
- resultList.add(result);
- }
- }
- if (buffer.length() > 0 && buffer.charAt(0) == ',') {
- buffer.deleteCharAt(0);
- }
- }
- if (buffer.length() > 0 && buffer.charAt(0) == '}') {
- buffer.deleteCharAt(0);
- }
- MIValue[] values = (MIValue[]) valueList.toArray(new MIValue[valueList.size()]);
- MIResult[] res = (MIResult[]) resultList.toArray(new MIResult[resultList.size()]);
- tuple.setMIValues(values);
- tuple.setMIResults(res);
- return tuple;
- }
-
- /**
- * Assuming the leading '[' was deleted, find the closing
- * ']' consuming/delete chars from the StringBuffer.
- */
- private MIValue processMIList(FSB buffer) {
- MIList list = new MIList();
- List valueList = new ArrayList();
- List resultList = new ArrayList();
- // catch closing ']'
- while (buffer.length() > 0 && buffer.charAt(0) != ']') {
- // Try for the MIValue first
- MIValue value = processMIValue(buffer);
- if (value != null) {
- valueList.add(value);
- } else {
- MIResult result = processMIResult(buffer);
- if (result != null) {
- resultList.add(result);
- }
- }
- if (buffer.length() > 0 && buffer.charAt(0) == ',') {
- buffer.deleteCharAt(0);
- }
- }
- if (buffer.length() > 0 && buffer.charAt(0) == ']') {
- buffer.deleteCharAt(0);
- }
- MIValue[] values = (MIValue[]) valueList.toArray(new MIValue[valueList.size()]);
- MIResult[] res = (MIResult[]) resultList.toArray(new MIResult[resultList.size()]);
- list.setMIValues(values);
- list.setMIResults(res);
- return list;
- }
-
- /*
- * MI C-String rather MICOnst values are enclose in double quotes
- * and any double quotes or backslash in the string are escaped.
- * Assuming the starting double quote was removed.
- * This method will stop at the closing double quote remove the extra
- * backslach escaping and return the string __without__ the enclosing double quotes
- * The orignal StringBuffer will move forward.
- */
- private String translateCString(FSB buffer) {
- boolean escape = false;
- boolean closingQuotes = false;
-
- StringBuffer sb = new StringBuffer();
-
- int index = 0;
- for (; index < buffer.length() && !closingQuotes; index++) {
- char c = buffer.charAt(index);
- if (c == '\\') {
- if (escape) {
- sb.append(c);
- escape = false;
- } else {
- escape = true;
- }
- } else if (c == '"') {
- if (escape) {
- sb.append(c);
- escape = false;
- } else {
- // Bail out.
- closingQuotes = true;
- }
- } else {
- if (escape) {
- sb.append('\\');
- }
- sb.append(c);
- escape = false;
- }
- }
- buffer.delete(0, index);
- return sb.toString();
- }
-
- /**
- * Tests if this string starts with the specified prefix beginning
- * a specified index.
- *
- * @param value the string.
- * @param prefix the prefix.
- * @return <code>true</code> if prefix starts value.
- */
- public boolean startsWith(StringBuffer value, String prefix) {
- int vlen = value.length();
- int plen = prefix.length();
-
- if (vlen < plen) {
- return false;
- }
- for (int i = 0; i < plen; i++) {
- if (value.charAt(i) != prefix.charAt(i)) {
- return false;
- }
- }
- return true;
- }
-
- /**
- * Fast String Buffer class. MIParser does a lot
- * of deleting off the front of a string, that's clearly
- * an order N operation for StringBuffer which makes
- * the MIParser an order N^2 operation. There are "issues"
- * with this for large arrays. Use of FSB rather than String
- * Buffer makes MIParser N rather than N^2 because FSB can
- * delete from the front in constant time.
- */
- public class FSB {
- StringBuffer buf;
- int pos;
- boolean shared;
-
- public FSB(StringBuffer buf) {
- this.buf = buf;
- pos = 0;
- shared = false;
- }
-
- public FSB(FSB fbuf) {
- pos = fbuf.pos;
- buf = fbuf.buf;
- shared = true;
- }
-
- public int length() {
- int res = buf.length() - pos;
- if (res < 0)
- return 0;
-
- return res;
- }
-
- public char charAt(int index) {
- return buf.charAt(index + pos);
- }
-
- private void resolveCopy() {
- if (shared) {
- buf = new StringBuffer(buf.toString());
- shared = false;
- }
- }
-
- public FSB deleteCharAt(int index) {
- if (index == 0) {
- pos++;
- } else {
- resolveCopy();
- buf = buf.deleteCharAt(pos + index);
- }
-
- return this;
- }
-
- public FSB delete(int start, int end) {
- if (start == 0) {
- pos = pos + end - start;
- } else {
- resolveCopy();
- buf.delete(start + pos, end + pos);
- }
-
- return this;
- }
-
- public void setLength(int a) {
- if (a == 0)
- pos = buf.length();
- else {
- // panic! fortunately we don't do this.
- }
- }
-
- public String substring(int start, int end) {
- return buf.substring(start + pos, end + pos);
- }
-
- public String toString() {
- return buf.substring(pos, buf.length());
- }
-
- int indexOf(char c) {
- int len = buf.length();
- for (int i = pos; i < len; i++) {
- if (buf.charAt(i) == c)
- return i - pos;
- }
-
- return -1;
- }
-
- boolean startsWith(String s) {
- int len = Math.min(s.length(), length());
- if (len < s.length())
- return false;
-
- for (int i = 0; i < len; i++) {
- if (s.charAt(i) != buf.charAt(pos + i))
- return false;
- }
-
- return true;
- }
- }
-}

Back to the top