KDevelop API Documentation

languages/java/debugger/jdbparser.cpp

Go to the documentation of this file.
00001 // ************************************************************************** 00002 // jdbparser.cpp - description 00003 // ------------------- 00004 // begin : Tue Aug 17 1999 00005 // copyright : (C) 1999 by John Birch 00006 // email : jbb@kdevelop.org 00007 // ************************************************************************** 00008 00009 // ************************************************************************** 00010 // * 00011 // This program is free software; you can redistribute it and/or modify * 00012 // it under the terms of the GNU General Public License as published by * 00013 // the Free Software Foundation; either version 2 of the License, or * 00014 // (at your option) any later version. * 00015 // * 00016 // ************************************************************************** 00017 00018 #include "jdbparser.h" 00019 #include "variablewidget.h" 00020 00021 #include <qregexp.h> 00022 00023 #include <ctype.h> 00024 #include <stdlib.h> 00025 00026 namespace JAVADebugger 00027 { 00028 00029 // ************************************************************************** 00030 // ************************************************************************** 00031 // ************************************************************************** 00032 00033 JDBParser::JDBParser() 00034 { 00035 } 00036 00037 // ************************************************************************** 00038 00039 JDBParser::~JDBParser() 00040 { 00041 } 00042 00043 // ************************************************************************** 00044 00045 void JDBParser::parseData(TrimmableItem *parent, char *buf, 00046 bool requested, bool params) 00047 { 00048 static const char *unknown = "?"; 00049 00050 Q_ASSERT(parent); 00051 if (!buf) 00052 return; 00053 00054 if (parent->getDataType() == typeArray) { 00055 parseArray(parent, buf); 00056 return; 00057 } 00058 00059 if (requested && !*buf) 00060 buf = (char*)unknown; 00061 00062 while (*buf) { 00063 QString varName = ""; 00064 DataType dataType = determineType(buf); 00065 00066 if (dataType == typeName) { 00067 varName = getName(&buf); 00068 dataType = determineType(buf); 00069 } 00070 00071 QCString value = getValue(&buf, requested); 00072 setItem(parent, varName, dataType, value, requested, params); 00073 } 00074 } 00075 00076 // ************************************************************************** 00077 00078 void JDBParser::parseArray(TrimmableItem *parent, char *buf) 00079 { 00080 QString elementRoot = parent->getName() + "[%1]"; 00081 int idx = 0; 00082 while (*buf) { 00083 buf = skipNextTokenStart(buf); 00084 if (!*buf) 00085 return; 00086 00087 DataType dataType = determineType(buf); 00088 QCString value = getValue(&buf, false); 00089 QString varName = elementRoot.arg(idx); 00090 setItem(parent, varName, dataType, value, false, false); 00091 00092 int pos = value.find(" <repeats", 0); 00093 if (pos > -1) { 00094 if (int i = atoi(value.data()+pos+10)) 00095 idx += (i-1); 00096 } 00097 00098 idx++; 00099 } 00100 } 00101 00102 // ************************************************************************** 00103 00104 QString JDBParser::getName(char **buf) 00105 { 00106 char *start = skipNextTokenStart(*buf); 00107 if (*start) { 00108 *buf = skipTokenValue(start); 00109 return QCString(start, *buf - start + 1); 00110 } else 00111 *buf = start; 00112 00113 return QString(); 00114 } 00115 00116 // ************************************************************************** 00117 00118 QCString JDBParser::getValue(char **buf, bool requested) 00119 { 00120 char *start = skipNextTokenStart(*buf); 00121 *buf = skipTokenValue(start); 00122 00123 if (*start == '{') 00124 return QCString(start+1, *buf - start -1); 00125 00126 QCString value(start, *buf - start + 1); 00127 00128 // QT2.x string handling 00129 // A very bad hack alert! 00130 if (requested) 00131 return value.replace( QRegExp("\\\\000"), "" ); 00132 00133 return value; 00134 } 00135 00136 // *************************************************************************** 00137 00138 TrimmableItem *JDBParser::getItem(TrimmableItem *parent, DataType dataType, 00139 const QString &varName, bool requested) 00140 { 00141 if (requested) 00142 return parent; 00143 00144 if (varName.isEmpty()) { 00145 if (parent->getDataType() == typeReference) 00146 return parent; 00147 00148 return 0; 00149 } 00150 00151 return parent->findMatch(varName, dataType); 00152 } 00153 00154 // ************************************************************************** 00155 00156 void JDBParser::setItem(TrimmableItem *parent, const QString &varName, 00157 DataType dataType, const QCString &value, 00158 bool requested, bool) 00159 { 00160 TrimmableItem *item = getItem(parent, dataType, varName, requested); 00161 if (!item) { 00162 if (varName.isEmpty()) 00163 return; 00164 00165 item = new VarItem(parent, varName, dataType); 00166 } else { 00167 // Don't update a "this" item because it'll alwasy stay red because the local 00168 // this looks different than the param this. 00169 // @todo - this is not good code. We should check to see if the address is the 00170 // same between params and locals before ignoring the param. 00171 // if (params && varName == "this") 00172 // return; 00173 } 00174 00175 switch (dataType) { 00176 case typePointer: 00177 item->setText(ValueCol, value); 00178 item->setExpandable(varName != "_vptr."); 00179 break; 00180 00181 case typeStruct: 00182 case typeArray: 00183 item->setCache(value); 00184 break; 00185 00186 case typeReference: 00187 { 00188 int pos; 00189 if ((pos = value.find(':', 0)) != -1) { 00190 QCString rhs((value.mid(pos+2, value.length()).data())); 00191 if (determineType(rhs.data()) != typeValue) { 00192 item->setCache(rhs); 00193 item->setText(ValueCol, value.left(pos)); 00194 break; 00195 } 00196 } 00197 item->setText(ValueCol, value); 00198 item->setExpandable(!value.isEmpty() && (value[0] == '@')); 00199 break; 00200 } 00201 00202 case typeValue: 00203 item->setText(ValueCol, value); 00204 break; 00205 00206 default: 00207 break; 00208 } 00209 } 00210 00211 // ************************************************************************** 00212 00213 DataType JDBParser::determineType(char *buf) const 00214 { 00215 if (!buf || !*(buf= skipNextTokenStart(buf))) 00216 return typeUnknown; 00217 00218 // A reference, probably from a parameter value. 00219 if (*buf == '@') 00220 return typeReference; 00221 00222 // Structures and arrays - (but which one is which?) 00223 // {void (void)} 0x804a944 <__builtin_new+41> - this is a fn pointer 00224 // (void (*)(void)) 0x804a944 <f(E *, char)> - so is this - ugly!!! 00225 if (*buf == '{') { 00226 if (strncmp(buf, "{{", 2) == 0) 00227 return typeArray; 00228 00229 if (strncmp(buf, "{<No data fields>}", 18) == 0) 00230 return typeValue; 00231 00232 buf++; 00233 while (*buf) { 00234 switch (*buf) { 00235 case '=': 00236 return typeStruct; 00237 case '"': 00238 buf = skipString(buf); 00239 break; 00240 case '\'': 00241 buf = skipQuotes(buf, '\''); 00242 break; 00243 case ',': 00244 if (*(buf-1) == '}') 00245 Q_ASSERT(false); 00246 return typeArray; 00247 case '}': 00248 if (*(buf+1) == ',' || *(buf+1) == '\n' || !*(buf+1)) 00249 return typeArray; // Hmm a single element array?? 00250 if (strncmp(buf+1, " 0x", 3) == 0) 00251 return typePointer; // What about references? 00252 return typeUnknown; // very odd? 00253 case '(': 00254 buf = skipDelim(buf, '(', ')'); 00255 break; 00256 case '<': 00257 buf = skipDelim(buf, '<', '>'); 00258 break; 00259 default: 00260 buf++; 00261 break; 00262 } 00263 } 00264 return typeUnknown; 00265 } 00266 00267 // some sort of address. We need to sort out if we have 00268 // a 0x888888 "this is a char*" type which we'll term a value 00269 // or whether we just have an address 00270 if (strncmp(buf, "0x", 2) == 0) { 00271 while (*buf) { 00272 if (!isspace(*buf)) 00273 buf++; 00274 else if (*(buf+1) == '\"') 00275 return typeValue; 00276 else 00277 break; 00278 } 00279 00280 return typePointer; 00281 } 00282 00283 // Pointers and references - references are a bit odd 00284 // and cause JDB to fail to produce all the local data 00285 // if they haven't been initialised. but that's not our problem!! 00286 // (void (*)(void)) 0x804a944 <f(E *, char)> - this is a fn pointer 00287 if (*buf == '(') { 00288 buf = skipDelim(buf, '(', ')'); 00289 switch (*(buf-2)) { 00290 case '*': 00291 return typePointer; 00292 case '&': 00293 return typeReference; 00294 default: 00295 return typeUnknown; 00296 } 00297 } 00298 00299 buf = skipTokenValue(buf); 00300 if ((strncmp(buf, " = ", 3) == 0) || (*buf == '=')) 00301 return typeName; 00302 00303 return typeValue; 00304 } 00305 00306 // ************************************************************************** 00307 00308 char *JDBParser::skipString(char *buf) const 00309 { 00310 if (buf && *buf == '\"') { 00311 buf = skipQuotes(buf, *buf); 00312 while (*buf) { 00313 if ((strncmp(buf, ", \"", 3) == 0) || (strncmp(buf, ", '", 3) == 0)) 00314 buf = skipQuotes(buf+2, *(buf+2)); 00315 else if (strncmp(buf, " <", 2) == 0) // take care of <repeats 00316 buf = skipDelim(buf+1, '<', '>'); 00317 else 00318 break; 00319 } 00320 00321 // If the string is long then it's chopped and has ... after it. 00322 while (*buf && *buf == '.') 00323 buf++; 00324 } 00325 00326 return buf; 00327 } 00328 00329 // *************************************************************************** 00330 00331 char *JDBParser::skipQuotes(char *buf, char quotes) const 00332 { 00333 if (buf && *buf == quotes) { 00334 buf++; 00335 00336 while (*buf) { 00337 if (*buf == '\\') 00338 buf++; // skips \" or \' problems 00339 else if (*buf == quotes) 00340 return buf+1; 00341 00342 buf++; 00343 } 00344 } 00345 00346 return buf; 00347 } 00348 00349 // ************************************************************************** 00350 00351 char *JDBParser::skipDelim(char *buf, char open, char close) const 00352 { 00353 if (buf && *buf == open) { 00354 buf++; 00355 00356 while (*buf) { 00357 if (*buf == open) 00358 buf = skipDelim(buf, open, close); 00359 else if (*buf == close) 00360 return buf+1; 00361 else if (*buf == '\"') 00362 buf = skipString(buf); 00363 else if (*buf == '\'') 00364 buf = skipQuotes(buf, *buf); 00365 else if (*buf) 00366 buf++; 00367 } 00368 } 00369 return buf; 00370 } 00371 00372 // ************************************************************************** 00373 00374 char *JDBParser::skipTokenValue(char *buf) const 00375 { 00376 if (buf) { 00377 while (true) { 00378 buf = skipTokenEnd(buf); 00379 00380 char *end = buf; 00381 while (*end && isspace(*end) && *end != '\n') 00382 end++; 00383 00384 if (*end == 0 || *end == ',' || *end == '\n' || *end == '=' || *end == '}') 00385 break; 00386 00387 if (buf == end) 00388 break; 00389 00390 buf = end; 00391 } 00392 } 00393 00394 return buf; 00395 } 00396 00397 // ************************************************************************** 00398 00399 char *JDBParser::skipTokenEnd(char *buf) const 00400 { 00401 if (buf) { 00402 switch (*buf) { 00403 case '"': 00404 return skipString(buf); 00405 case '\'': 00406 return skipQuotes(buf, *buf); 00407 case '{': 00408 return skipDelim(buf, '{', '}'); 00409 case '<': 00410 return skipDelim(buf, '<', '>'); 00411 case '(': 00412 return skipDelim(buf, '(', ')'); 00413 } 00414 00415 while (*buf && !isspace(*buf) && *buf != ',' && *buf != '}' && *buf != '=') 00416 buf++; 00417 } 00418 00419 return buf; 00420 } 00421 00422 // ************************************************************************** 00423 00424 char *JDBParser::skipNextTokenStart(char *buf) const 00425 { 00426 if (buf) 00427 while (*buf && (isspace(*buf) || *buf == ',' || *buf == '}' || *buf == '=')) 00428 buf++; 00429 00430 return buf; 00431 } 00432 00433 } 00434 00435 // ************************************************************************** 00436 // ************************************************************************** 00437 // **************************************************************************
KDE Logo
This file is part of the documentation for KDevelop Version 3.0.4.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Tue Oct 19 08:01:43 2004 by doxygen 1.3.7 written by Dimitri van Heesch, © 1997-2003