From f82c4efea54dc7f57073b582860637a565288bdc Mon Sep 17 00:00:00 2001 From: Johannes Sixt Date: Tue, 21 Nov 2006 21:19:33 +0100 Subject: [PATCH] Restructure wchar_t support. Stefan's original work submitted a DCprintWChar command from the parse routines. This modification removes this at the expense of special-casing the value replacements that happen in ExprWnd. At the same time, we also reuse the framework that prints structure members to decode the wchar_t strings. --- kdbg/debugger.cpp | 73 +++++++++++++++++++----------------------------------- kdbg/debugger.h | 1 - kdbg/exprwnd.cpp | 63 ++++++++++++++++++++++++++++++++++++++++++---- kdbg/exprwnd.h | 2 ++ kdbg/gdbdriver.cpp | 10 -------- kdbg/typetable.cpp | 2 ++ kdbg/typetable.h | 5 ++++ 7 files changed, 92 insertions(+), 64 deletions(-) diff --git a/kdbg/debugger.cpp b/kdbg/debugger.cpp index 151e492..661cef1 100644 --- a/kdbg/debugger.cpp +++ b/kdbg/debugger.cpp @@ -1045,9 +1045,6 @@ void KDebugger::parse(CmdQueueItem* cmd, const char* output) case DCprintDeref: handlePrintDeref(cmd, output); break; - case DCprintWChar: - handlePrintWChar(cmd, output); - break; case DCattach: m_haveExecutable = true; // fall through @@ -1091,6 +1088,7 @@ void KDebugger::parse(CmdQueueItem* cmd, const char* output) break; case DCprintStruct: case DCprintQStringStruct: + case DCprintWChar: handlePrintStruct(cmd, output); break; case DCinfosharedlib: @@ -1400,34 +1398,6 @@ bool KDebugger::handlePrint(CmdQueueItem* cmd, const char* output) return true; } -bool KDebugger::handlePrintWChar(CmdQueueItem* cmd, const char* output) -{ - ASSERT(cmd->m_expr != 0); - - VarTree* variable = m_d->parseQCharArray(output, false, true); - if (variable == 0) return false; - - variable->setText(cmd->m_expr->getText()); - variable->m_nameKind = VarTree::NKplain; - variable->m_varKind = VarTree::VKsimple; -// variable->m_value = partValue; - - QString val = cmd->m_expr->m_partialValue; - int pos = val.find(") "); - if (pos>0) val = val.mid(pos+2); - variable->m_value = val+" L"+variable->m_value; - - m_localVariables.updateExpr(variable); - delete variable; - - delete cmd->m_expr; - cmd->m_expr = 0; - - evalExpressions(); /* enqueue dereferenced pointers */ - - return true; -} - bool KDebugger::handlePrintDeref(CmdQueueItem* cmd, const char* output) { ASSERT(cmd->m_expr != 0); @@ -1609,23 +1579,14 @@ void KDebugger::dereferencePointer(ExprWnd* wnd, VarTree* exprItem, bool immediate) { ASSERT(exprItem->m_varKind == VarTree::VKpointer); - DbgCommand dbgCmd = DCprintDeref; QString expr = exprItem->computeExpr(); - - if (strncmp(exprItem->m_value, "(const wchar_t *)", 17)==0 || - strncmp(exprItem->m_value, "(wchar_t *)", 11)==0) - { - expr = "*"+expr+"@wcslen("+expr+")"; - dbgCmd = DCprintWChar; - } - TRACE("dereferencing pointer: " + expr); CmdQueueItem* cmd; if (immediate) { - cmd = m_d->queueCmd(dbgCmd, expr, DebuggerDriver::QMoverrideMoreEqual); + cmd = m_d->queueCmd(DCprintDeref, expr, DebuggerDriver::QMoverrideMoreEqual); } else { - cmd = m_d->queueCmd(dbgCmd, expr, DebuggerDriver::QMoverride); + cmd = m_d->queueCmd(DCprintDeref, expr, DebuggerDriver::QMoverride); } // remember which expr this was cmd->m_expr = exprItem; @@ -1692,10 +1653,12 @@ void KDebugger::handlePrintStruct(CmdQueueItem* cmd, const char* output) ASSERT(var->m_varKind == VarTree::VKstruct); VarTree* partExpr; - if (cmd->m_cmd != DCprintQStringStruct) { - partExpr = parseExpr(output, false); - } else { + if (cmd->m_cmd == DCprintQStringStruct) { partExpr = m_d->parseQCharArray(output, false, m_typeTable->qCharIsShort()); + } else if (cmd->m_cmd == DCprintWChar) { + partExpr = m_d->parseQCharArray(output, false, true); + } else { + partExpr = parseExpr(output, false); } bool errorValue = partExpr == 0 || @@ -1760,9 +1723,23 @@ void KDebugger::handlePrintStruct(CmdQueueItem* cmd, const char* output) void KDebugger::evalInitialStructExpression(VarTree* var, ExprWnd* wnd, bool immediate) { var->m_exprIndex = 0; - var->m_exprIndexUseGuard = true; - var->m_partialValue = var->m_type->m_displayString[0]; - evalStructExpression(var, wnd, immediate); + if (var->m_type != TypeInfo::wchartType()) + { + var->m_exprIndexUseGuard = true; + var->m_partialValue = var->m_type->m_displayString[0]; + evalStructExpression(var, wnd, immediate); + } + else + { + var->m_exprIndexUseGuard = false; + QString expr = var->computeExpr(); + CmdQueueItem* cmd = m_d->queueCmd(DCprintWChar, expr, + immediate ? DebuggerDriver::QMoverrideMoreEqual + : DebuggerDriver::QMoverride); + // remember which expression this was + cmd->m_expr = var; + cmd->m_exprWnd = wnd; + } } /* queues a printStruct command; var must have been initialized correctly */ diff --git a/kdbg/debugger.h b/kdbg/debugger.h index ebeabe0..8712462 100644 --- a/kdbg/debugger.h +++ b/kdbg/debugger.h @@ -355,7 +355,6 @@ protected: void handleLocals(const char* output); bool handlePrint(CmdQueueItem* cmd, const char* output); bool handlePrintDeref(CmdQueueItem* cmd, const char* output); - bool handlePrintWChar(CmdQueueItem* cmd, const char* output); void handleBacktrace(const char* output); void handleFrameChange(const char* output); void handleFindType(CmdQueueItem* cmd, const char* output); diff --git a/kdbg/exprwnd.cpp b/kdbg/exprwnd.cpp index b55acff..83e3e11 100644 --- a/kdbg/exprwnd.cpp +++ b/kdbg/exprwnd.cpp @@ -161,6 +161,16 @@ void VarTree::inferTypesOfChildren(ProgramTypeTable& typeTable) // if this is a pointer, get the type from the value (less the pointer) if (m_varKind == VKpointer) { + if (isWcharT()) + { + /* + * wchart_t pointers must be treated as struct, because the array + * of characters is printed similar to how QStrings are decoded. + */ + m_varKind = VKstruct; + setDelayedExpanding(false); + return; + } #ifndef I_know_a_way_to_do_this_cleanly return; #else @@ -217,6 +227,13 @@ void VarTree::inferTypesOfChildren(ProgramTypeTable& typeTable) } } +// the value contains the pointer type in parenthesis +bool VarTree::isWcharT() const +{ + return m_value.startsWith("(const wchar_t *)") || + m_value.startsWith("(wchar_t *)"); +} + /* * Get the type of the first base class whose type we know. */ @@ -433,13 +450,27 @@ void ExprWnd::updateSingleExpr(VarTree* display, VarTree* newValue) * If this node is a struct and we know its type then don't update its * value now. This is a node for which we know how to find a nested * value. So register the node for an update. + * + * wchar_t types are also treated specially here: We consider them + * as struct (has been set in inferTypesOfChildren()). */ if (display->m_varKind == VarTree::VKstruct && display->m_type != 0 && display->m_type != TypeInfo::unknownType()) { ASSERT(newValue->m_varKind == VarTree::VKstruct); - display->m_partialValue = display->m_type->m_displayString[0]; + if (display->m_type == TypeInfo::wchartType()) + { + /* + * We do not copy the new pointer value to the destination right + * away, but consider it as the first part of the nested value. + * Then the display will change its color only when the new value + * is completed. + */ + display->m_partialValue = newValue->m_value + " L"; + } + else + display->m_partialValue = display->m_type->m_displayString[0]; m_updateStruct.append(display); } else @@ -504,8 +535,19 @@ void ExprWnd::collectUnknownTypes(VarTree* var) var->m_varKind == VarTree::VKstruct && var->m_nameKind != VarTree::NKtype) { - /* this struct node doesn't have a type yet: register it */ - m_updateType.append(var); + if (!var->isWcharT()) + { + /* this struct node doesn't have a type yet: register it */ + m_updateType.append(var); + } + else + { + var->m_type = TypeInfo::wchartType(); + // see updateSingleExpr() why we move the value + var->m_partialValue = var->m_value + " L"; + var->m_value.truncate(0); + m_updateStruct.append(var); + } } // add pointer pixmap to pointers @@ -525,8 +567,19 @@ bool ExprWnd::collectUnknownTypes(KTreeViewItem* item, void* user) var->m_varKind == VarTree::VKstruct && var->m_nameKind != VarTree::NKtype) { - /* this struct node doesn't have a type yet: register it */ - tree->m_updateType.append(var); + if (!var->isWcharT()) + { + /* this struct node doesn't have a type yet: register it */ + tree->m_updateType.append(var); + } + else + { + var->m_type = TypeInfo::wchartType(); + // see updateSingleExpr() why we move the value + var->m_partialValue = var->m_value + " L"; + var->m_value.truncate(0); + tree->m_updateStruct.append(var); + } } // add pointer pixmap to pointers if (var->m_varKind == VarTree::VKpointer) { diff --git a/kdbg/exprwnd.h b/kdbg/exprwnd.h index 371654f..0218ec9 100644 --- a/kdbg/exprwnd.h +++ b/kdbg/exprwnd.h @@ -49,6 +49,8 @@ public: void inferTypesOfChildren(ProgramTypeTable& typeTable); /** get the type from base class part */ TypeInfo* inferTypeFromBaseClass(); + /** returns whether the pointer is a wchar_t */ + bool isWcharT() const; }; diff --git a/kdbg/gdbdriver.cpp b/kdbg/gdbdriver.cpp index 4e2e6ae..5801626 100644 --- a/kdbg/gdbdriver.cpp +++ b/kdbg/gdbdriver.cpp @@ -2026,16 +2026,6 @@ void GdbDriver::parseLocals(const char* output, QList& newVars) goto skipDuplicate; } } - if ((variable->m_value.startsWith("(const wchar_t *)") || - variable->m_value.startsWith("(wchar_t *)")) && - !variable->m_value.endsWith(" 0x0")) - { - variable->m_varKind = VarTree::VKsimple; - variable->m_partialValue = variable->m_value; - variable->m_value = QString::null; - CmdQueueItem *c = executeCmd(DCprintWChar, variable->getText()); - c->m_expr = new VarTree(*variable); - } newVars.append(variable); skipDuplicate:; } diff --git a/kdbg/typetable.cpp b/kdbg/typetable.cpp index 10067b9..945bf89 100644 --- a/kdbg/typetable.cpp +++ b/kdbg/typetable.cpp @@ -19,6 +19,8 @@ static QList typeTables; bool typeTablesInited = false; +// an indentifier for wchar_t +TypeInfo TypeInfo::m_wchartType(""); // the unknown type TypeInfo TypeInfo::m_unknownType(""); diff --git a/kdbg/typetable.h b/kdbg/typetable.h index 7159d9f..dc05a53 100644 --- a/kdbg/typetable.h +++ b/kdbg/typetable.h @@ -49,11 +49,16 @@ struct TypeInfo */ QString m_guardStrings[typeInfoMaxExpr]; /** + * Returns a pointer to a TypeInfo that identifies wchar_t + */ + static TypeInfo* wchartType() { return &m_wchartType; } + /** * Gets a pointer to a TypeInfo that means: "I don't know the type" */ static TypeInfo* unknownType() { return &m_unknownType; } protected: + static TypeInfo m_wchartType; static TypeInfo m_unknownType; }; -- 2.11.4.GIT