mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-04-29 19:45:01 +02:00
[219202] - [variables][cdi] Variables view should use icons to represent types
This commit is contained in:
parent
fa79d364cc
commit
afdcf2e551
4 changed files with 668 additions and 25 deletions
|
@ -0,0 +1,580 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2010 Wind River 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:
|
||||
* Wind River Systems - initial implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.dsf.gdb;
|
||||
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* GDB Type Parser (duplicate of org.eclipse.cdt.debug.mi.core.GDBTypeParser)
|
||||
* The code was lifted from: The C Programming Language
|
||||
* B. W. Kernighan and D. Ritchie
|
||||
*
|
||||
* @since 3.0
|
||||
*/
|
||||
public class GDBTypeParser {
|
||||
|
||||
// GDB type parsing from whatis command
|
||||
// declarator: type dcl
|
||||
// type: (name)+
|
||||
// dcl: ('*' | '&')* direct-decl
|
||||
// direct-dcl: '(' dcl ')'
|
||||
// direct-dcl '(' ')'
|
||||
// direct-dcl '[' integer ']'
|
||||
// name: ([a-zA-z][0-9])+
|
||||
// integer ([0-9)+
|
||||
|
||||
final static int EOF = -1;
|
||||
final static int NAME = 0;
|
||||
final static int PARENS = 1;
|
||||
final static int BRACKETS = 2;
|
||||
|
||||
String line;
|
||||
int index;
|
||||
int tokenType;
|
||||
String token;
|
||||
String dataType;
|
||||
String name;
|
||||
GDBDerivedType gdbDerivedType;
|
||||
GDBType genericType;
|
||||
|
||||
public GDBType getGDBType() {
|
||||
if (gdbDerivedType != null) {
|
||||
return gdbDerivedType;
|
||||
}
|
||||
return genericType;
|
||||
}
|
||||
|
||||
public String getVariableName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public GDBType parse(String s) {
|
||||
// Sanity.
|
||||
if (s == null) {
|
||||
s = new String();
|
||||
}
|
||||
s = Pattern.compile("\\bconst\\b").matcher(s).replaceAll(""); //$NON-NLS-1$//$NON-NLS-2$
|
||||
s = Pattern.compile("\\bvolatile\\b").matcher(s).replaceAll(""); //$NON-NLS-1$//$NON-NLS-2$
|
||||
s = s.trim();
|
||||
|
||||
// Initialize.
|
||||
line = s;
|
||||
index = 0;
|
||||
tokenType = -1;
|
||||
token = ""; //$NON-NLS-1$
|
||||
dataType = ""; //$NON-NLS-1$
|
||||
name = ""; //$NON-NLS-1$
|
||||
gdbDerivedType = null;
|
||||
genericType = null;
|
||||
|
||||
// Fetch the datatype.
|
||||
while (getToken() == NAME) {
|
||||
dataType += " " + token; //$NON-NLS-1$
|
||||
}
|
||||
|
||||
// Hack for GDB, the typename can be something like
|
||||
// class A : public B, C { ... } *
|
||||
// We are only interested in "class A"
|
||||
// Carefull for class A::data or class ns::A<ns::data>
|
||||
int column = dataType.indexOf(':');
|
||||
while (column > 0) {
|
||||
if ((column + 2) < dataType.length() && dataType.charAt(column + 1) == ':') {
|
||||
column = dataType.indexOf(':', column+2);
|
||||
continue;
|
||||
}
|
||||
dataType = dataType.substring(0, column);
|
||||
break;
|
||||
}
|
||||
genericType = new GDBType(dataType);
|
||||
|
||||
// Start the recursive parser.
|
||||
dcl(tokenType);
|
||||
return getGDBType();
|
||||
}
|
||||
|
||||
public static String unParse (GDBType gdbType) {
|
||||
|
||||
StringBuffer sb = new StringBuffer();
|
||||
// Fetch the datatype.
|
||||
while (gdbType != null) {
|
||||
GDBDerivedType derived = null;
|
||||
int type = gdbType.getType();
|
||||
if (gdbType instanceof GDBDerivedType) {
|
||||
derived = (GDBDerivedType)gdbType;
|
||||
gdbType = derived.getChild();
|
||||
// respect the precedence of operators.
|
||||
if (type == GDBType.FUNCTION) {
|
||||
sb.append("()"); //$NON-NLS-1$
|
||||
} else if (type == GDBType.ARRAY) {
|
||||
sb.append('[').append(derived.getDimension()).append(']');
|
||||
} else if (type == GDBType.POINTER) {
|
||||
int childType = (gdbType != null) ? gdbType.getType() : GDBType.GENERIC;
|
||||
if (childType == GDBType.POINTER || childType == GDBType.REFERENCE) {
|
||||
sb.append('*');
|
||||
} else if (childType == GDBType.GENERIC) {
|
||||
sb.insert(0, '*');
|
||||
} else {
|
||||
sb.insert(0, "(*").append(')'); //$NON-NLS-1$
|
||||
}
|
||||
} else if (type == GDBType.REFERENCE) {
|
||||
int childType = (gdbType != null) ? gdbType.getType() : GDBType.GENERIC;
|
||||
if (childType == GDBType.POINTER || childType == GDBType.REFERENCE) {
|
||||
sb.append("&"); //$NON-NLS-1$
|
||||
} else if (childType == GDBType.GENERIC) {
|
||||
sb.insert(0, '&');
|
||||
} else {
|
||||
sb.insert(0, "(&").append(')'); //$NON-NLS-1$
|
||||
}
|
||||
}
|
||||
} else {
|
||||
sb.insert(0, ' ');
|
||||
sb.insert(0, gdbType.nameType);
|
||||
gdbType = null;
|
||||
}
|
||||
}
|
||||
return sb.toString().trim();
|
||||
|
||||
}
|
||||
|
||||
public class GDBType {
|
||||
public final static int GENERIC = 0;
|
||||
public final static int POINTER = 1;
|
||||
public final static int REFERENCE = 2;
|
||||
public final static int ARRAY = 3;
|
||||
public final static int FUNCTION = 4;
|
||||
|
||||
String nameType;
|
||||
int type;
|
||||
|
||||
public GDBType(String n) {
|
||||
this(n, 0);
|
||||
}
|
||||
|
||||
public GDBType(int t) {
|
||||
this("", t); //$NON-NLS-1$
|
||||
}
|
||||
|
||||
public GDBType(String n, int t) {
|
||||
nameType = n;
|
||||
type = t;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return unParse(this);
|
||||
}
|
||||
|
||||
public String verbose() {
|
||||
return nameType;
|
||||
}
|
||||
|
||||
public int getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public String getTypeName() {
|
||||
return nameType;
|
||||
}
|
||||
}
|
||||
|
||||
public class GDBDerivedType extends GDBType {
|
||||
int dimension;
|
||||
GDBType child;
|
||||
|
||||
public GDBDerivedType(GDBType c, int i) {
|
||||
this(c, i, 0);
|
||||
}
|
||||
|
||||
public GDBDerivedType(GDBType c, int t, int dim) {
|
||||
super(t);
|
||||
setChild(c);
|
||||
dimension = dim;
|
||||
}
|
||||
|
||||
public int getDimension() {
|
||||
return dimension;
|
||||
}
|
||||
|
||||
public void setChild(GDBType c) {
|
||||
child = c;
|
||||
}
|
||||
|
||||
public GDBType getChild() {
|
||||
return child;
|
||||
}
|
||||
|
||||
public boolean hasChild() {
|
||||
return child != null;
|
||||
}
|
||||
|
||||
public String verbose() {
|
||||
StringBuffer sb = new StringBuffer();
|
||||
switch (getType()) {
|
||||
case FUNCTION :
|
||||
sb.append(" function returning " + (hasChild() ? child.verbose() : "")); //$NON-NLS-1$//$NON-NLS-2$
|
||||
break;
|
||||
case ARRAY :
|
||||
sb.append(" array[" + dimension + "]" + " of " + (hasChild() ? child.verbose() : "")); //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
|
||||
break;
|
||||
case REFERENCE :
|
||||
sb.append(" reference to " + (hasChild() ? child.verbose() : "")); //$NON-NLS-1$//$NON-NLS-2$
|
||||
break;
|
||||
case POINTER :
|
||||
sb.append(" pointer to " + (hasChild() ? child.verbose() : "")); //$NON-NLS-1$//$NON-NLS-2$
|
||||
break;
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
|
||||
int getch() {
|
||||
if (index >= line.length() || index < 0) {
|
||||
return EOF;
|
||||
}
|
||||
return line.charAt(index++);
|
||||
}
|
||||
|
||||
void ungetch() {
|
||||
if (index > 0) {
|
||||
index--;
|
||||
}
|
||||
}
|
||||
|
||||
// check if the character is an alphabet
|
||||
boolean isCIdentifierStart(int c) {
|
||||
if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || c == '_' || c == ':' || c == ',') {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// check is the character is alpha numeric
|
||||
// [a-zA-Z0-9]
|
||||
// GDB hack accept ':' ',' part of the GDB hacks
|
||||
// when doing ptype gdb returns "class A : public C { ..}"
|
||||
boolean isCIdentifierPart(int c) {
|
||||
if ((c >= '0' && c <= '9') || (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || c == '_' || c == ':') {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean isCSpace(int c) {
|
||||
if (c == ' ' || c == '\t' || c == '\f' || c == '\n') {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void insertingChild(int kind) {
|
||||
insertingChild(kind, 0);
|
||||
}
|
||||
|
||||
void insertingChild(int kind, int d) {
|
||||
if (gdbDerivedType == null) {
|
||||
gdbDerivedType = new GDBDerivedType(genericType, kind, d);
|
||||
} else {
|
||||
GDBDerivedType dType = gdbDerivedType;
|
||||
GDBType gdbType = gdbDerivedType.getChild();
|
||||
while (gdbType instanceof GDBDerivedType) {
|
||||
dType = (GDBDerivedType)gdbType;
|
||||
gdbType = dType.getChild();
|
||||
}
|
||||
gdbType = new GDBDerivedType(gdbType, kind, d);
|
||||
dType.setChild(gdbType);
|
||||
}
|
||||
}
|
||||
|
||||
// method returns the next token
|
||||
int getToken() {
|
||||
token = ""; //$NON-NLS-1$
|
||||
|
||||
int c = getch();
|
||||
|
||||
// Skip over any space
|
||||
while (isCSpace(c)) {
|
||||
c = getch();
|
||||
}
|
||||
|
||||
//char character = (char) c;
|
||||
|
||||
if (c == '(') {
|
||||
c = getch();
|
||||
if (c == ')') {
|
||||
token = "()"; //$NON-NLS-1$
|
||||
tokenType = PARENS;
|
||||
} else if (isCIdentifierStart(c)) {
|
||||
int i = 0;
|
||||
token += (char)c;
|
||||
while (i == 0 && c != ')') {
|
||||
if (c == EOF) {
|
||||
// Unbalanced parantheses.
|
||||
break;
|
||||
}
|
||||
c = getch();
|
||||
token += (char)c;
|
||||
if (c == '(') {
|
||||
++i;
|
||||
} else if (c == ')') {
|
||||
--i;
|
||||
}
|
||||
}
|
||||
tokenType = PARENS;
|
||||
} else {
|
||||
ungetch();
|
||||
tokenType = '(';
|
||||
}
|
||||
|
||||
|
||||
|
||||
} else if (c == '[') {
|
||||
while ((c = getch()) != ']' && c != EOF) {
|
||||
token += (char) c;
|
||||
}
|
||||
tokenType = BRACKETS;
|
||||
} else if (isCIdentifierStart(c)) {
|
||||
StringBuffer sb = new StringBuffer();
|
||||
sb.append((char) c);
|
||||
while (isCIdentifierPart((c = getch())) && c != EOF) {
|
||||
sb.append((char) c);
|
||||
}
|
||||
if (c == '<') {
|
||||
// Swallow template args in types like "class foobar<A,B> : public C {..} *"
|
||||
// FIXME: if the bracket is not terminate do we throw exception?
|
||||
sb.append((char) c);
|
||||
int count = 1;
|
||||
do {
|
||||
c = getch();
|
||||
if (c == '<') {
|
||||
count++;
|
||||
} else if (c == '>') {
|
||||
count--;
|
||||
}
|
||||
if (c != ' ') {
|
||||
sb.append((char)c);
|
||||
}
|
||||
} while (count > 0 && c != EOF);
|
||||
} else if (c != EOF) {
|
||||
ungetch();
|
||||
}
|
||||
token = sb.toString();
|
||||
tokenType = NAME;
|
||||
} else if (c == '{') {
|
||||
// Swallow gdb sends things like "struct foobar {..} *"
|
||||
// FIXME: if the bracket is not terminate do we throw exception?
|
||||
int count = 1;
|
||||
do {
|
||||
c = getch();
|
||||
if (c == '{') {
|
||||
count++;
|
||||
} else if (c == '}') {
|
||||
count--;
|
||||
}
|
||||
} while (count > 0 && c != EOF);
|
||||
} else {
|
||||
tokenType = c;
|
||||
}
|
||||
return tokenType;
|
||||
}
|
||||
|
||||
void dcl() {
|
||||
dcl(getToken());
|
||||
}
|
||||
|
||||
// parse a declarator
|
||||
void dcl(int c) {
|
||||
int nstar = 0;
|
||||
int namp = 0;
|
||||
if (c == '*') {
|
||||
nstar++;
|
||||
for (; getToken() == '*'; nstar++) {
|
||||
}
|
||||
} else if (c == '&') {
|
||||
namp++;
|
||||
for (; getToken() == '&'; namp++) {
|
||||
}
|
||||
}
|
||||
dirdcl();
|
||||
while (nstar-- > 0) {
|
||||
insertingChild(GDBType.POINTER);
|
||||
}
|
||||
while (namp-- > 0) {
|
||||
insertingChild(GDBType.REFERENCE);
|
||||
}
|
||||
}
|
||||
|
||||
// parse a direct declarator
|
||||
void dirdcl() {
|
||||
int type;
|
||||
|
||||
if (tokenType == '(') {
|
||||
dcl();
|
||||
if (tokenType != ')' /*&& name.length() > 0*/) {
|
||||
// Do we throw an exception on unterminated parentheses
|
||||
// It should have been handle by getToken()
|
||||
return;
|
||||
}
|
||||
} else if (tokenType == NAME) {
|
||||
// Useless we do not need the name of the variable
|
||||
name = " " + token; //$NON-NLS-1$
|
||||
} else if (tokenType == PARENS) {
|
||||
insertingChild(GDBType.FUNCTION);
|
||||
} else if (tokenType == BRACKETS) {
|
||||
int len = 0;
|
||||
if (token.length() > 0) {
|
||||
try {
|
||||
len = Integer.parseInt(token);
|
||||
} catch (NumberFormatException e) {
|
||||
}
|
||||
}
|
||||
insertingChild(GDBType.ARRAY, len);
|
||||
} else if (tokenType == '&') {
|
||||
insertingChild(GDBType.REFERENCE);
|
||||
} else {
|
||||
// oops bad declaration ?
|
||||
return;
|
||||
}
|
||||
|
||||
while ((type = getToken()) == PARENS || type == BRACKETS) {
|
||||
if (type == PARENS) {
|
||||
insertingChild(GDBType.FUNCTION);
|
||||
} else { /* BRACKETS */
|
||||
int len = 0;
|
||||
if (token.length() > 0) {
|
||||
try {
|
||||
len = Integer.parseInt(token);
|
||||
} catch (NumberFormatException e) {
|
||||
}
|
||||
}
|
||||
insertingChild(GDBType.ARRAY, len);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
GDBTypeParser parser = new GDBTypeParser();
|
||||
|
||||
System.out.println("int *&"); //$NON-NLS-1$
|
||||
parser.parse("int *&"); //$NON-NLS-1$
|
||||
System.out.println(GDBTypeParser.unParse(parser.getGDBType()));
|
||||
System.out.println(parser.getGDBType().verbose());
|
||||
System.out.println();
|
||||
|
||||
System.out.println("int (&rg)(int)"); //$NON-NLS-1$
|
||||
parser.parse("int (&rg)(int)"); //$NON-NLS-1$
|
||||
System.out.println(GDBTypeParser.unParse(parser.getGDBType()));
|
||||
System.out.println(parser.getGDBType().verbose());
|
||||
System.out.println();
|
||||
|
||||
System.out.println("int (&ra)[3]"); //$NON-NLS-1$
|
||||
parser.parse("int (&rg)[3]"); //$NON-NLS-1$
|
||||
System.out.println(GDBTypeParser.unParse(parser.getGDBType()));
|
||||
System.out.println(parser.getGDBType().verbose());
|
||||
System.out.println();
|
||||
|
||||
System.out.println("struct link { int i; int j; struct link * next;} *"); //$NON-NLS-1$
|
||||
parser.parse("struct link { int i; int j; struct link * next} *"); //$NON-NLS-1$
|
||||
System.out.println(GDBTypeParser.unParse(parser.getGDBType()));
|
||||
System.out.println(parser.getGDBType().verbose());
|
||||
System.out.println();
|
||||
|
||||
System.out.println("class ns::link<8, ns::A> : public ns::B { int i; int j; struct link * next;} *"); //$NON-NLS-1$
|
||||
parser.parse("class ns::link<8, ns::A> : public ns::B { int i; int j; struct link * next;} *"); //$NON-NLS-1$
|
||||
System.out.println(GDBTypeParser.unParse(parser.getGDBType()));
|
||||
System.out.println(parser.getGDBType().verbose());
|
||||
System.out.println();
|
||||
|
||||
System.out.println("char **argv"); //$NON-NLS-1$
|
||||
parser.parse("char **argv"); //$NON-NLS-1$
|
||||
System.out.println(GDBTypeParser.unParse(parser.getGDBType()));
|
||||
System.out.println(parser.getGDBType().verbose());
|
||||
System.out.println();
|
||||
|
||||
System.out.println("int (*daytab)[13]"); //$NON-NLS-1$
|
||||
parser.parse("int (*daytab)[13]"); //$NON-NLS-1$
|
||||
System.out.println(GDBTypeParser.unParse(parser.getGDBType()));
|
||||
System.out.println(parser.getGDBType().verbose());
|
||||
System.out.println();
|
||||
|
||||
System.out.println("int *daytab[13]"); //$NON-NLS-1$
|
||||
parser.parse("int *daytab[13]"); //$NON-NLS-1$
|
||||
System.out.println(GDBTypeParser.unParse(parser.getGDBType()));
|
||||
System.out.println(parser.getGDBType().verbose());
|
||||
System.out.println();
|
||||
|
||||
System.out.println("void *comp()"); //$NON-NLS-1$
|
||||
parser.parse("void *comp()"); //$NON-NLS-1$
|
||||
System.out.println(GDBTypeParser.unParse(parser.getGDBType()));
|
||||
System.out.println(parser.getGDBType().verbose());
|
||||
System.out.println();
|
||||
|
||||
System.out.println("void (*comp)()"); //$NON-NLS-1$
|
||||
parser.parse("void (*comp)()"); //$NON-NLS-1$
|
||||
System.out.println(GDBTypeParser.unParse(parser.getGDBType()));
|
||||
System.out.println(parser.getGDBType().verbose());
|
||||
System.out.println();
|
||||
|
||||
System.out.println("int (*func[15])()"); //$NON-NLS-1$
|
||||
parser.parse("int (*func[15])()"); //$NON-NLS-1$
|
||||
System.out.println(GDBTypeParser.unParse(parser.getGDBType()));
|
||||
System.out.println(parser.getGDBType().verbose());
|
||||
System.out.println();
|
||||
|
||||
System.out.println("char (*(*x())[])()"); //$NON-NLS-1$
|
||||
parser.parse("char (*(*x())[])()"); //$NON-NLS-1$
|
||||
System.out.println(GDBTypeParser.unParse(parser.getGDBType()));
|
||||
System.out.println(parser.getGDBType().verbose());
|
||||
System.out.println();
|
||||
|
||||
System.out.println("char (*(*x[3])())[5]"); //$NON-NLS-1$
|
||||
parser.parse("char (*(*x[3])())[5]"); //$NON-NLS-1$
|
||||
System.out.println(GDBTypeParser.unParse(parser.getGDBType()));
|
||||
System.out.println(parser.getGDBType().verbose());
|
||||
System.out.println();
|
||||
|
||||
System.out.println("char *[5]"); //$NON-NLS-1$
|
||||
parser.parse("char *[5]"); //$NON-NLS-1$
|
||||
System.out.println(GDBTypeParser.unParse(parser.getGDBType()));
|
||||
System.out.println(parser.getGDBType().verbose());
|
||||
System.out.println();
|
||||
|
||||
System.out.println("int [2][3]"); //$NON-NLS-1$
|
||||
parser.parse("int [2][3]"); //$NON-NLS-1$
|
||||
System.out.println(GDBTypeParser.unParse(parser.getGDBType()));
|
||||
System.out.println(parser.getGDBType().verbose());
|
||||
System.out.println();
|
||||
|
||||
System.out.println("int (int, char **)"); //$NON-NLS-1$
|
||||
parser.parse("int (int, char **)"); //$NON-NLS-1$
|
||||
System.out.println(GDBTypeParser.unParse(parser.getGDBType()));
|
||||
System.out.println(parser.getGDBType().verbose());
|
||||
System.out.println();
|
||||
|
||||
System.out.println("int (int)"); //$NON-NLS-1$
|
||||
parser.parse("int (int)"); //$NON-NLS-1$
|
||||
System.out.println(GDBTypeParser.unParse(parser.getGDBType()));
|
||||
System.out.println(parser.getGDBType().verbose());
|
||||
System.out.println();
|
||||
|
||||
System.out.println("int (void)"); //$NON-NLS-1$
|
||||
parser.parse("int (void)"); //$NON-NLS-1$
|
||||
System.out.println(GDBTypeParser.unParse(parser.getGDBType()));
|
||||
System.out.println(parser.getGDBType().verbose());
|
||||
System.out.println();
|
||||
|
||||
System.out.println("int ()"); //$NON-NLS-1$
|
||||
parser.parse("int ()"); //$NON-NLS-1$
|
||||
System.out.println(GDBTypeParser.unParse(parser.getGDBType()));
|
||||
System.out.println(parser.getGDBType().verbose());
|
||||
System.out.println();
|
||||
|
||||
}
|
||||
}
|
|
@ -33,6 +33,7 @@ import org.eclipse.cdt.dsf.debug.service.IRunControl.StateChangeReason;
|
|||
import org.eclipse.cdt.dsf.debug.service.IStack.IFrameDMContext;
|
||||
import org.eclipse.cdt.dsf.debug.service.command.CommandCache;
|
||||
import org.eclipse.cdt.dsf.debug.service.command.ICommandControlService;
|
||||
import org.eclipse.cdt.dsf.gdb.GDBTypeParser.GDBType;
|
||||
import org.eclipse.cdt.dsf.gdb.internal.GdbPlugin;
|
||||
import org.eclipse.cdt.dsf.mi.service.command.CommandFactory;
|
||||
import org.eclipse.cdt.dsf.mi.service.command.commands.ExprMetaGetAttributes;
|
||||
|
@ -71,7 +72,7 @@ public class MIExpressions extends AbstractDsfService implements IExpressions, I
|
|||
*
|
||||
* @since 3.0
|
||||
*/
|
||||
public static final String DETAILS_FORMAT = "Details";
|
||||
public static final String DETAILS_FORMAT = "Details"; //$NON-NLS-1$
|
||||
|
||||
/* The order given here is the order that will be used by DSF in the Details Pane */
|
||||
private static final String[] FORMATS_SUPPORTED = new String[] {
|
||||
|
@ -322,19 +323,29 @@ public class MIExpressions extends AbstractDsfService implements IExpressions, I
|
|||
private final String exprType;
|
||||
private final int numChildren;
|
||||
private final boolean editable;
|
||||
private final BasicType fBasicType;
|
||||
|
||||
/**
|
||||
* ExpressionDMData constructor.
|
||||
*/
|
||||
public ExpressionDMData(String expr, String type, int num, boolean edit) {
|
||||
relativeExpression = expr;
|
||||
exprType = type;
|
||||
numChildren = num;
|
||||
editable = edit;
|
||||
this (expr, type, num, edit, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* ExpressionDMData constructor.
|
||||
* @since 3.0
|
||||
*/
|
||||
public ExpressionDMData(String expr, String type, int num, boolean edit, BasicType basicType) {
|
||||
relativeExpression = expr;
|
||||
exprType = type;
|
||||
numChildren = num;
|
||||
editable = edit;
|
||||
fBasicType = basicType;
|
||||
}
|
||||
|
||||
public BasicType getBasicType() {
|
||||
return null;
|
||||
return fBasicType;
|
||||
}
|
||||
|
||||
public String getEncoding() {
|
||||
|
@ -603,16 +614,44 @@ public class MIExpressions extends AbstractDsfService implements IExpressions, I
|
|||
final DataRequestMonitor<IExpressionDMData> rm)
|
||||
{
|
||||
if (dmc instanceof MIExpressionDMC) {
|
||||
fExpressionCache.execute(
|
||||
new ExprMetaGetVar(dmc),
|
||||
new DataRequestMonitor<ExprMetaGetVarInfo>(getExecutor(), rm) {
|
||||
@Override
|
||||
protected void handleSuccess() {
|
||||
rm.setData(new ExpressionDMData(getData().getExpr(),
|
||||
getData().getType(), getData().getNumChildren(), getData().getEditable()));
|
||||
rm.done();
|
||||
}
|
||||
});
|
||||
fExpressionCache.execute(
|
||||
new ExprMetaGetVar(dmc),
|
||||
new DataRequestMonitor<ExprMetaGetVarInfo>(getExecutor(), rm) {
|
||||
@Override
|
||||
protected void handleSuccess() {
|
||||
IExpressionDMData.BasicType basicType = null;
|
||||
|
||||
GDBType gdbType = getData().getGDBType();
|
||||
|
||||
if (gdbType != null) {
|
||||
switch (gdbType.getType()) {
|
||||
case GDBType.ARRAY:
|
||||
basicType = IExpressionDMData.BasicType.array;
|
||||
break;
|
||||
case GDBType.FUNCTION:
|
||||
basicType = IExpressionDMData.BasicType.function;
|
||||
break;
|
||||
case GDBType.POINTER:
|
||||
case GDBType.REFERENCE:
|
||||
basicType = IExpressionDMData.BasicType.pointer;
|
||||
break;
|
||||
case GDBType.GENERIC:
|
||||
default:
|
||||
if (getData().getNumChildren() > 0) {
|
||||
basicType = IExpressionDMData.BasicType.array;
|
||||
} else {
|
||||
basicType = IExpressionDMData.BasicType.basic;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
rm.setData(new ExpressionDMData(
|
||||
getData().getExpr(),getData().getType(), getData().getNumChildren(),
|
||||
getData().getEditable(), basicType));
|
||||
rm.done();
|
||||
}
|
||||
});
|
||||
} else if (dmc instanceof InvalidContextExpressionDMC) {
|
||||
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, INVALID_HANDLE, "Invalid context for evaluating expressions.", null)); //$NON-NLS-1$
|
||||
rm.done();
|
||||
|
|
|
@ -42,6 +42,8 @@ import org.eclipse.cdt.dsf.debug.service.command.ICommandResult;
|
|||
import org.eclipse.cdt.dsf.debug.service.command.ICommandToken;
|
||||
import org.eclipse.cdt.dsf.debug.service.command.IEventListener;
|
||||
import org.eclipse.cdt.dsf.debug.service.command.ICommandControlService.ICommandControlDMContext;
|
||||
import org.eclipse.cdt.dsf.gdb.GDBTypeParser;
|
||||
import org.eclipse.cdt.dsf.gdb.GDBTypeParser.GDBType;
|
||||
import org.eclipse.cdt.dsf.gdb.internal.GdbPlugin;
|
||||
import org.eclipse.cdt.dsf.mi.service.MIExpressions.ExpressionInfo;
|
||||
import org.eclipse.cdt.dsf.mi.service.MIExpressions.MIExpressionDMC;
|
||||
|
@ -207,6 +209,7 @@ public class MIVariableManager implements ICommandControl {
|
|||
// The full expression that can be used to characterize this object
|
||||
private String fullExp = null;
|
||||
private String type = null;
|
||||
private GDBType gdbType;
|
||||
private int numChildren = 0;
|
||||
private Boolean editable = null;
|
||||
|
||||
|
@ -254,21 +257,21 @@ public class MIVariableManager implements ICommandControl {
|
|||
|
||||
public String getExpression() { return fullExp; }
|
||||
public String getType() { return type; }
|
||||
|
||||
/** @since 3.0 */
|
||||
public GDBType getGDBType() { return gdbType; }
|
||||
public int getNumChildren() { return numChildren; }
|
||||
public String getValue(String format) { return valueMap.get(format); }
|
||||
|
||||
public ExpressionInfo[] getChildren() { return children; }
|
||||
|
||||
|
||||
//FIX replace these methods with CDT's GDBTypeParser (see bug 200897 comment #5)
|
||||
// int(*)[5] is a pointer to an array (so it is a pointer but not an array) (e.g., &b where int b[5])
|
||||
// int *[5] is an array of pointers (so it is an array but not a pointer) (e.g., int *b[5])
|
||||
public boolean isArray() { return (getType() == null) ? false : getType().endsWith("]") && !getType().contains("(*)") ; }//$NON-NLS-1$//$NON-NLS-2$
|
||||
public boolean isPointer() { return (getType() == null) ? false : getType().contains("*")&& !isArray(); }//$NON-NLS-1$
|
||||
public boolean isMethod() { return (getType() == null) ? false : getType().contains("()"); }//$NON-NLS-1$
|
||||
public boolean isArray() { return (getGDBType() == null) ? false : getGDBType().getType() == GDBType.ARRAY; }
|
||||
public boolean isPointer() { return (getGDBType() == null) ? false : getGDBType().getType() == GDBType.POINTER; }
|
||||
public boolean isMethod() { return (getGDBType() == null) ? false : getGDBType().getType() == GDBType.FUNCTION; }
|
||||
// A complex variable is one with children. However, it must not be a pointer since a pointer has one child
|
||||
// according to GDB, but is still a 'simple' variable
|
||||
public boolean isComplex() { return (getType() == null) ? false : getNumChildren() > 0 && !isPointer(); }
|
||||
public boolean isComplex() { return (getGDBType() == null) ? false : getGDBType().getType() != GDBType.POINTER && getNumChildren() > 0; }
|
||||
|
||||
public void setGdbName(String n) { gdbName = n; }
|
||||
public void setCurrentFormat(String f) { format = f; }
|
||||
|
@ -276,6 +279,7 @@ public class MIVariableManager implements ICommandControl {
|
|||
public void setExpressionData(String fullExpression, String t, int num) {
|
||||
fullExp = fullExpression;
|
||||
type = t;
|
||||
gdbType = fGDBTypeParser.parse(t);
|
||||
numChildren = num;
|
||||
}
|
||||
|
||||
|
@ -1324,6 +1328,11 @@ public class MIVariableManager implements ICommandControl {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 3.0
|
||||
*/
|
||||
private static final GDBTypeParser fGDBTypeParser = new GDBTypeParser();
|
||||
|
||||
private final DsfSession fSession;
|
||||
|
||||
/** Provides access to the GDB/MI back-end */
|
||||
|
@ -1586,6 +1595,7 @@ public class MIVariableManager implements ICommandControl {
|
|||
exprCtx.getRelativeExpression(),
|
||||
getData().getNumChildren(),
|
||||
getData().getType(),
|
||||
getData().getGDBType(),
|
||||
!getData().isComplex()));
|
||||
drm.done();
|
||||
processCommandDone(token, drm.getData());
|
||||
|
|
|
@ -12,6 +12,7 @@ package org.eclipse.cdt.dsf.mi.service.command.output;
|
|||
|
||||
import org.eclipse.cdt.dsf.debug.service.command.ICommand;
|
||||
import org.eclipse.cdt.dsf.debug.service.command.ICommandResult;
|
||||
import org.eclipse.cdt.dsf.gdb.GDBTypeParser.GDBType;
|
||||
|
||||
public class ExprMetaGetVarInfo implements ICommandResult {
|
||||
|
||||
|
@ -19,17 +20,30 @@ public class ExprMetaGetVarInfo implements ICommandResult {
|
|||
private final int numChild;
|
||||
private final String type;
|
||||
private final boolean editable;
|
||||
|
||||
public ExprMetaGetVarInfo(String e, int n, String t, boolean edit) {
|
||||
private final GDBType gdbType;
|
||||
|
||||
public ExprMetaGetVarInfo(String e, int n, String t, boolean edit) {
|
||||
this (e, n, t, null, edit);
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 3.0
|
||||
*/
|
||||
public ExprMetaGetVarInfo(String e, int n, String t, GDBType gt, boolean edit) {
|
||||
expression = e;
|
||||
numChild = n;
|
||||
type = t;
|
||||
editable = edit;
|
||||
gdbType = gt;
|
||||
}
|
||||
|
||||
public String getExpr() { return expression; }
|
||||
public int getNumChildren() { return numChild; }
|
||||
public String getType() { return type; }
|
||||
/**
|
||||
* @since 3.0
|
||||
*/
|
||||
public GDBType getGDBType() { return gdbType; }
|
||||
public boolean getEditable() { return editable; }
|
||||
|
||||
public <V extends ICommandResult> V getSubsetResult(ICommand<V> command) {
|
||||
|
|
Loading…
Add table
Reference in a new issue