Commit b351cc97953e8a1713bef53be36cab6199a7614b
- Diff rendering mode:
- inline
- side by side
|   | |||
| 402 | 402 | } | |
| 403 | 403 | ||
| 404 | 404 | // Return hexadecimal pointer value from a CDB pointer value | |
| 405 | // which look like "0x000032a" or "0x00000000`0250124a" on 64-bit systems. | ||
| 406 | static bool inline getPointerValue(QString stringValue, quint64 *value) | ||
| 405 | // which look like "0x000032a" or "0x00000000`0250124a" or | ||
| 406 | // "0x1`0250124a" on 64-bit systems. | ||
| 407 | static bool inline getUnsignedHexValue(QString stringValue, quint64 *value) | ||
| 407 | 408 | { | |
| 408 | 409 | *value = 0; | |
| 409 | 410 | if (!stringValue.startsWith(QLatin1String("0x"))) | |
| 410 | 411 | return false; | |
| 411 | 412 | stringValue.remove(0, 2); | |
| 412 | 413 | // Remove 64bit separator | |
| 413 | if (stringValue.size() > 8 && stringValue.at(8) == QLatin1Char('`')) | ||
| 414 | stringValue.remove(8, 1); | ||
| 414 | if (stringValue.size() > 9) { | ||
| 415 | const int sepPos = stringValue.size() - 9; | ||
| 416 | if (stringValue.at(sepPos) == QLatin1Char('`')) | ||
| 417 | stringValue.remove(sepPos, 1); | ||
| 418 | } | ||
| 415 | 419 | bool ok; | |
| 416 | 420 | *value = stringValue.toULongLong(&ok, 16); | |
| 417 | 421 | return ok; | |
| … | … | ||
| 431 | 431 | if (blankPos != -1) | |
| 432 | 432 | stringValue.truncate(blankPos); | |
| 433 | 433 | quint64 value; | |
| 434 | return getPointerValue(stringValue, &value) && value == 0u; | ||
| 434 | return getUnsignedHexValue(stringValue, &value) && value == 0u; | ||
| 435 | 435 | } | |
| 436 | 436 | ||
| 437 | 437 | // Fix a symbol group value. It is set to the class type for | |
| … | … | ||
| 449 | 449 | return value; | |
| 450 | 450 | } | |
| 451 | 451 | ||
| 452 | static inline QString fixValue(const QString &value) | ||
| 452 | // Fix display values: Pass through strings, convert unsigned integers | ||
| 453 | // to decimal ('0x5454`fedf'), remove inner templates from | ||
| 454 | // "0x4343 class list<>". | ||
| 455 | static inline QString fixValue(const QString &value, const QString &type) | ||
| 453 | 456 | { | |
| 454 | if (value.size() < 20 || value.endsWith(QLatin1Char('"'))) | ||
| 457 | if (value.endsWith(QLatin1Char('"'))) // Pass through strings | ||
| 455 | 458 | return value; | |
| 456 | return removeInnerTemplateType(value); | ||
| 459 | const int size = value.size(); | ||
| 460 | // Unsigned hex numbers | ||
| 461 | if (isIntType(type) && (size > 2 && value.at(1) == QLatin1Char('x'))) { | ||
| 462 | quint64 intValue; | ||
| 463 | if (getUnsignedHexValue(value, &intValue)) | ||
| 464 | return QString::number(intValue); | ||
| 465 | } | ||
| 466 | return size < 20 ? value : removeInnerTemplateType(value); | ||
| 457 | 467 | } | |
| 458 | 468 | ||
| 459 | 469 | WatchData CdbSymbolGroupContext::watchDataAt(unsigned long index) const | |
| … | … | ||
| 495 | 495 | return wd; | |
| 496 | 496 | } | |
| 497 | 497 | const QString value = getSymbolString(m_symbolGroup, &IDebugSymbolGroup2::GetSymbolValueTextWide, index); | |
| 498 | wd.setValue(fixValue(value)); | ||
| 498 | wd.setValue(fixValue(value, type)); | ||
| 499 | 499 | wd.setChildrenNeeded(); // compensate side effects of above setters | |
| 500 | 500 | // Figure out children. The SubElement is only a guess unless the symbol, | |
| 501 | 501 | // is expanded, so, we leave this as a guess for later updates. | |
| … | … | ||
| 743 | 743 | ||
| 744 | 744 | // Get pointer value of symbol group ("0xAAB") | |
| 745 | 745 | // Note that this is on "00000000`0250124a" on 64bit systems. | |
| 746 | static inline bool getPointerValue(CIDebugSymbolGroup *sg, int index, quint64 *value) | ||
| 746 | static inline bool getUnsignedHexValue(CIDebugSymbolGroup *sg, int index, quint64 *value) | ||
| 747 | 747 | { | |
| 748 | 748 | const QString stringValue = getSymbolString(sg, &IDebugSymbolGroup2::GetSymbolValueTextWide, index); | |
| 749 | return getPointerValue(stringValue, value); | ||
| 749 | return getUnsignedHexValue(stringValue, value); | ||
| 750 | 750 | } | |
| 751 | 751 | ||
| 752 | 752 | int CdbSymbolGroupContext::dumpQString(CIDebugDataSpaces *ds, WatchData *wd) | |
| … | … | ||
| 770 | 770 | if (!getIntValue(m_symbolGroup, sizeIndex, &size)) | |
| 771 | 771 | return 4; | |
| 772 | 772 | quint64 array; | |
| 773 | if (!getPointerValue(m_symbolGroup, arrayIndex, &array)) | ||
| 773 | if (!getUnsignedHexValue(m_symbolGroup, arrayIndex, &array)) | ||
| 774 | 774 | return 5; | |
| 775 | 775 | // Fetch | |
| 776 | 776 | const bool truncated = size > maxLength; |
|   | |||
| 588 | 588 | return type; | |
| 589 | 589 | } | |
| 590 | 590 | ||
| 591 | template <class IntType> QString reformatInteger(IntType value, int format) | ||
| 592 | { | ||
| 593 | switch (format) { | ||
| 594 | case HexadecimalFormat: | ||
| 595 | return ("(hex) ") + QString::number(value, 16); | ||
| 596 | case BinaryFormat: | ||
| 597 | return ("(bin) ") + QString::number(value, 2); | ||
| 598 | case OctalFormat: | ||
| 599 | return ("(oct) ") + QString::number(value, 8); | ||
| 600 | } | ||
| 601 | return QString::number(value); // not reached | ||
| 602 | } | ||
| 603 | |||
| 591 | 604 | static QString formattedValue(const WatchData &data, | |
| 592 | 605 | int individualFormat, int typeFormat) | |
| 593 | 606 | { | |
| 594 | 607 | if (isIntType(data.type)) { | |
| 595 | int format = individualFormat == -1 ? typeFormat : individualFormat; | ||
| 596 | int value = data.value.toInt(); | ||
| 597 | if (format == HexadecimalFormat) | ||
| 598 | return ("(hex) ") + QString::number(value, 16); | ||
| 599 | if (format == BinaryFormat) | ||
| 600 | return ("(bin) ") + QString::number(value, 2); | ||
| 601 | if (format == OctalFormat) | ||
| 602 | return ("(oct) ") + QString::number(value, 8); | ||
| 603 | return data.value; | ||
| 608 | const int format = individualFormat == -1 ? typeFormat : individualFormat; | ||
| 609 | if (format <= 0) | ||
| 610 | return data.value; | ||
| 611 | if (data.type.contains(QLatin1String("unsigned"))) { | ||
| 612 | return reformatInteger(data.value.toULongLong(), format); | ||
| 613 | } else { | ||
| 614 | return reformatInteger(data.value.toLongLong(), format); | ||
| 615 | } | ||
| 604 | 616 | } | |
| 605 | |||
| 606 | 617 | return data.value; | |
| 607 | 618 | } | |
| 608 | 619 | ||
| … | … | ||
| 780 | 780 | break; | |
| 781 | 781 | ||
| 782 | 782 | case TypeFormatRole: | |
| 783 | return m_handler->m_typeFormats[data.type]; | ||
| 784 | |||
| 785 | case IndividualFormatRole: { | ||
| 786 | int format = m_handler->m_individualFormats[data.iname]; | ||
| 787 | if (format == -1) | ||
| 788 | return m_handler->m_typeFormats[data.type]; | ||
| 789 | return format; | ||
| 790 | } | ||
| 791 | |||
| 783 | return m_handler->m_typeFormats.value(data.type, -1); | ||
| 784 | case IndividualFormatRole: | ||
| 785 | return m_handler->m_individualFormats.value(data.iname, -1); | ||
| 792 | 786 | case AddressRole: { | |
| 793 | 787 | if (!data.addr.isEmpty()) | |
| 794 | 788 | return data.addr; | |
| … | … | ||
| 812 | 812 | } | |
| 813 | 813 | } else if (role == TypeFormatRole) { | |
| 814 | 814 | m_handler->setFormat(data.type, value.toInt()); | |
| 815 | } else if (role == IndividualFormatRole) { | ||
| 816 | m_handler->m_individualFormats[data.iname] = value.toInt(); | ||
| 815 | } else if (role == IndividualFormatRole) { | ||
| 816 | const int format = value.toInt(); | ||
| 817 | if (format == -1) { | ||
| 818 | m_handler->m_individualFormats.remove(data.iname); | ||
| 819 | } else { | ||
| 820 | m_handler->m_individualFormats[data.iname] = format; | ||
| 821 | } | ||
| 817 | 822 | } | |
| 818 | 823 | emit dataChanged(index, index); | |
| 819 | 824 | return true; | |
| … | … | ||
| 1383 | 1383 | QHashIterator<QString, int> it(m_typeFormats); | |
| 1384 | 1384 | while (it.hasNext()) { | |
| 1385 | 1385 | it.next(); | |
| 1386 | QString key = it.key().trimmed(); | ||
| 1387 | if (!key.isEmpty()) | ||
| 1388 | typeFormats.insert(key, it.value()); | ||
| 1386 | const int format = it.value(); | ||
| 1387 | if (format != DecimalFormat) { | ||
| 1388 | const QString key = it.key().trimmed(); | ||
| 1389 | if (!key.isEmpty()) | ||
| 1390 | typeFormats.insert(key, format); | ||
| 1391 | } | ||
| 1389 | 1392 | } | |
| 1390 | 1393 | m_manager->setSessionValue("DefaultFormats", QVariant(typeFormats)); | |
| 1391 | 1394 | } |
|   | |||
| 542 | 542 | << QLatin1String("long") << QLatin1String("bool") | |
| 543 | 543 | << QLatin1String("signed char") << QLatin1String("unsigned") | |
| 544 | 544 | << QLatin1String("unsigned char") << QLatin1String("unsigned long") | |
| 545 | << QLatin1String("long long") << QLatin1String("unsigned long long"); | ||
| 546 | return type.endsWith(QLatin1String(" int")) || types.contains(type); | ||
| 545 | << QLatin1String("long long") << QLatin1String("unsigned long long") | ||
| 546 | << QLatin1String("qint16") << QLatin1String("quint16") | ||
| 547 | << QLatin1String("qint32") << QLatin1String("quint32") | ||
| 548 | << QLatin1String("qint64") << QLatin1String("quint64"); | ||
| 549 | return type.endsWith(QLatin1String(" int")) | ||
| 550 | || type.endsWith(QLatin1String(" int64")) | ||
| 551 | || types.contains(type); | ||
| 547 | 552 | } | |
| 548 | 553 | ||
| 549 | 554 | bool isSymbianIntType(const QString &type) |
src/plugins/debugger/watchwindow.cpp
(25 / 19)
|   | |||
| 210 | 210 | ||
| 211 | 211 | QStringList alternativeFormats = | |
| 212 | 212 | model()->data(mi0, TypeFormatListRole).toStringList(); | |
| 213 | int typeFormat = | ||
| 214 | model()->data(mi0, TypeFormatRole).toInt(); | ||
| 215 | int individualFormat = | ||
| 216 | model()->data(mi0, IndividualFormatRole).toInt(); | ||
| 213 | const int typeFormat = qMax(int(DecimalFormat), model()->data(mi0, TypeFormatRole).toInt()); | ||
| 214 | const int individualFormat = model()->data(mi0, IndividualFormatRole).toInt(); | ||
| 215 | const int effectiveIndividualFormat = individualFormat == -1 ? typeFormat : individualFormat; | ||
| 217 | 216 | ||
| 218 | 217 | QMenu typeFormatMenu; | |
| 219 | 218 | QMenu individualFormatMenu; | |
| 220 | 219 | QList<QAction *> typeFormatActions; | |
| 221 | 220 | QList<QAction *> individualFormatActions; | |
| 221 | QAction *clearIndividualFormatAction = 0; | ||
| 222 | 222 | if (idx.isValid()) { | |
| 223 | 223 | typeFormatMenu.setTitle(tr("Change format for type '%1'").arg(type)); | |
| 224 | 224 | individualFormatMenu.setTitle(tr("Change format for expression '%1'").arg(exp)); | |
| 225 | for (int i = 0; i != alternativeFormats.size(); ++i) { | ||
| 226 | const QString format = alternativeFormats.at(i); | ||
| 227 | QAction *act = new QAction(format, &typeFormatMenu); | ||
| 228 | act->setCheckable(true); | ||
| 229 | if (i == typeFormat) | ||
| 230 | act->setChecked(true); | ||
| 231 | typeFormatMenu.addAction(act); | ||
| 232 | typeFormatActions.append(act); | ||
| 233 | act = new QAction(format, &individualFormatMenu); | ||
| 234 | act->setCheckable(true); | ||
| 235 | if (i == individualFormat) | ||
| 236 | act->setChecked(true); | ||
| 237 | individualFormatMenu.addAction(act); | ||
| 238 | individualFormatActions.append(act); | ||
| 239 | } | ||
| 240 | 225 | if (alternativeFormats.isEmpty()) { | |
| 241 | 226 | typeFormatMenu.setEnabled(false); | |
| 242 | 227 | individualFormatMenu.setEnabled(false); | |
| 228 | } else { | ||
| 229 | clearIndividualFormatAction = individualFormatMenu.addAction(tr("Clear")); | ||
| 230 | clearIndividualFormatAction->setEnabled(individualFormat != -1); | ||
| 231 | individualFormatMenu.addSeparator(); | ||
| 232 | for (int i = 0; i != alternativeFormats.size(); ++i) { | ||
| 233 | const QString format = alternativeFormats.at(i); | ||
| 234 | QAction *act = new QAction(format, &typeFormatMenu); | ||
| 235 | act->setCheckable(true); | ||
| 236 | if (i == typeFormat) | ||
| 237 | act->setChecked(true); | ||
| 238 | typeFormatMenu.addAction(act); | ||
| 239 | typeFormatActions.append(act); | ||
| 240 | act = new QAction(format, &individualFormatMenu); | ||
| 241 | act->setCheckable(true); | ||
| 242 | if (i == effectiveIndividualFormat) | ||
| 243 | act->setChecked(true); | ||
| 244 | individualFormatMenu.addAction(act); | ||
| 245 | individualFormatActions.append(act); | ||
| 246 | } | ||
| 243 | 247 | } | |
| 244 | 248 | } else { | |
| 245 | 249 | typeFormatMenu.setTitle(tr("Change format for type")); | |
| … | … | ||
| 320 | 320 | m_grabbing = true; | |
| 321 | 321 | } else if (act == actClearCodeModelSnapshot) { | |
| 322 | 322 | m_manager->clearCppCodeModelSnapshot(); | |
| 323 | } else if (clearIndividualFormatAction && act == clearIndividualFormatAction) { | ||
| 324 | model()->setData(mi1, -1, IndividualFormatRole); | ||
| 323 | 325 | } else { | |
| 324 | 326 | for (int i = 0; i != alternativeFormats.size(); ++i) { | |
| 325 | 327 | if (act == typeFormatActions.at(i)) |

