forked from qt-creator/qt-creator
Merge branch 'master' of git@scm.dev.nokia.troll.no:creator/mainline
This commit is contained in:
@@ -117,6 +117,13 @@ Macro *Environment::bind(const Macro &__macro)
|
||||
return m;
|
||||
}
|
||||
|
||||
void Environment::addMacros(const QList<Macro> ¯os)
|
||||
{
|
||||
foreach (const Macro ¯o, macros) {
|
||||
bind(macro);
|
||||
}
|
||||
}
|
||||
|
||||
Macro *Environment::remove(const QByteArray &name)
|
||||
{
|
||||
Macro macro;
|
||||
@@ -127,6 +134,23 @@ Macro *Environment::remove(const QByteArray &name)
|
||||
return bind(macro);
|
||||
}
|
||||
|
||||
void Environment::reset()
|
||||
{
|
||||
if (_macros) {
|
||||
qDeleteAll(firstMacro(), lastMacro());
|
||||
free(_macros);
|
||||
}
|
||||
|
||||
if (_hash)
|
||||
free(_hash);
|
||||
|
||||
_macros = 0;
|
||||
_allocated_macros = 0;
|
||||
_macro_count = -1;
|
||||
_hash = 0;
|
||||
_hash_count = 401;
|
||||
}
|
||||
|
||||
bool Environment::isBuiltinMacro(const QByteArray &s) const
|
||||
{
|
||||
if (s.length() != 8)
|
||||
|
@@ -56,6 +56,7 @@
|
||||
#include "CPlusPlusForwardDeclarations.h"
|
||||
|
||||
#include <QVector>
|
||||
#include <QList>
|
||||
#include <QByteArray>
|
||||
|
||||
namespace CPlusPlus {
|
||||
@@ -89,6 +90,9 @@ public:
|
||||
Macro **lastMacro()
|
||||
{ return _macros + _macro_count + 1; }
|
||||
|
||||
void reset();
|
||||
void addMacros(const QList<Macro> ¯os);
|
||||
|
||||
private:
|
||||
static unsigned hashCode(const QByteArray &s);
|
||||
void rehash();
|
||||
|
@@ -54,6 +54,11 @@ bool SimpleToken::isKeyword() const
|
||||
return _kind >= T_FIRST_KEYWORD && _kind < T_FIRST_QT_KEYWORD;
|
||||
}
|
||||
|
||||
bool SimpleToken::isComment() const
|
||||
{
|
||||
return _kind == T_COMMENT || _kind == T_DOXY_COMMENT;
|
||||
}
|
||||
|
||||
SimpleLexer::SimpleLexer()
|
||||
: _lastState(0),
|
||||
_skipComments(false),
|
||||
|
@@ -69,6 +69,7 @@ public:
|
||||
bool isLiteral() const;
|
||||
bool isOperator() const;
|
||||
bool isKeyword() const;
|
||||
bool isComment() const;
|
||||
|
||||
public:
|
||||
int _kind;
|
||||
|
@@ -49,6 +49,9 @@ TokenUnderCursor::~TokenUnderCursor()
|
||||
SimpleToken TokenUnderCursor::operator()(const QTextCursor &cursor) const
|
||||
{
|
||||
SimpleLexer tokenize;
|
||||
tokenize.setObjCEnabled(true);
|
||||
tokenize.setSkipComments(false);
|
||||
|
||||
QTextBlock block = cursor.block();
|
||||
int column = cursor.columnNumber();
|
||||
|
||||
|
@@ -43,6 +43,7 @@
|
||||
<glob pattern="*.c++"/>
|
||||
<glob pattern="*.C"/>
|
||||
<glob pattern="*.inl"/>
|
||||
<glob pattern="*.qdoc"/>
|
||||
</mime-type>
|
||||
|
||||
<mime-type type="text/x-objcsrc">
|
||||
|
@@ -740,7 +740,9 @@ void CPPEditor::setFontSettings(const TextEditor::FontSettings &fs)
|
||||
<< QLatin1String(TextEditor::Constants::C_OPERATOR)
|
||||
<< QLatin1String(TextEditor::Constants::C_PREPROCESSOR)
|
||||
<< QLatin1String(TextEditor::Constants::C_LABEL)
|
||||
<< QLatin1String(TextEditor::Constants::C_COMMENT);
|
||||
<< QLatin1String(TextEditor::Constants::C_COMMENT)
|
||||
<< QLatin1String(TextEditor::Constants::C_DOXYGEN_COMMENT)
|
||||
<< QLatin1String(TextEditor::Constants::C_DOXYGEN_TAG);
|
||||
}
|
||||
|
||||
const QVector<QTextCharFormat> formats = fs.toTextCharFormats(categories);
|
||||
|
@@ -16,6 +16,7 @@ HEADERS += cppplugin.h \
|
||||
cppeditorenums.h \
|
||||
cppeditor_global.h \
|
||||
cppclasswizard.h
|
||||
|
||||
SOURCES += cppplugin.cpp \
|
||||
cppeditoractionhandler.cpp \
|
||||
cppeditor.cpp \
|
||||
@@ -23,4 +24,5 @@ SOURCES += cppplugin.cpp \
|
||||
cpphoverhandler.cpp \
|
||||
cppfilewizard.cpp \
|
||||
cppclasswizard.cpp
|
||||
|
||||
RESOURCES += cppeditor.qrc
|
||||
|
@@ -51,6 +51,8 @@ enum CppFormats {
|
||||
CppPreprocessorFormat,
|
||||
CppLabelFormat,
|
||||
CppCommentFormat,
|
||||
CppDoxygenCommentFormat,
|
||||
CppDoxygenTagFormat,
|
||||
NumCppFormats
|
||||
};
|
||||
|
||||
|
@@ -32,6 +32,7 @@
|
||||
***************************************************************************/
|
||||
|
||||
#include "cpphighlighter.h"
|
||||
#include <cpptools/cppdoxygen.h>
|
||||
|
||||
#include <Token.h>
|
||||
#include <cplusplus/SimpleLexer.h>
|
||||
@@ -115,23 +116,35 @@ void CppHighlighter::highlightBlock(const QString &text)
|
||||
}
|
||||
|
||||
bool highlightCurrentWordAsPreprocessor = highlightAsPreprocessor;
|
||||
|
||||
if (highlightAsPreprocessor)
|
||||
highlightAsPreprocessor = false;
|
||||
|
||||
if (i == 0 && tk.is(T_POUND)) {
|
||||
setFormat(tk.position(), tk.length(), m_formats[CppPreprocessorFormat]);
|
||||
highlightAsPreprocessor = true;
|
||||
|
||||
} else if (highlightCurrentWordAsPreprocessor &&
|
||||
(tk.isKeyword() || tk.is(T_IDENTIFIER)) && isPPKeyword(tk.text()))
|
||||
setFormat(tk.position(), tk.length(), m_formats[CppPreprocessorFormat]);
|
||||
|
||||
else if (tk.is(T_INT_LITERAL) || tk.is(T_FLOAT_LITERAL))
|
||||
setFormat(tk.position(), tk.length(), m_formats[CppNumberFormat]);
|
||||
|
||||
else if (tk.is(T_STRING_LITERAL) || tk.is(T_CHAR_LITERAL) || tk.is(T_ANGLE_STRING_LITERAL))
|
||||
setFormat(tk.position(), tk.length(), m_formats[CppStringFormat]);
|
||||
|
||||
else if (tk.is(T_WIDE_STRING_LITERAL) || tk.is(T_WIDE_CHAR_LITERAL))
|
||||
setFormat(tk.position(), tk.length(), m_formats[CppStringFormat]);
|
||||
else if (tk.is(T_COMMENT)) {
|
||||
|
||||
else if (tk.isComment()) {
|
||||
|
||||
if (tk.is(T_COMMENT))
|
||||
setFormat(tk.position(), tk.length(), m_formats[CppCommentFormat]);
|
||||
|
||||
else // a doxygen comment
|
||||
highlightDoxygenComment(text, tk.position(), tk.length());
|
||||
|
||||
// we need to insert a close comment parenthesis, if
|
||||
// - the line starts in a C Comment (initalState != 0)
|
||||
// - the first token of the line is a T_COMMENT (i == 0 && tk.is(T_COMMENT))
|
||||
@@ -145,12 +158,16 @@ void CppHighlighter::highlightBlock(const QString &text)
|
||||
// clear the initial state.
|
||||
initialState = 0;
|
||||
}
|
||||
|
||||
} else if (tk.isKeyword() || isQtKeyword(tk.text()))
|
||||
setFormat(tk.position(), tk.length(), m_formats[CppKeywordFormat]);
|
||||
|
||||
else if (tk.isOperator())
|
||||
setFormat(tk.position(), tk.length(), m_formats[CppOperatorFormat]);
|
||||
|
||||
else if (i == 0 && tokens.size() > 1 && tk.is(T_IDENTIFIER) && tokens.at(1).is(T_COLON))
|
||||
setFormat(tk.position(), tk.length(), m_formats[CppLabelFormat]);
|
||||
|
||||
else if (tk.is(T_IDENTIFIER))
|
||||
highlightWord(tk.text(), tk.position(), tk.length());
|
||||
}
|
||||
@@ -304,3 +321,36 @@ void CppHighlighter::highlightWord(QStringRef word, int position, int length)
|
||||
setFormat(position, length, m_formats[CppTypeFormat]);
|
||||
}
|
||||
}
|
||||
|
||||
void CppHighlighter::highlightDoxygenComment(const QString &text, int position, int)
|
||||
{
|
||||
int initial = position;
|
||||
|
||||
const QChar *uc = text.unicode();
|
||||
const QChar *it = uc + position;
|
||||
|
||||
const QTextCharFormat &format = m_formats[CppDoxygenCommentFormat];
|
||||
const QTextCharFormat &kwFormat = m_formats[CppDoxygenTagFormat];
|
||||
|
||||
while (! it->isNull()) {
|
||||
if (it->unicode() == QLatin1Char('\\') ||
|
||||
it->unicode() == QLatin1Char('@')) {
|
||||
++it;
|
||||
|
||||
const QChar *start = it;
|
||||
while (it->isLetterOrNumber() || it->unicode() == '_')
|
||||
++it;
|
||||
|
||||
int k = CppTools::classifyDoxygenTag(start, it - start);
|
||||
if (k != CppTools::T_DOXY_IDENTIFIER) {
|
||||
setFormat(initial, start - uc - initial, format);
|
||||
setFormat(start - uc - 1, it - start + 1, kwFormat);
|
||||
initial = it - uc;
|
||||
}
|
||||
} else
|
||||
++it;
|
||||
}
|
||||
|
||||
setFormat(initial, it - uc - initial, format);
|
||||
}
|
||||
|
||||
|
@@ -61,6 +61,10 @@ public:
|
||||
|
||||
private:
|
||||
void highlightWord(QStringRef word, int position, int length);
|
||||
|
||||
void highlightDoxygenComment(const QString &text, int position,
|
||||
int length);
|
||||
|
||||
bool isPPKeyword(const QStringRef &text) const;
|
||||
bool isQtKeyword(const QStringRef &text) const;
|
||||
|
||||
|
@@ -32,8 +32,8 @@
|
||||
***************************************************************************/
|
||||
|
||||
#include "cppcodecompletion.h"
|
||||
|
||||
#include "cppmodelmanager.h"
|
||||
#include "cppdoxygen.h"
|
||||
|
||||
#include <Control.h>
|
||||
#include <AST.h>
|
||||
@@ -371,45 +371,53 @@ static int startOfOperator(TextEditor::ITextEditable *editor,
|
||||
const QChar ch3 = pos > 1 ? editor->characterAt(pos - 3) : QChar();
|
||||
|
||||
int start = pos;
|
||||
int k = T_EOF_SYMBOL;
|
||||
|
||||
if (ch2 != QLatin1Char('.') && ch == QLatin1Char('.')) {
|
||||
if (kind)
|
||||
*kind = T_DOT;
|
||||
k = T_DOT;
|
||||
--start;
|
||||
} else if (wantFunctionCall && ch == QLatin1Char('(')) {
|
||||
if (kind)
|
||||
*kind = T_LPAREN;
|
||||
k = T_LPAREN;
|
||||
--start;
|
||||
} else if (ch2 == QLatin1Char(':') && ch == QLatin1Char(':')) {
|
||||
if (kind)
|
||||
*kind = T_COLON_COLON;
|
||||
k = T_COLON_COLON;
|
||||
start -= 2;
|
||||
} else if (ch2 == QLatin1Char('-') && ch == QLatin1Char('>')) {
|
||||
if (kind)
|
||||
*kind = T_ARROW;
|
||||
k = T_ARROW;
|
||||
start -= 2;
|
||||
} else if (ch2 == QLatin1Char('.') && ch == QLatin1Char('*')) {
|
||||
if (kind)
|
||||
*kind = T_DOT_STAR;
|
||||
k = T_DOT_STAR;
|
||||
start -= 2;
|
||||
} else if (ch3 == QLatin1Char('-') && ch2 == QLatin1Char('>') && ch == QLatin1Char('*')) {
|
||||
if (kind)
|
||||
*kind = T_ARROW_STAR;
|
||||
k = T_ARROW_STAR;
|
||||
start -= 3;
|
||||
} else if (ch == QLatin1Char('@') || ch == QLatin1Char('\\')) {
|
||||
k = T_DOXY_COMMENT;
|
||||
--start;
|
||||
}
|
||||
|
||||
if (start != pos) {
|
||||
if (start == pos)
|
||||
return start;
|
||||
|
||||
TextEditor::BaseTextEditor *edit = qobject_cast<TextEditor::BaseTextEditor *>(editor->widget());
|
||||
QTextCursor tc(edit->textCursor());
|
||||
tc.setPosition(pos);
|
||||
|
||||
static CPlusPlus::TokenUnderCursor tokenUnderCursor;
|
||||
const SimpleToken tk = tokenUnderCursor(tc);
|
||||
if (tk.is(T_COMMENT) || tk.isLiteral()) {
|
||||
|
||||
if (k == T_DOXY_COMMENT && tk.isNot(T_DOXY_COMMENT)) {
|
||||
k = T_EOF_SYMBOL;
|
||||
start = pos;
|
||||
}
|
||||
|
||||
else if (tk.is(T_COMMENT) || tk.isLiteral()) {
|
||||
k = T_EOF_SYMBOL;
|
||||
start = pos;
|
||||
}
|
||||
|
||||
if (kind)
|
||||
*kind = T_EOF_SYMBOL;
|
||||
return pos;
|
||||
}
|
||||
}
|
||||
*kind = k;
|
||||
|
||||
return start;
|
||||
}
|
||||
@@ -457,15 +465,32 @@ int CppCodeCompletion::startCompletion(TextEditor::ITextEditable *editor)
|
||||
ExpressionUnderCursor expressionUnderCursor;
|
||||
QString expression;
|
||||
|
||||
|
||||
if (m_completionOperator == T_DOXY_COMMENT) {
|
||||
for (int i = 1; i < T_DOXY_LAST_TAG; ++i) {
|
||||
TextEditor::CompletionItem item(this);
|
||||
item.m_text.append(QString::fromLatin1(doxygenTagSpell(i)));
|
||||
item.m_icon = m_icons.keywordIcon();
|
||||
m_completions.append(item);
|
||||
}
|
||||
|
||||
return m_startPosition;
|
||||
}
|
||||
|
||||
|
||||
if (m_completionOperator) {
|
||||
QTextCursor tc(edit->document());
|
||||
tc.setPosition(endOfExpression);
|
||||
|
||||
expression = expressionUnderCursor(tc);
|
||||
|
||||
if (m_completionOperator == T_LPAREN) {
|
||||
if (expression.endsWith(QLatin1String("SIGNAL")))
|
||||
m_completionOperator = T_SIGNAL;
|
||||
|
||||
else if (expression.endsWith(QLatin1String("SLOT")))
|
||||
m_completionOperator = T_SLOT;
|
||||
|
||||
else if (editor->position() != endOfOperator) {
|
||||
// We don't want a function completion when the cursor isn't at the opening brace
|
||||
expression.clear();
|
||||
|
3149
src/plugins/cpptools/cppdoxygen.cpp
Normal file
3149
src/plugins/cpptools/cppdoxygen.cpp
Normal file
File diff suppressed because it is too large
Load Diff
264
src/plugins/cpptools/cppdoxygen.h
Normal file
264
src/plugins/cpptools/cppdoxygen.h
Normal file
@@ -0,0 +1,264 @@
|
||||
/***************************************************************************
|
||||
**
|
||||
** This file is part of Qt Creator
|
||||
**
|
||||
** Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
|
||||
**
|
||||
** Contact: Qt Software Information (qt-info@nokia.com)
|
||||
**
|
||||
**
|
||||
** Non-Open Source Usage
|
||||
**
|
||||
** Licensees may use this file in accordance with the Qt Beta Version
|
||||
** License Agreement, Agreement version 2.2 provided with the Software or,
|
||||
** alternatively, in accordance with the terms contained in a written
|
||||
** agreement between you and Nokia.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
**
|
||||
** Alternatively, this file may be used under the terms of the GNU General
|
||||
** Public License versions 2.0 or 3.0 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL included in the packaging
|
||||
** of this file. Please review the following information to ensure GNU
|
||||
** General Public Licensing requirements will be met:
|
||||
**
|
||||
** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
|
||||
** http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** In addition, as a special exception, Nokia gives you certain additional
|
||||
** rights. These rights are described in the Nokia Qt GPL Exception
|
||||
** version 1.3, included in the file GPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
***************************************************************************/
|
||||
|
||||
#include "cpptools_global.h"
|
||||
|
||||
namespace CppTools {
|
||||
|
||||
enum DoxygenReservedWord {
|
||||
T_DOXY_IDENTIFIER,
|
||||
T_DOXY_ARG,
|
||||
T_DOXY_ATTENTION,
|
||||
T_DOXY_AUTHOR,
|
||||
T_DOXY_CALLGRAPH,
|
||||
T_DOXY_CODE,
|
||||
T_DOXY_DOT,
|
||||
T_DOXY_ELSE,
|
||||
T_DOXY_ENDCODE,
|
||||
T_DOXY_ENDCOND,
|
||||
T_DOXY_ENDDOT,
|
||||
T_DOXY_ENDHTMLONLY,
|
||||
T_DOXY_ENDIF,
|
||||
T_DOXY_ENDLATEXONLY,
|
||||
T_DOXY_ENDLINK,
|
||||
T_DOXY_ENDMANONLY,
|
||||
T_DOXY_ENDVERBATIM,
|
||||
T_DOXY_ENDXMLONLY,
|
||||
T_DOXY_HIDEINITIALIZER,
|
||||
T_DOXY_HTMLONLY,
|
||||
T_DOXY_INTERFACE,
|
||||
T_DOXY_INTERNAL,
|
||||
T_DOXY_INVARIANT,
|
||||
T_DOXY_LATEXONLY,
|
||||
T_DOXY_LI,
|
||||
T_DOXY_MANONLY,
|
||||
T_DOXY_N,
|
||||
T_DOXY_NOSUBGROUPING,
|
||||
T_DOXY_NOTE,
|
||||
T_DOXY_ONLY,
|
||||
T_DOXY_POST,
|
||||
T_DOXY_PRE,
|
||||
T_DOXY_REMARKS,
|
||||
T_DOXY_RETURN,
|
||||
T_DOXY_RETURNS,
|
||||
T_DOXY_SA,
|
||||
T_DOXY_SEE,
|
||||
T_DOXY_SHOWINITIALIZER,
|
||||
T_DOXY_SINCE,
|
||||
T_DOXY_TEST,
|
||||
T_DOXY_TODO,
|
||||
T_DOXY_VERBATIM,
|
||||
T_DOXY_WARNING,
|
||||
T_DOXY_XMLONLY,
|
||||
T_DOXY_A,
|
||||
T_DOXY_ADDTOGROUP,
|
||||
T_DOXY_ANCHOR,
|
||||
T_DOXY_B,
|
||||
T_DOXY_C,
|
||||
T_DOXY_CLASS,
|
||||
T_DOXY_COND,
|
||||
T_DOXY_COPYDOC,
|
||||
T_DOXY_DEF,
|
||||
T_DOXY_DONTINCLUDE,
|
||||
T_DOXY_DOTFILE,
|
||||
T_DOXY_E,
|
||||
T_DOXY_ELSEIF,
|
||||
T_DOXY_EM,
|
||||
T_DOXY_ENUM,
|
||||
T_DOXY_EXAMPLE,
|
||||
T_DOXY_EXCEPTION,
|
||||
T_DOXY_EXCEPTIONS,
|
||||
T_DOXY_FILE,
|
||||
T_DOXY_HTMLINCLUDE,
|
||||
T_DOXY_IF,
|
||||
T_DOXY_IFNOT,
|
||||
T_DOXY_INCLUDE,
|
||||
T_DOXY_LINK,
|
||||
T_DOXY_NAMESPACE,
|
||||
T_DOXY_P,
|
||||
T_DOXY_PACKAGE,
|
||||
T_DOXY_REF,
|
||||
T_DOXY_RELATES,
|
||||
T_DOXY_RELATESALSO,
|
||||
T_DOXY_RETVAL,
|
||||
T_DOXY_THROW,
|
||||
T_DOXY_THROWS,
|
||||
T_DOXY_VERBINCLUDE,
|
||||
T_DOXY_VERSION,
|
||||
T_DOXY_XREFITEM,
|
||||
T_DOXY_PARAM,
|
||||
T_DOXY_IMAGE,
|
||||
T_DOXY_DEFGROUP,
|
||||
T_DOXY_PAGE,
|
||||
T_DOXY_PARAGRAPH,
|
||||
T_DOXY_SECTION,
|
||||
T_DOXY_STRUCT,
|
||||
T_DOXY_SUBSECTION,
|
||||
T_DOXY_SUBSUBSECTION,
|
||||
T_DOXY_UNION,
|
||||
T_DOXY_WEAKGROUP,
|
||||
T_DOXY_ADDINDEX,
|
||||
T_DOXY_BRIEF,
|
||||
T_DOXY_BUG,
|
||||
T_DOXY_DATE,
|
||||
T_DOXY_DEPRECATED,
|
||||
T_DOXY_FN,
|
||||
T_DOXY_INGROUP,
|
||||
T_DOXY_LINE,
|
||||
T_DOXY_MAINPAGE,
|
||||
T_DOXY_NAME,
|
||||
T_DOXY_OVERLOAD,
|
||||
T_DOXY_PAR,
|
||||
T_DOXY_SHORT,
|
||||
T_DOXY_SKIP,
|
||||
T_DOXY_SKIPLINE,
|
||||
T_DOXY_TYPEDEF,
|
||||
T_DOXY_UNTIL,
|
||||
T_DOXY_VAR,
|
||||
|
||||
T_FIRST_QDOC_TAG,
|
||||
|
||||
T_DOXY_ABSTRACT = T_FIRST_QDOC_TAG,
|
||||
T_DOXY_BADCODE,
|
||||
T_DOXY_BASENAME,
|
||||
T_DOXY_BOLD,
|
||||
T_DOXY_CAPTION,
|
||||
T_DOXY_CHAPTER,
|
||||
T_DOXY_CODELINE,
|
||||
T_DOXY_DOTS,
|
||||
T_DOXY_ENDABSTRACT,
|
||||
T_DOXY_ENDCHAPTER,
|
||||
T_DOXY_ENDFOOTNOTE,
|
||||
T_DOXY_ENDLEGALESE,
|
||||
T_DOXY_ENDLIST,
|
||||
T_DOXY_ENDOMIT,
|
||||
T_DOXY_ENDPART,
|
||||
T_DOXY_ENDQUOTATION,
|
||||
T_DOXY_ENDRAW,
|
||||
T_DOXY_ENDSECTION1,
|
||||
T_DOXY_ENDSECTION2,
|
||||
T_DOXY_ENDSECTION3,
|
||||
T_DOXY_ENDSECTION4,
|
||||
T_DOXY_ENDSIDEBAR,
|
||||
T_DOXY_ENDTABLE,
|
||||
T_DOXY_EXPIRE,
|
||||
T_DOXY_FOOTNOTE,
|
||||
T_DOXY_GENERATELIST,
|
||||
T_DOXY_GRANULARITY,
|
||||
T_DOXY_HEADER,
|
||||
T_DOXY_I,
|
||||
T_DOXY_INDEX,
|
||||
T_DOXY_INLINEIMAGE,
|
||||
T_DOXY_KEYWORD,
|
||||
T_DOXY_L,
|
||||
T_DOXY_LEGALESE,
|
||||
T_DOXY_LIST,
|
||||
T_DOXY_META,
|
||||
T_DOXY_NEWCODE,
|
||||
T_DOXY_O,
|
||||
T_DOXY_OLDCODE,
|
||||
T_DOXY_OMIT,
|
||||
T_DOXY_OMITVALUE,
|
||||
T_DOXY_PART,
|
||||
T_DOXY_PRINTLINE,
|
||||
T_DOXY_PRINTTO,
|
||||
T_DOXY_PRINTUNTIL,
|
||||
T_DOXY_QUOTATION,
|
||||
T_DOXY_QUOTEFILE,
|
||||
T_DOXY_QUOTEFROMFILE,
|
||||
T_DOXY_QUOTEFUNCTION,
|
||||
T_DOXY_RAW,
|
||||
T_DOXY_ROW,
|
||||
T_DOXY_SECTION1,
|
||||
T_DOXY_SECTION2,
|
||||
T_DOXY_SECTION3,
|
||||
T_DOXY_SECTION4,
|
||||
T_DOXY_SIDEBAR,
|
||||
T_DOXY_SKIPTO,
|
||||
T_DOXY_SKIPUNTIL,
|
||||
T_DOXY_SNIPPET,
|
||||
T_DOXY_SUB,
|
||||
T_DOXY_SUP,
|
||||
T_DOXY_TABLE,
|
||||
T_DOXY_TABLEOFCONTENTS,
|
||||
T_DOXY_TARGET,
|
||||
T_DOXY_TT,
|
||||
T_DOXY_UNDERLINE,
|
||||
T_DOXY_UNICODE,
|
||||
T_DOXY_VALUE,
|
||||
T_DOXY_CONTENTSPAGE,
|
||||
T_DOXY_EXTERNALPAGE,
|
||||
T_DOXY_GROUP,
|
||||
T_DOXY_HEADERFILE,
|
||||
T_DOXY_INDEXPAGE,
|
||||
T_DOXY_INHEADERFILE,
|
||||
T_DOXY_MACRO,
|
||||
T_DOXY_MODULE,
|
||||
T_DOXY_NEXTPAGE,
|
||||
T_DOXY_PREVIOUSPAGE,
|
||||
T_DOXY_PROPERTY,
|
||||
T_DOXY_REIMP,
|
||||
T_DOXY_SERVICE,
|
||||
T_DOXY_STARTPAGE,
|
||||
T_DOXY_VARIABLE,
|
||||
T_DOXY_COMPAT,
|
||||
T_DOXY_INMODULE,
|
||||
T_DOXY_MAINCLASS,
|
||||
T_DOXY_NONREENTRANT,
|
||||
T_DOXY_OBSOLETE,
|
||||
T_DOXY_PRELIMINARY,
|
||||
T_DOXY_INPUBLICGROUP,
|
||||
T_DOXY_REENTRANT,
|
||||
T_DOXY_SUBTITLE,
|
||||
T_DOXY_THREADSAFE,
|
||||
T_DOXY_TITLE,
|
||||
T_DOXY_CORELIB,
|
||||
T_DOXY_UITOOLS,
|
||||
T_DOXY_GUI,
|
||||
T_DOXY_NETWORK,
|
||||
T_DOXY_OPENGL,
|
||||
T_DOXY_QT3SUPPORT,
|
||||
T_DOXY_SVG,
|
||||
T_DOXY_SQL,
|
||||
T_DOXY_QTESTLIB,
|
||||
T_DOXY_WEBKIT,
|
||||
T_DOXY_XML,
|
||||
|
||||
T_DOXY_LAST_TAG
|
||||
};
|
||||
|
||||
CPPTOOLS_EXPORT int classifyDoxygenTag(const QChar *s, int n);
|
||||
CPPTOOLS_EXPORT const char *doxygenTagSpell(int index);
|
||||
|
||||
} // namespace ::CppTools
|
||||
|
@@ -48,6 +48,7 @@
|
||||
|
||||
#include <coreplugin/icore.h>
|
||||
#include <coreplugin/uniqueidmanager.h>
|
||||
#include <coreplugin/mimedatabase.h>
|
||||
#include <coreplugin/editormanager/editormanager.h>
|
||||
#include <coreplugin/progressmanager/progressmanager.h>
|
||||
|
||||
@@ -140,6 +141,10 @@ static const char pp_configuration[] =
|
||||
"#define restrict\n"
|
||||
"#define __restrict\n"
|
||||
|
||||
"#define __complex__\n"
|
||||
"#define __imag__\n"
|
||||
"#define __real__\n"
|
||||
|
||||
// ### add macros for win32
|
||||
"#define __cdecl\n"
|
||||
"#define QT_WA(x) x\n"
|
||||
@@ -164,9 +169,16 @@ public:
|
||||
void setIncludePaths(const QStringList &includePaths);
|
||||
void setFrameworkPaths(const QStringList &frameworkPaths);
|
||||
void setProjectFiles(const QStringList &files);
|
||||
void setTodo(const QStringList &files);
|
||||
|
||||
void run(QString &fileName);
|
||||
void operator()(QString &fileName);
|
||||
|
||||
void resetEnvironment();
|
||||
|
||||
const QSet<QString> &todo() const
|
||||
{ return m_todo; }
|
||||
|
||||
public: // attributes
|
||||
Snapshot snapshot;
|
||||
|
||||
@@ -200,6 +212,7 @@ private:
|
||||
QStringList m_frameworkPaths;
|
||||
QSet<QString> m_included;
|
||||
CPlusPlus::Document::Ptr m_currentDoc;
|
||||
QSet<QString> m_todo;
|
||||
};
|
||||
|
||||
} // namespace Internal
|
||||
@@ -223,9 +236,15 @@ void CppPreprocessor::setFrameworkPaths(const QStringList &frameworkPaths)
|
||||
void CppPreprocessor::setProjectFiles(const QStringList &files)
|
||||
{ m_projectFiles = files; }
|
||||
|
||||
void CppPreprocessor::setTodo(const QStringList &files)
|
||||
{ m_todo = QSet<QString>::fromList(files); }
|
||||
|
||||
void CppPreprocessor::run(QString &fileName)
|
||||
{ sourceNeeded(fileName, IncludeGlobal, /*line = */ 0); }
|
||||
|
||||
void CppPreprocessor::resetEnvironment()
|
||||
{ env.reset(); }
|
||||
|
||||
void CppPreprocessor::operator()(QString &fileName)
|
||||
{ run(fileName); }
|
||||
|
||||
@@ -386,7 +405,7 @@ void CppPreprocessor::mergeEnvironment(Document::Ptr doc, QSet<QString> *process
|
||||
|
||||
processed->insert(fn);
|
||||
|
||||
foreach (Document::Include incl, doc->includes()) {
|
||||
foreach (const Document::Include &incl, doc->includes()) {
|
||||
QString includedFile = incl.fileName();
|
||||
|
||||
if (Document::Ptr includedDoc = snapshot.value(includedFile))
|
||||
@@ -395,9 +414,7 @@ void CppPreprocessor::mergeEnvironment(Document::Ptr doc, QSet<QString> *process
|
||||
run(includedFile);
|
||||
}
|
||||
|
||||
foreach (const Macro macro, doc->definedMacros()) {
|
||||
env.bind(macro);
|
||||
}
|
||||
env.addMacros(doc->definedMacros());
|
||||
}
|
||||
|
||||
void CppPreprocessor::startSkippingBlocks(unsigned offset)
|
||||
@@ -424,55 +441,59 @@ void CppPreprocessor::sourceNeeded(QString &fileName, IncludeType type,
|
||||
|
||||
if (m_currentDoc) {
|
||||
m_currentDoc->addIncludeFile(fileName, line);
|
||||
|
||||
if (contents.isEmpty() && ! QFileInfo(fileName).isAbsolute()) {
|
||||
QString msg;
|
||||
|
||||
msg += fileName;
|
||||
msg += QLatin1String(": No such file or directory");
|
||||
|
||||
Document::DiagnosticMessage d(Document::DiagnosticMessage::Warning,
|
||||
m_currentDoc->fileName(),
|
||||
env.currentLine, /*column = */ 0,
|
||||
msg);
|
||||
|
||||
m_currentDoc->addDiagnosticMessage(d);
|
||||
|
||||
//qWarning() << "file not found:" << fileName << m_currentDoc->fileName() << env.current_line;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (! contents.isEmpty()) {
|
||||
Document::Ptr cachedDoc = snapshot.value(fileName);
|
||||
if (cachedDoc && m_currentDoc) {
|
||||
mergeEnvironment(cachedDoc);
|
||||
} else {
|
||||
Document::Ptr previousDoc = switchDocument(Document::create(fileName));
|
||||
//qDebug() << "parse file:" << fileName << "contents:" << contents.size();
|
||||
|
||||
const QByteArray previousFile = env.currentFile;
|
||||
const unsigned previousLine = env.currentLine;
|
||||
Document::Ptr doc = snapshot.value(fileName);
|
||||
if (doc) {
|
||||
mergeEnvironment(doc);
|
||||
return;
|
||||
}
|
||||
|
||||
TranslationUnit *unit = m_currentDoc->translationUnit();
|
||||
env.currentFile = QByteArray(unit->fileName(), unit->fileNameLength());
|
||||
doc = Document::create(fileName);
|
||||
|
||||
Document::Ptr previousDoc = switchDocument(doc);
|
||||
|
||||
QByteArray preprocessedCode;
|
||||
m_proc(contents, &preprocessedCode);
|
||||
//qDebug() << preprocessedCode;
|
||||
m_proc(fileName.toUtf8(), contents, &preprocessedCode);
|
||||
|
||||
env.currentFile = previousFile;
|
||||
env.currentLine = previousLine;
|
||||
doc->setSource(preprocessedCode);
|
||||
|
||||
m_currentDoc->setSource(preprocessedCode);
|
||||
m_currentDoc->parse();
|
||||
doc->parse();
|
||||
doc->check();
|
||||
|
||||
#if defined(QTCREATOR_WITH_DUMP_AST) && defined(Q_CC_GNU)
|
||||
DumpAST dump(m_currentDoc->control());
|
||||
dump(m_currentDoc->translationUnit()->ast());
|
||||
#endif
|
||||
|
||||
m_currentDoc->check();
|
||||
m_currentDoc->releaseTranslationUnit(); // release the AST and the token stream.
|
||||
doc->releaseTranslationUnit();
|
||||
|
||||
snapshot[fileName] = doc;
|
||||
|
||||
if (m_modelManager)
|
||||
m_modelManager->emitDocumentUpdated(m_currentDoc);
|
||||
m_modelManager->emitDocumentUpdated(m_currentDoc); // ### TODO: compress
|
||||
|
||||
(void) switchDocument(previousDoc);
|
||||
}
|
||||
}
|
||||
m_todo.remove(fileName);
|
||||
}
|
||||
|
||||
Document::Ptr CppPreprocessor::switchDocument(Document::Ptr doc)
|
||||
@@ -737,7 +758,7 @@ void CppModelManager::onDocumentUpdated(Document::Ptr doc)
|
||||
|
||||
QList<TextEditor::BaseTextEditor::BlockRange> blockRanges;
|
||||
|
||||
foreach (const Document::Block block, doc->skippedBlocks()) {
|
||||
foreach (const Document::Block &block, doc->skippedBlocks()) {
|
||||
blockRanges.append(TextEditor::BaseTextEditor::BlockRange(block.begin(), block.end()));
|
||||
}
|
||||
ed->setIfdefedOutBlocks(blockRanges);
|
||||
@@ -750,7 +771,7 @@ void CppModelManager::onDocumentUpdated(Document::Ptr doc)
|
||||
macroFormat.setUnderlineStyle(QTextCharFormat::SingleUnderline);
|
||||
|
||||
QTextCursor c = ed->textCursor();
|
||||
foreach (const Document::Block block, doc->macroUses()) {
|
||||
foreach (const Document::MacroUse &block, doc->macroUses()) {
|
||||
QTextEdit::ExtraSelection sel;
|
||||
sel.cursor = c;
|
||||
sel.cursor.setPosition(block.begin());
|
||||
@@ -771,7 +792,7 @@ void CppModelManager::onDocumentUpdated(Document::Ptr doc)
|
||||
warningFormat.setUnderlineColor(Qt::darkYellow);
|
||||
|
||||
QSet<int> lines;
|
||||
foreach (const Document::DiagnosticMessage m, doc->diagnosticMessages()) {
|
||||
foreach (const Document::DiagnosticMessage &m, doc->diagnosticMessages()) {
|
||||
if (m.fileName() != fileName)
|
||||
continue;
|
||||
else if (lines.contains(m.line()))
|
||||
@@ -799,7 +820,7 @@ void CppModelManager::onDocumentUpdated(Document::Ptr doc)
|
||||
}
|
||||
|
||||
QList<Editor> todo;
|
||||
foreach (Editor e, todo) {
|
||||
foreach (const Editor &e, todo) {
|
||||
if (e.widget != ed)
|
||||
todo.append(e);
|
||||
}
|
||||
@@ -822,7 +843,7 @@ void CppModelManager::postEditorUpdate()
|
||||
|
||||
void CppModelManager::updateEditorSelections()
|
||||
{
|
||||
foreach (Editor ed, m_todo) {
|
||||
foreach (const Editor &ed, m_todo) {
|
||||
if (! ed.widget)
|
||||
continue;
|
||||
|
||||
@@ -872,20 +893,40 @@ void CppModelManager::parse(QFutureInterface<void> &future,
|
||||
if (files.isEmpty())
|
||||
return;
|
||||
|
||||
foreach (QString file, files) {
|
||||
Core::MimeDatabase *db = Core::ICore::instance()->mimeDatabase();
|
||||
QStringList headers, sources;
|
||||
Core::MimeType cSourceTy = db->findByType(QLatin1String("text/x-csrc"));
|
||||
Core::MimeType cppSourceTy = db->findByType(QLatin1String("text/x-c++src"));
|
||||
|
||||
foreach (const QString &file, files) {
|
||||
const QFileInfo fileInfo(file);
|
||||
|
||||
if (cSourceTy.matchesFile(fileInfo) || cppSourceTy.matchesFile(fileInfo))
|
||||
sources.append(file);
|
||||
|
||||
else
|
||||
headers.append(file);
|
||||
}
|
||||
|
||||
foreach (const QString &file, files) {
|
||||
preproc->snapshot.remove(file);
|
||||
}
|
||||
|
||||
files = sources;
|
||||
files += headers;
|
||||
|
||||
preproc->setTodo(files);
|
||||
|
||||
// Change the priority of the background parser thread to idle.
|
||||
QThread::currentThread()->setPriority(QThread::IdlePriority);
|
||||
|
||||
future.setProgressRange(0, files.size());
|
||||
|
||||
QString conf = QLatin1String(pp_configuration_file);
|
||||
(void) preproc->run(conf);
|
||||
|
||||
const int STEP = 10;
|
||||
|
||||
bool processingHeaders = false;
|
||||
|
||||
for (int i = 0; i < files.size(); ++i) {
|
||||
if (future.isPaused())
|
||||
future.waitForResume();
|
||||
@@ -893,16 +934,33 @@ void CppModelManager::parse(QFutureInterface<void> &future,
|
||||
if (future.isCanceled())
|
||||
break;
|
||||
|
||||
future.setProgressValue(i);
|
||||
|
||||
#ifdef CPPTOOLS_DEBUG_PARSING_TIME
|
||||
QTime tm;
|
||||
tm.start();
|
||||
#endif
|
||||
|
||||
QString fileName = files.at(i);
|
||||
|
||||
bool isSourceFile = false;
|
||||
if (cppSourceTy.matchesFile(fileName) || cSourceTy.matchesFile(fileName))
|
||||
isSourceFile = true;
|
||||
|
||||
if (isSourceFile)
|
||||
(void) preproc->run(conf);
|
||||
|
||||
else if (! processingHeaders) {
|
||||
(void) preproc->run(conf);
|
||||
|
||||
processingHeaders = true;
|
||||
}
|
||||
|
||||
preproc->run(fileName);
|
||||
|
||||
future.setProgressValue(files.size() - preproc->todo().size());
|
||||
|
||||
if (isSourceFile)
|
||||
preproc->resetEnvironment();
|
||||
|
||||
if (! (i % STEP)) // Yields execution of the current thread.
|
||||
QThread::yieldCurrentThread();
|
||||
|
||||
|
@@ -8,27 +8,29 @@ include(cpptools_dependencies.pri)
|
||||
DEFINES += QT_NO_CAST_TO_ASCII
|
||||
INCLUDEPATH += .
|
||||
DEFINES += CPPTOOLS_LIBRARY
|
||||
HEADERS += cpptools_global.h \
|
||||
cppquickopenfilter.h \
|
||||
HEADERS += completionsettingspage.h \
|
||||
cppclassesfilter.h \
|
||||
searchsymbols.h \
|
||||
cppfunctionsfilter.h \
|
||||
completionsettingspage.h
|
||||
SOURCES += cppquickopenfilter.cpp \
|
||||
cpptoolseditorsupport.cpp \
|
||||
cppclassesfilter.cpp \
|
||||
searchsymbols.cpp \
|
||||
cppfunctionsfilter.cpp \
|
||||
completionsettingspage.cpp
|
||||
|
||||
# Input
|
||||
SOURCES += cpptoolsplugin.cpp \
|
||||
cppmodelmanager.cpp \
|
||||
cppcodecompletion.cpp
|
||||
HEADERS += cpptoolsplugin.h \
|
||||
cppmodelmanager.h \
|
||||
cppcodecompletion.h \
|
||||
cppfunctionsfilter.h \
|
||||
cppmodelmanager.h \
|
||||
cppmodelmanagerinterface.h \
|
||||
cppquickopenfilter.h \
|
||||
cpptools_global.h \
|
||||
cpptoolsconstants.h \
|
||||
cpptoolseditorsupport.h \
|
||||
cpptoolsconstants.h
|
||||
cpptoolsplugin.h \
|
||||
searchsymbols.h \
|
||||
cppdoxygen.h
|
||||
|
||||
SOURCES += completionsettingspage.cpp \
|
||||
cppclassesfilter.cpp \
|
||||
cppcodecompletion.cpp \
|
||||
cppfunctionsfilter.cpp \
|
||||
cppmodelmanager.cpp \
|
||||
cppquickopenfilter.cpp \
|
||||
cpptoolseditorsupport.cpp \
|
||||
cpptoolsplugin.cpp \
|
||||
searchsymbols.cpp \
|
||||
cppdoxygen.cpp
|
||||
|
||||
FORMS += completionsettingspage.ui
|
||||
|
@@ -34,6 +34,8 @@
|
||||
#ifndef CPPTOOLS_GLOBAL_H
|
||||
#define CPPTOOLS_GLOBAL_H
|
||||
|
||||
#include <QtGlobal>
|
||||
|
||||
#if defined(CPPTOOLS_LIBRARY)
|
||||
# define CPPTOOLS_EXPORT Q_DECL_EXPORT
|
||||
#else
|
||||
|
34
src/plugins/debugger/cdb/cdb.pri
Normal file
34
src/plugins/debugger/cdb/cdb.pri
Normal file
@@ -0,0 +1,34 @@
|
||||
win32 {
|
||||
# ---- Detect Debugging Tools For Windows
|
||||
|
||||
CDB_PATH="$$(ProgramFiles)/Debugging Tools For Windows/sdk"
|
||||
|
||||
exists ($$CDB_PATH) {
|
||||
message("Experimental: Adding support for $$CDB_PATH")
|
||||
|
||||
DEFINES+=CDB_ENABLED
|
||||
|
||||
CDB_PLATFORM=i386
|
||||
|
||||
INCLUDEPATH*=$$CDB_PATH
|
||||
INCLUDEPATH*=$$PWD
|
||||
|
||||
CDB_LIBPATH=$$CDB_PATH/lib/$$CDB_PLATFORM
|
||||
|
||||
HEADERS += \
|
||||
$$PWD/cdbdebugengine.h \
|
||||
$$PWD/cdbdebugengine_p.h \
|
||||
$$PWD/cdbdebugeventcallback.h \
|
||||
$$PWD/cdbdebugoutput.h
|
||||
|
||||
SOURCES += \
|
||||
$$PWD/cdbdebugengine.cpp \
|
||||
$$PWD/cdbdebugeventcallback.cpp \
|
||||
$$PWD/cdbdebugoutput.cpp
|
||||
|
||||
LIBS += -L$$CDB_LIBPATH Dbghelp.lib dbgeng.lib
|
||||
|
||||
} else {
|
||||
error("Debugging Tools for Windows could not be found in $$CDB_PATH")
|
||||
}
|
||||
}
|
@@ -1,4 +1,38 @@
|
||||
/***************************************************************************
|
||||
**
|
||||
** This file is part of Qt Creator
|
||||
**
|
||||
** Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
|
||||
**
|
||||
** Contact: Qt Software Information (qt-info@nokia.com)
|
||||
**
|
||||
**
|
||||
** Non-Open Source Usage
|
||||
**
|
||||
** Licensees may use this file in accordance with the Qt Beta Version
|
||||
** License Agreement, Agreement version 2.2 provided with the Software or,
|
||||
** alternatively, in accordance with the terms contained in a written
|
||||
** agreement between you and Nokia.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
**
|
||||
** Alternatively, this file may be used under the terms of the GNU General
|
||||
** Public License versions 2.0 or 3.0 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL included in the packaging
|
||||
** of this file. Please review the following information to ensure GNU
|
||||
** General Public Licensing requirements will be met:
|
||||
**
|
||||
** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
|
||||
** http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** In addition, as a special exception, Nokia gives you certain additional
|
||||
** rights. These rights are described in the Nokia Qt GPL Exception
|
||||
** version 1.3, included in the file GPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
***************************************************************************/
|
||||
|
||||
#include "cdbdebugengine.h"
|
||||
#include "cdbdebugengine_p.h"
|
||||
|
||||
#include "debuggermanager.h"
|
||||
#include "breakhandler.h"
|
||||
@@ -6,30 +40,28 @@
|
||||
|
||||
#include <utils/qtcassert.h>
|
||||
|
||||
#include <QDebug>
|
||||
#include <QTimerEvent>
|
||||
#include <QFileInfo>
|
||||
#include <QtCore/QDebug>
|
||||
#include <QtCore/QTimerEvent>
|
||||
#include <QtCore/QFileInfo>
|
||||
#include <QtCore/QDir>
|
||||
|
||||
#define DBGHELP_TRANSLATE_TCHAR
|
||||
#include <Dbghelp.h>
|
||||
#include <inc/Dbghelp.h>
|
||||
|
||||
using namespace Debugger;
|
||||
using namespace Debugger::Internal;
|
||||
|
||||
|
||||
CdbDebugEngine::CdbDebugEngine(DebuggerManager *parent)
|
||||
: IDebuggerEngine(parent),
|
||||
CdbDebugEnginePrivate::CdbDebugEnginePrivate(DebuggerManager *parent, CdbDebugEngine* engine) :
|
||||
m_hDebuggeeProcess(0),
|
||||
m_hDebuggeeThread(0),
|
||||
//m_hDebuggeeImage(0),
|
||||
m_bIgnoreNextDebugEvent(false),
|
||||
m_watchTimer(-1),
|
||||
m_debugEventCallBack(this),
|
||||
m_debugOutputCallBack(this)
|
||||
m_debugEventCallBack(engine),
|
||||
m_debugOutputCallBack(engine),
|
||||
m_engine(engine),
|
||||
m_debuggerManager(parent),
|
||||
m_debuggerManagerAccess(parent->engineInterface())
|
||||
{
|
||||
q = parent;
|
||||
qq = parent->engineInterface();
|
||||
|
||||
HRESULT hr;
|
||||
hr = DebugCreate( __uuidof(IDebugClient5), reinterpret_cast<void**>(&m_pDebugClient));
|
||||
if (FAILED(hr)) m_pDebugClient = 0;
|
||||
@@ -51,7 +83,7 @@ CdbDebugEngine::CdbDebugEngine(DebuggerManager *parent)
|
||||
}
|
||||
}
|
||||
|
||||
CdbDebugEngine::~CdbDebugEngine()
|
||||
CdbDebugEnginePrivate::~CdbDebugEnginePrivate()
|
||||
{
|
||||
if (m_pDebugClient)
|
||||
m_pDebugClient->Release();
|
||||
@@ -65,17 +97,28 @@ CdbDebugEngine::~CdbDebugEngine()
|
||||
m_pDebugRegisters->Release();
|
||||
}
|
||||
|
||||
CdbDebugEngine::CdbDebugEngine(DebuggerManager *parent)
|
||||
: IDebuggerEngine(parent),
|
||||
m_d(new CdbDebugEnginePrivate(parent, this))
|
||||
{
|
||||
}
|
||||
|
||||
CdbDebugEngine::~CdbDebugEngine()
|
||||
{
|
||||
delete m_d;
|
||||
}
|
||||
|
||||
void CdbDebugEngine::startWatchTimer()
|
||||
{
|
||||
if (m_watchTimer == -1)
|
||||
m_watchTimer = startTimer(0);
|
||||
if (m_d->m_watchTimer == -1)
|
||||
m_d->m_watchTimer = startTimer(0);
|
||||
}
|
||||
|
||||
void CdbDebugEngine::killWatchTimer()
|
||||
{
|
||||
if (m_watchTimer != -1) {
|
||||
killTimer(m_watchTimer);
|
||||
m_watchTimer = -1;
|
||||
if (m_d->m_watchTimer != -1) {
|
||||
killTimer(m_d->m_watchTimer);
|
||||
m_d->m_watchTimer = -1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -84,13 +127,13 @@ void CdbDebugEngine::shutdown()
|
||||
exitDebugger();
|
||||
}
|
||||
|
||||
void CdbDebugEngine::setToolTipExpression(const QPoint &pos, const QString &exp)
|
||||
void CdbDebugEngine::setToolTipExpression(const QPoint & /*pos*/, const QString & /*exp*/)
|
||||
{
|
||||
}
|
||||
|
||||
bool CdbDebugEngine::startDebugger()
|
||||
{
|
||||
q->showStatusMessage("Starting Debugger", -1);
|
||||
m_d->m_debuggerManager->showStatusMessage("Starting Debugger", -1);
|
||||
|
||||
//if (!q->m_workingDir.isEmpty())
|
||||
// m_gdbProc.setWorkingDirectory(q->m_workingDir);
|
||||
@@ -101,19 +144,21 @@ bool CdbDebugEngine::startDebugger()
|
||||
memset(&dbgopts, 0, sizeof(dbgopts));
|
||||
dbgopts.CreateFlags = DEBUG_PROCESS | DEBUG_ONLY_THIS_PROCESS;
|
||||
|
||||
HRESULT hr;
|
||||
const QString filename(m_d->m_debuggerManager->m_executable);
|
||||
if (debugCDB)
|
||||
qDebug() << Q_FUNC_INFO <<filename;
|
||||
|
||||
QString filename(q->m_executable);
|
||||
QFileInfo fi(filename);
|
||||
m_pDebugSymbols->AppendImagePathWide(fi.absolutePath().replace('/','\\').utf16());
|
||||
const QFileInfo fi(filename);
|
||||
m_d->m_pDebugSymbols->AppendImagePathWide(QDir::toNativeSeparators(fi.absolutePath()).utf16());
|
||||
//m_pDebugSymbols->SetSymbolOptions(SYMOPT_CASE_INSENSITIVE | SYMOPT_UNDNAME | SYMOPT_DEBUG | SYMOPT_LOAD_LINES | SYMOPT_OMAP_FIND_NEAREST | SYMOPT_AUTO_PUBLICS);
|
||||
m_pDebugSymbols->SetSymbolOptions(SYMOPT_CASE_INSENSITIVE | SYMOPT_UNDNAME | SYMOPT_LOAD_LINES | SYMOPT_OMAP_FIND_NEAREST | SYMOPT_AUTO_PUBLICS);
|
||||
m_d->m_pDebugSymbols->SetSymbolOptions(SYMOPT_CASE_INSENSITIVE | SYMOPT_UNDNAME | SYMOPT_LOAD_LINES | SYMOPT_OMAP_FIND_NEAREST | SYMOPT_AUTO_PUBLICS);
|
||||
//m_pDebugSymbols->AddSymbolOptions(SYMOPT_CASE_INSENSITIVE | SYMOPT_UNDNAME | SYMOPT_DEFERRED_LOADS | SYMOPT_DEBUG | SYMOPT_LOAD_LINES | SYMOPT_OMAP_FIND_NEAREST | SYMOPT_AUTO_PUBLICS | SYMOPT_NO_IMAGE_SEARCH);
|
||||
|
||||
if (q->startMode() == q->attachExternal) {
|
||||
if (m_d->m_debuggerManager->startMode() == DebuggerManager::AttachExternal) {
|
||||
qWarning("CdbDebugEngine: attach to process not yet implemented!");
|
||||
return false;
|
||||
} else {
|
||||
hr = m_pDebugClient->CreateProcess2Wide(NULL,
|
||||
HRESULT hr = m_d->m_pDebugClient->CreateProcess2Wide(NULL,
|
||||
const_cast<PWSTR>(filename.utf16()),
|
||||
&dbgopts,
|
||||
sizeof(dbgopts),
|
||||
@@ -121,19 +166,22 @@ bool CdbDebugEngine::startDebugger()
|
||||
NULL); // TODO: think about setting the environment
|
||||
if (FAILED(hr)) {
|
||||
//qWarning("CreateProcess2Wide failed");
|
||||
qq->notifyInferiorExited();
|
||||
m_d->m_debuggerManagerAccess->notifyInferiorExited();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
q->showStatusMessage(tr("Debugger Running"), -1);
|
||||
m_d->m_debuggerManager->showStatusMessage(tr("Debugger Running"), -1);
|
||||
startWatchTimer();
|
||||
return true;
|
||||
}
|
||||
|
||||
void CdbDebugEngine::exitDebugger()
|
||||
{
|
||||
m_pDebugClient->TerminateCurrentProcess();
|
||||
if (debugCDB)
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
|
||||
m_d->m_pDebugClient->TerminateCurrentProcess();
|
||||
killWatchTimer();
|
||||
}
|
||||
|
||||
@@ -143,18 +191,22 @@ void CdbDebugEngine::updateWatchModel()
|
||||
|
||||
void CdbDebugEngine::stepExec()
|
||||
{
|
||||
//qDebug() << "CdbDebugEngine::stepExec()";
|
||||
if (debugCDB)
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
|
||||
//m_pDebugControl->Execute(DEBUG_OUTCTL_THIS_CLIENT, "p", 0);
|
||||
HRESULT hr;
|
||||
hr = m_pDebugControl->SetExecutionStatus(DEBUG_STATUS_STEP_INTO);
|
||||
m_bIgnoreNextDebugEvent = true;
|
||||
hr = m_d->m_pDebugControl->SetExecutionStatus(DEBUG_STATUS_STEP_INTO);
|
||||
m_d->m_bIgnoreNextDebugEvent = true;
|
||||
startWatchTimer();
|
||||
}
|
||||
|
||||
void CdbDebugEngine::stepOutExec()
|
||||
{
|
||||
//qDebug() << "CdbDebugEngine::stepOutExec()";
|
||||
StackHandler* sh = qq->stackHandler();
|
||||
if (debugCDB)
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
|
||||
StackHandler* sh = m_d->m_debuggerManagerAccess->stackHandler();
|
||||
const int idx = sh->currentIndex() + 1;
|
||||
QList<StackFrame> stackframes = sh->frames();
|
||||
if (idx < 0 || idx >= stackframes.size()) {
|
||||
@@ -171,7 +223,7 @@ void CdbDebugEngine::stepOutExec()
|
||||
}
|
||||
|
||||
IDebugBreakpoint2* pBP;
|
||||
HRESULT hr = m_pDebugControl->AddBreakpoint2(DEBUG_BREAKPOINT_CODE, DEBUG_ANY_ID, &pBP);
|
||||
HRESULT hr = m_d->m_pDebugControl->AddBreakpoint2(DEBUG_BREAKPOINT_CODE, DEBUG_ANY_ID, &pBP);
|
||||
if (FAILED(hr) || !pBP) {
|
||||
qWarning("stepOutExec: cannot create temporary breakpoint");
|
||||
return;
|
||||
@@ -194,9 +246,11 @@ void CdbDebugEngine::stepOutExec()
|
||||
|
||||
void CdbDebugEngine::nextExec()
|
||||
{
|
||||
//qDebug() << "CdbDebugEngine::nextExec()";
|
||||
if (debugCDB)
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
|
||||
HRESULT hr;
|
||||
hr = m_pDebugControl->SetExecutionStatus(DEBUG_STATUS_STEP_OVER);
|
||||
hr = m_d->m_pDebugControl->SetExecutionStatus(DEBUG_STATUS_STEP_OVER);
|
||||
startWatchTimer();
|
||||
}
|
||||
|
||||
@@ -207,68 +261,85 @@ void CdbDebugEngine::stepIExec()
|
||||
|
||||
void CdbDebugEngine::nextIExec()
|
||||
{
|
||||
m_pDebugControl->Execute(DEBUG_OUTCTL_THIS_CLIENT, "p", 0);
|
||||
if (debugCDB)
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
|
||||
m_d->m_pDebugControl->Execute(DEBUG_OUTCTL_THIS_CLIENT, "p", 0);
|
||||
startWatchTimer();
|
||||
}
|
||||
|
||||
void CdbDebugEngine::continueInferior()
|
||||
{
|
||||
if (debugCDB)
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
|
||||
killWatchTimer();
|
||||
q->resetLocation();
|
||||
m_d->m_debuggerManager->resetLocation();
|
||||
|
||||
ULONG executionStatus;
|
||||
HRESULT hr = m_pDebugControl->GetExecutionStatus(&executionStatus);
|
||||
HRESULT hr = m_d->m_pDebugControl->GetExecutionStatus(&executionStatus);
|
||||
if (SUCCEEDED(hr) && executionStatus != DEBUG_STATUS_GO)
|
||||
m_pDebugControl->SetExecutionStatus(DEBUG_STATUS_GO);
|
||||
m_d->m_pDebugControl->SetExecutionStatus(DEBUG_STATUS_GO);
|
||||
|
||||
startWatchTimer();
|
||||
qq->notifyInferiorRunning();
|
||||
}
|
||||
|
||||
void CdbDebugEngine::runInferior()
|
||||
{
|
||||
continueInferior();
|
||||
m_d->m_debuggerManagerAccess->notifyInferiorRunning();
|
||||
}
|
||||
|
||||
void CdbDebugEngine::interruptInferior()
|
||||
{
|
||||
if (debugCDB)
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
|
||||
//TODO: better use IDebugControl::SetInterrupt?
|
||||
if (!m_hDebuggeeProcess)
|
||||
if (!m_d->m_hDebuggeeProcess)
|
||||
return;
|
||||
if (!DebugBreakProcess(m_hDebuggeeProcess)) {
|
||||
if (!DebugBreakProcess(m_d->m_hDebuggeeProcess)) {
|
||||
qWarning("DebugBreakProcess failed.");
|
||||
return;
|
||||
}
|
||||
qq->notifyInferiorStopped();
|
||||
m_d->m_debuggerManagerAccess->notifyInferiorStopped();
|
||||
}
|
||||
|
||||
void CdbDebugEngine::runToLineExec(const QString &fileName, int lineNumber)
|
||||
{
|
||||
if (debugCDB)
|
||||
qDebug() << Q_FUNC_INFO << fileName << lineNumber;
|
||||
}
|
||||
|
||||
void CdbDebugEngine::runToFunctionExec(const QString &functionName)
|
||||
{
|
||||
if (debugCDB)
|
||||
qDebug() << Q_FUNC_INFO << functionName;
|
||||
}
|
||||
|
||||
void CdbDebugEngine::jumpToLineExec(const QString &fileName, int lineNumber)
|
||||
{
|
||||
if (debugCDB)
|
||||
qDebug() << Q_FUNC_INFO << fileName << lineNumber;
|
||||
}
|
||||
|
||||
void CdbDebugEngine::assignValueInDebugger(const QString &expr, const QString &value)
|
||||
{
|
||||
if (debugCDB)
|
||||
qDebug() << Q_FUNC_INFO << expr << value;
|
||||
}
|
||||
|
||||
void CdbDebugEngine::executeDebuggerCommand(const QString &/*command*/)
|
||||
void CdbDebugEngine::executeDebuggerCommand(const QString &command)
|
||||
{
|
||||
if (debugCDB)
|
||||
qDebug() << Q_FUNC_INFO << command;
|
||||
}
|
||||
|
||||
void CdbDebugEngine::activateFrame(int frameIndex)
|
||||
{
|
||||
if (q->status() != DebuggerInferiorStopped)
|
||||
if (debugCDB)
|
||||
qDebug() << Q_FUNC_INFO << frameIndex;
|
||||
|
||||
if (m_d->m_debuggerManager->status() != DebuggerInferiorStopped)
|
||||
return;
|
||||
|
||||
StackHandler *stackHandler = qq->stackHandler();
|
||||
int oldIndex = stackHandler->currentIndex();
|
||||
StackHandler *stackHandler = m_d->m_debuggerManagerAccess->stackHandler();
|
||||
const int oldIndex = stackHandler->currentIndex();
|
||||
//qDebug() << "ACTIVATE FRAME: " << frameIndex << oldIndex
|
||||
// << stackHandler->currentIndex();
|
||||
|
||||
@@ -281,42 +352,63 @@ void CdbDebugEngine::activateFrame(int frameIndex)
|
||||
|
||||
const StackFrame &frame = stackHandler->currentFrame();
|
||||
|
||||
bool usable = !frame.file.isEmpty() && QFileInfo(frame.file).isReadable();
|
||||
const bool usable = !frame.file.isEmpty() && QFileInfo(frame.file).isReadable();
|
||||
if (usable)
|
||||
q->gotoLocation(frame.file, frame.line, true);
|
||||
m_d->m_debuggerManager->gotoLocation(frame.file, frame.line, true);
|
||||
else
|
||||
qDebug() << "FULL NAME NOT USABLE: " << frame.file;
|
||||
}
|
||||
|
||||
void CdbDebugEngine::selectThread(int index)
|
||||
{
|
||||
//reset location arrow
|
||||
q->resetLocation();
|
||||
if (debugCDB)
|
||||
qDebug() << Q_FUNC_INFO << index;
|
||||
|
||||
ThreadsHandler *threadsHandler = qq->threadsHandler();
|
||||
//reset location arrow
|
||||
m_d->m_debuggerManager->resetLocation();
|
||||
|
||||
ThreadsHandler *threadsHandler = m_d->m_debuggerManagerAccess->threadsHandler();
|
||||
threadsHandler->setCurrentThread(index);
|
||||
m_currentThreadId = index;
|
||||
updateStackTrace();
|
||||
m_d->m_currentThreadId = index;
|
||||
m_d->updateStackTrace();
|
||||
}
|
||||
|
||||
static inline QString breakPointExpression(const QString &fileName, const QString &lineNumber)
|
||||
{
|
||||
QString str;
|
||||
str += QLatin1Char('`');
|
||||
str += QDir::toNativeSeparators(fileName);
|
||||
str += QLatin1Char(':');
|
||||
str += lineNumber;
|
||||
str += QLatin1Char('`');
|
||||
return str;
|
||||
}
|
||||
|
||||
void CdbDebugEngine::attemptBreakpointSynchronization()
|
||||
{
|
||||
BreakHandler *handler = qq->breakHandler();
|
||||
//qDebug() << "attemptBreakpointSynchronization";
|
||||
if (debugCDB)
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
|
||||
if (!m_d->m_hDebuggeeProcess) {
|
||||
qWarning("attemptBreakpointSynchronization() called while debugger is not running");
|
||||
return;
|
||||
}
|
||||
|
||||
BreakHandler *handler = m_d->m_debuggerManagerAccess->breakHandler();
|
||||
for (int i=0; i < handler->size(); ++i) {
|
||||
BreakpointData* breakpoint = handler->at(i);
|
||||
if (breakpoint->pending) {
|
||||
const QString expr = breakPointExpression(breakpoint->fileName, breakpoint->lineNumber);
|
||||
IDebugBreakpoint2* pBP = 0;
|
||||
HRESULT hr = m_pDebugControl->AddBreakpoint2(DEBUG_BREAKPOINT_CODE, DEBUG_ANY_ID, &pBP);
|
||||
HRESULT hr = m_d->m_pDebugControl->AddBreakpoint2(DEBUG_BREAKPOINT_CODE, DEBUG_ANY_ID, &pBP);
|
||||
if (FAILED(hr) || !pBP) {
|
||||
qWarning("m_pDebugControl->AddBreakpoint2 failed");
|
||||
qWarning("m_pDebugControl->AddBreakpoint2 %s failed.", qPrintable(expr));
|
||||
continue;
|
||||
}
|
||||
|
||||
QString str = '`' + breakpoint->fileName + ':' + breakpoint->lineNumber + '`';
|
||||
hr = pBP->SetOffsetExpressionWide(str.utf16());
|
||||
hr = pBP->SetOffsetExpressionWide(expr.utf16());
|
||||
if (FAILED(hr)) {
|
||||
qWarning("SetOffsetExpressionWide failed");
|
||||
qWarning("SetOffsetExpressionWide %s failed", qPrintable(expr));
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -352,10 +444,14 @@ void CdbDebugEngine::reloadModules()
|
||||
|
||||
void CdbDebugEngine::loadSymbols(const QString &moduleName)
|
||||
{
|
||||
if (debugCDB)
|
||||
qDebug() << Q_FUNC_INFO << moduleName;
|
||||
}
|
||||
|
||||
void CdbDebugEngine::loadAllSymbols()
|
||||
{
|
||||
if (debugCDB)
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
}
|
||||
|
||||
void CdbDebugEngine::reloadRegisters()
|
||||
@@ -364,41 +460,52 @@ void CdbDebugEngine::reloadRegisters()
|
||||
|
||||
void CdbDebugEngine::timerEvent(QTimerEvent* te)
|
||||
{
|
||||
if (te->timerId() != m_watchTimer)
|
||||
if (te->timerId() != m_d->m_watchTimer)
|
||||
return;
|
||||
|
||||
if (debugCDB > 1)
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
|
||||
HRESULT hr;
|
||||
hr = m_pDebugControl->WaitForEvent(0, 1);
|
||||
hr = m_d->m_pDebugControl->WaitForEvent(0, 1);
|
||||
switch (hr) {
|
||||
case S_OK:
|
||||
//qDebug() << "WaitForEvent S_OK";
|
||||
if (debugCDB > 1)
|
||||
qDebug() << "WaitForEvent S_OK";
|
||||
|
||||
killWatchTimer();
|
||||
handleDebugEvent();
|
||||
m_d->handleDebugEvent();
|
||||
break;
|
||||
case S_FALSE:
|
||||
//qDebug() << "S_FALSE";
|
||||
if (debugCDB > 1)
|
||||
qDebug() << "WaitForEvent S_FALSE";
|
||||
break;
|
||||
case E_PENDING:
|
||||
qDebug() << "S_PENDING";
|
||||
if (debugCDB > 1)
|
||||
qDebug() << "WaitForEvent E_PENDING";
|
||||
break;
|
||||
case E_UNEXPECTED:
|
||||
if (debugCDB > 1)
|
||||
qDebug() << "WaitForEvent E_UNEXPECTED";
|
||||
killWatchTimer();
|
||||
break;
|
||||
case E_FAIL:
|
||||
qDebug() << "E_FAIL";
|
||||
if (debugCDB > 1)
|
||||
qDebug() << "WaitForEvent E_FAIL";
|
||||
break;
|
||||
//default:
|
||||
// qDebug() << "asser welljuh, schuddnt heppn";
|
||||
}
|
||||
}
|
||||
|
||||
void CdbDebugEngine::handleDebugEvent()
|
||||
void CdbDebugEnginePrivate::handleDebugEvent()
|
||||
{
|
||||
if (debugCDB)
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
|
||||
if (m_bIgnoreNextDebugEvent) {
|
||||
startWatchTimer();
|
||||
m_engine->startWatchTimer();
|
||||
m_bIgnoreNextDebugEvent = false;
|
||||
} else {
|
||||
qq->notifyInferiorStopped();
|
||||
m_debuggerManagerAccess->notifyInferiorStopped();
|
||||
updateThreadList();
|
||||
updateStackTrace();
|
||||
}
|
||||
@@ -415,9 +522,12 @@ void CdbDebugEngine::handleDebugEvent()
|
||||
//}
|
||||
}
|
||||
|
||||
void CdbDebugEngine::updateThreadList()
|
||||
void CdbDebugEnginePrivate::updateThreadList()
|
||||
{
|
||||
ThreadsHandler* th = qq->threadsHandler();
|
||||
if (debugCDB)
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
|
||||
ThreadsHandler* th = m_debuggerManagerAccess->threadsHandler();
|
||||
QList<ThreadData> threads;
|
||||
|
||||
HRESULT hr;
|
||||
@@ -436,11 +546,13 @@ void CdbDebugEngine::updateThreadList()
|
||||
th->setThreads(threads);
|
||||
}
|
||||
|
||||
void CdbDebugEngine::updateStackTrace()
|
||||
void CdbDebugEnginePrivate::updateStackTrace()
|
||||
{
|
||||
if (debugCDB)
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
|
||||
//qDebug() << "updateStackTrace()";
|
||||
HRESULT hr;
|
||||
hr = m_pDebugSystemObjects->SetCurrentThreadId(m_currentThreadId);
|
||||
HRESULT hr = m_pDebugSystemObjects->SetCurrentThreadId(m_currentThreadId);
|
||||
|
||||
//ULONG64 frameOffset, instructionOffset, stackOffset;
|
||||
//if (FAILED(m_pDebugRegisters->GetFrameOffset2(DEBUG_REGSRC_DEBUGGEE, &frameOffset)) ||
|
||||
@@ -466,7 +578,7 @@ void CdbDebugEngine::updateStackTrace()
|
||||
StackFrame frame;
|
||||
frame.line = 0;
|
||||
frame.level = i;
|
||||
frame.address = QString("0x%1").arg(frames[i].InstructionOffset, 0, 16);
|
||||
frame.address = QString::fromLatin1("0x%1").arg(frames[i].InstructionOffset, 0, 16);
|
||||
|
||||
m_pDebugSymbols->GetNameByOffsetWide(frames[i].InstructionOffset, wszBuf, MAX_PATH, 0, 0);
|
||||
frame.function = QString::fromUtf16(wszBuf);
|
||||
@@ -482,15 +594,15 @@ void CdbDebugEngine::updateStackTrace()
|
||||
stackFrames.append(frame);
|
||||
}
|
||||
|
||||
qq->stackHandler()->setFrames(stackFrames);
|
||||
m_debuggerManagerAccess->stackHandler()->setFrames(stackFrames);
|
||||
|
||||
// find the first usable frame and select it
|
||||
for (int i=0; i < stackFrames.count(); ++i) {
|
||||
const StackFrame &frame = stackFrames.at(i);
|
||||
bool usable = !frame.file.isEmpty() && QFileInfo(frame.file).isReadable();
|
||||
const bool usable = !frame.file.isEmpty() && QFileInfo(frame.file).isReadable();
|
||||
if (usable) {
|
||||
qq->stackHandler()->setCurrentIndex(i);
|
||||
q->gotoLocation(frame.file, frame.line, true);
|
||||
m_debuggerManagerAccess->stackHandler()->setCurrentIndex(i);
|
||||
m_debuggerManager->gotoLocation(frame.file, frame.line, true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -504,17 +616,33 @@ void CdbDebugEngine::updateStackTrace()
|
||||
//m_pDebugControl->OutputStackTrace(DEBUG_OUTCTL_THIS_CLIENT, frames, numFramesFilled, DEBUG_STACK_SOURCE_LINE);
|
||||
}
|
||||
|
||||
void CdbDebugEngine::handleDebugOutput(const char* szOutputString)
|
||||
void CdbDebugEnginePrivate::handleDebugOutput(const char* szOutputString)
|
||||
{
|
||||
qq->showApplicationOutput("app-dbgoutput", QString::fromLocal8Bit(szOutputString));
|
||||
m_debuggerManagerAccess->showApplicationOutput(QString::fromLocal8Bit(szOutputString));
|
||||
}
|
||||
|
||||
void CdbDebugEngine::handleBreakpointEvent(PDEBUG_BREAKPOINT pBP)
|
||||
void CdbDebugEnginePrivate::handleBreakpointEvent(PDEBUG_BREAKPOINT pBP)
|
||||
{
|
||||
qDebug() << "CdbDebugEngine::handleBreakpointEvent()";
|
||||
Q_UNUSED(pBP)
|
||||
if (debugCDB)
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
}
|
||||
|
||||
IDebuggerEngine *createWinEngine(DebuggerManager *parent)
|
||||
{
|
||||
return new CdbDebugEngine(parent);
|
||||
}
|
||||
|
||||
void CdbDebugEngine::setDebugDumpers(bool on)
|
||||
{
|
||||
Q_UNUSED(on)
|
||||
}
|
||||
|
||||
void CdbDebugEngine::setUseCustomDumpers(bool on)
|
||||
{
|
||||
Q_UNUSED(on)
|
||||
}
|
||||
|
||||
void CdbDebugEngine::reloadSourceFiles()
|
||||
{
|
||||
}
|
@@ -1,17 +1,48 @@
|
||||
/***************************************************************************
|
||||
**
|
||||
** This file is part of Qt Creator
|
||||
**
|
||||
** Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
|
||||
**
|
||||
** Contact: Qt Software Information (qt-info@nokia.com)
|
||||
**
|
||||
**
|
||||
** Non-Open Source Usage
|
||||
**
|
||||
** Licensees may use this file in accordance with the Qt Beta Version
|
||||
** License Agreement, Agreement version 2.2 provided with the Software or,
|
||||
** alternatively, in accordance with the terms contained in a written
|
||||
** agreement between you and Nokia.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
**
|
||||
** Alternatively, this file may be used under the terms of the GNU General
|
||||
** Public License versions 2.0 or 3.0 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL included in the packaging
|
||||
** of this file. Please review the following information to ensure GNU
|
||||
** General Public Licensing requirements will be met:
|
||||
**
|
||||
** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
|
||||
** http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** In addition, as a special exception, Nokia gives you certain additional
|
||||
** rights. These rights are described in the Nokia Qt GPL Exception
|
||||
** version 1.3, included in the file GPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef DEBUGGER_CDBENGINE_H
|
||||
#define DEBUGGER_CDBENGINE_H
|
||||
|
||||
#include "idebuggerengine.h"
|
||||
#include "cdbdebugeventcallback.h"
|
||||
#include "cdbdebugoutput.h"
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
namespace Debugger {
|
||||
namespace Internal {
|
||||
|
||||
class DebuggerManager;
|
||||
class IDebuggerManagerAccessForEngines;
|
||||
class CdbDebugEventCallback;
|
||||
class CdbDebugOutput;
|
||||
struct CdbDebugEnginePrivate;
|
||||
|
||||
class CdbDebugEngine : public IDebuggerEngine
|
||||
{
|
||||
@@ -33,7 +64,6 @@ public:
|
||||
virtual void nextIExec();
|
||||
|
||||
virtual void continueInferior();
|
||||
virtual void runInferior();
|
||||
virtual void interruptInferior();
|
||||
|
||||
virtual void runToLineExec(const QString &fileName, int lineNumber);
|
||||
@@ -58,37 +88,21 @@ public:
|
||||
|
||||
virtual void reloadRegisters();
|
||||
|
||||
virtual void setDebugDumpers(bool on);
|
||||
virtual void setUseCustomDumpers(bool on);
|
||||
|
||||
virtual void reloadSourceFiles();
|
||||
|
||||
protected:
|
||||
void timerEvent(QTimerEvent*);
|
||||
|
||||
private:
|
||||
void startWatchTimer();
|
||||
void killWatchTimer();
|
||||
bool isDebuggeeRunning() const { return m_watchTimer != -1; }
|
||||
void handleDebugEvent();
|
||||
void updateThreadList();
|
||||
void updateStackTrace();
|
||||
void handleDebugOutput(const char* szOutputString);
|
||||
void handleBreakpointEvent(PDEBUG_BREAKPOINT pBP);
|
||||
|
||||
private:
|
||||
HANDLE m_hDebuggeeProcess;
|
||||
HANDLE m_hDebuggeeThread;
|
||||
int m_currentThreadId;
|
||||
bool m_bIgnoreNextDebugEvent;
|
||||
|
||||
int m_watchTimer;
|
||||
IDebugClient5* m_pDebugClient;
|
||||
IDebugControl4* m_pDebugControl;
|
||||
IDebugSystemObjects4* m_pDebugSystemObjects;
|
||||
IDebugSymbols3* m_pDebugSymbols;
|
||||
IDebugRegisters2* m_pDebugRegisters;
|
||||
CdbDebugEventCallback m_debugEventCallBack;
|
||||
CdbDebugOutput m_debugOutputCallBack;
|
||||
|
||||
DebuggerManager *q;
|
||||
IDebuggerManagerAccessForEngines *qq;
|
||||
CdbDebugEnginePrivate *m_d;
|
||||
|
||||
friend struct CdbDebugEnginePrivate;
|
||||
friend class CdbDebugEventCallback;
|
||||
friend class CdbDebugOutput;
|
||||
};
|
82
src/plugins/debugger/cdb/cdbdebugengine_p.h
Normal file
82
src/plugins/debugger/cdb/cdbdebugengine_p.h
Normal file
@@ -0,0 +1,82 @@
|
||||
/***************************************************************************
|
||||
**
|
||||
** This file is part of Qt Creator
|
||||
**
|
||||
** Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
|
||||
**
|
||||
** Contact: Qt Software Information (qt-info@nokia.com)
|
||||
**
|
||||
**
|
||||
** Non-Open Source Usage
|
||||
**
|
||||
** Licensees may use this file in accordance with the Qt Beta Version
|
||||
** License Agreement, Agreement version 2.2 provided with the Software or,
|
||||
** alternatively, in accordance with the terms contained in a written
|
||||
** agreement between you and Nokia.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
**
|
||||
** Alternatively, this file may be used under the terms of the GNU General
|
||||
** Public License versions 2.0 or 3.0 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL included in the packaging
|
||||
** of this file. Please review the following information to ensure GNU
|
||||
** General Public Licensing requirements will be met:
|
||||
**
|
||||
** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
|
||||
** http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** In addition, as a special exception, Nokia gives you certain additional
|
||||
** rights. These rights are described in the Nokia Qt GPL Exception
|
||||
** version 1.3, included in the file GPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef DEBUGGER_CDBENGINEPRIVATE_H
|
||||
#define DEBUGGER_CDBENGINEPRIVATE_H
|
||||
|
||||
#include "cdbdebugeventcallback.h"
|
||||
#include "cdbdebugoutput.h"
|
||||
|
||||
namespace Debugger {
|
||||
namespace Internal {
|
||||
|
||||
class DebuggerManager;
|
||||
class IDebuggerManagerAccessForEngines;
|
||||
|
||||
struct CdbDebugEnginePrivate
|
||||
{
|
||||
explicit CdbDebugEnginePrivate(DebuggerManager *parent, CdbDebugEngine* engine);
|
||||
~CdbDebugEnginePrivate();
|
||||
|
||||
bool isDebuggeeRunning() const { return m_watchTimer != -1; }
|
||||
void handleDebugEvent();
|
||||
void updateThreadList();
|
||||
void updateStackTrace();
|
||||
void handleDebugOutput(const char* szOutputString);
|
||||
void handleBreakpointEvent(PDEBUG_BREAKPOINT pBP);
|
||||
|
||||
HANDLE m_hDebuggeeProcess;
|
||||
HANDLE m_hDebuggeeThread;
|
||||
int m_currentThreadId;
|
||||
bool m_bIgnoreNextDebugEvent;
|
||||
|
||||
int m_watchTimer;
|
||||
IDebugClient5* m_pDebugClient;
|
||||
IDebugControl4* m_pDebugControl;
|
||||
IDebugSystemObjects4* m_pDebugSystemObjects;
|
||||
IDebugSymbols3* m_pDebugSymbols;
|
||||
IDebugRegisters2* m_pDebugRegisters;
|
||||
CdbDebugEventCallback m_debugEventCallBack;
|
||||
CdbDebugOutput m_debugOutputCallBack;
|
||||
|
||||
CdbDebugEngine* m_engine;
|
||||
DebuggerManager *m_debuggerManager;
|
||||
IDebuggerManagerAccessForEngines *m_debuggerManagerAccess;
|
||||
};
|
||||
|
||||
enum { debugCDB = 0 };
|
||||
|
||||
} // namespace Internal
|
||||
} // namespace Debugger
|
||||
|
||||
#endif // DEBUGGER_CDBENGINEPRIVATE_H
|
288
src/plugins/debugger/cdb/cdbdebugeventcallback.cpp
Normal file
288
src/plugins/debugger/cdb/cdbdebugeventcallback.cpp
Normal file
@@ -0,0 +1,288 @@
|
||||
/***************************************************************************
|
||||
**
|
||||
** This file is part of Qt Creator
|
||||
**
|
||||
** Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
|
||||
**
|
||||
** Contact: Qt Software Information (qt-info@nokia.com)
|
||||
**
|
||||
**
|
||||
** Non-Open Source Usage
|
||||
**
|
||||
** Licensees may use this file in accordance with the Qt Beta Version
|
||||
** License Agreement, Agreement version 2.2 provided with the Software or,
|
||||
** alternatively, in accordance with the terms contained in a written
|
||||
** agreement between you and Nokia.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
**
|
||||
** Alternatively, this file may be used under the terms of the GNU General
|
||||
** Public License versions 2.0 or 3.0 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL included in the packaging
|
||||
** of this file. Please review the following information to ensure GNU
|
||||
** General Public Licensing requirements will be met:
|
||||
**
|
||||
** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
|
||||
** http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** In addition, as a special exception, Nokia gives you certain additional
|
||||
** rights. These rights are described in the Nokia Qt GPL Exception
|
||||
** version 1.3, included in the file GPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
***************************************************************************/
|
||||
|
||||
#include "cdbdebugeventcallback.h"
|
||||
#include "cdbdebugengine.h"
|
||||
#include "cdbdebugengine_p.h"
|
||||
#include "debuggermanager.h"
|
||||
|
||||
#include <QtCore/QDebug>
|
||||
|
||||
namespace Debugger {
|
||||
namespace Internal {
|
||||
|
||||
CdbDebugEventCallback::CdbDebugEventCallback(CdbDebugEngine* dbg) :
|
||||
m_pEngine(dbg)
|
||||
{
|
||||
}
|
||||
|
||||
STDMETHODIMP CdbDebugEventCallback::QueryInterface(
|
||||
THIS_
|
||||
IN REFIID InterfaceId,
|
||||
OUT PVOID* Interface)
|
||||
{
|
||||
*Interface = NULL;
|
||||
|
||||
if (IsEqualIID(InterfaceId, __uuidof(IUnknown)) ||
|
||||
IsEqualIID(InterfaceId, __uuidof(IDebugOutputCallbacks))) {
|
||||
*Interface = (IDebugOutputCallbacks *)this;
|
||||
AddRef();
|
||||
return S_OK;
|
||||
} else {
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
}
|
||||
|
||||
STDMETHODIMP_(ULONG) CdbDebugEventCallback::AddRef(THIS)
|
||||
{
|
||||
// This class is designed to be static so
|
||||
// there's no true refcount.
|
||||
return 1;
|
||||
}
|
||||
|
||||
STDMETHODIMP_(ULONG) CdbDebugEventCallback::Release(THIS)
|
||||
{
|
||||
// This class is designed to be static so
|
||||
// there's no true refcount.
|
||||
return 0;
|
||||
}
|
||||
|
||||
STDMETHODIMP CdbDebugEventCallback::GetInterestMask(THIS_ __out PULONG mask)
|
||||
{
|
||||
*mask = DEBUG_EVENT_CREATE_PROCESS | DEBUG_EVENT_EXIT_PROCESS
|
||||
//| DEBUG_EVENT_CREATE_THREAD | DEBUG_EVENT_EXIT_THREAD
|
||||
| DEBUG_EVENT_BREAKPOINT
|
||||
| DEBUG_EVENT_EXCEPTION
|
||||
;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CdbDebugEventCallback::Breakpoint(THIS_ __in PDEBUG_BREAKPOINT Bp)
|
||||
{
|
||||
if (debugCDB)
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
m_pEngine->m_d->handleBreakpointEvent(Bp);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CdbDebugEventCallback::Exception(
|
||||
THIS_
|
||||
__in PEXCEPTION_RECORD64 Exception,
|
||||
__in ULONG FirstChance
|
||||
)
|
||||
{
|
||||
Q_UNUSED(Exception)
|
||||
if (debugCDB)
|
||||
qDebug() << Q_FUNC_INFO << FirstChance;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CdbDebugEventCallback::CreateThread(
|
||||
THIS_
|
||||
__in ULONG64 Handle,
|
||||
__in ULONG64 DataOffset,
|
||||
__in ULONG64 StartOffset
|
||||
)
|
||||
{
|
||||
Q_UNUSED(Handle)
|
||||
Q_UNUSED(DataOffset)
|
||||
Q_UNUSED(StartOffset)
|
||||
|
||||
if (debugCDB)
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
//Debugger::ThreadInfo ti;
|
||||
//ti.handle = Handle;
|
||||
//ti.dataOffset = DataOffset;
|
||||
//ti.startOffset = StartOffset;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CdbDebugEventCallback::ExitThread(
|
||||
THIS_
|
||||
__in ULONG ExitCode
|
||||
)
|
||||
{
|
||||
if (debugCDB)
|
||||
qDebug() << Q_FUNC_INFO << ExitCode;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CdbDebugEventCallback::CreateProcess(
|
||||
THIS_
|
||||
__in ULONG64 ImageFileHandle,
|
||||
__in ULONG64 Handle,
|
||||
__in ULONG64 BaseOffset,
|
||||
__in ULONG ModuleSize,
|
||||
__in_opt PCSTR ModuleName,
|
||||
__in_opt PCSTR ImageName,
|
||||
__in ULONG CheckSum,
|
||||
__in ULONG TimeDateStamp,
|
||||
__in ULONG64 InitialThreadHandle,
|
||||
__in ULONG64 ThreadDataOffset,
|
||||
__in ULONG64 StartOffset
|
||||
)
|
||||
{
|
||||
Q_UNUSED(ImageFileHandle)
|
||||
Q_UNUSED(BaseOffset)
|
||||
Q_UNUSED(ModuleSize)
|
||||
Q_UNUSED(ModuleName)
|
||||
Q_UNUSED(ImageName)
|
||||
Q_UNUSED(CheckSum)
|
||||
Q_UNUSED(TimeDateStamp)
|
||||
Q_UNUSED(ThreadDataOffset)
|
||||
Q_UNUSED(StartOffset)
|
||||
if (debugCDB)
|
||||
qDebug() << Q_FUNC_INFO << ModuleName;
|
||||
|
||||
m_pEngine->m_d->m_hDebuggeeProcess = (HANDLE)Handle;
|
||||
m_pEngine->m_d->m_hDebuggeeThread = (HANDLE)InitialThreadHandle;
|
||||
m_pEngine->m_d->m_debuggerManagerAccess->notifyInferiorRunning();
|
||||
|
||||
ULONG currentThreadId;
|
||||
if (SUCCEEDED(m_pEngine->m_d->m_pDebugSystemObjects->GetThreadIdByHandle(InitialThreadHandle, ¤tThreadId)))
|
||||
m_pEngine->m_d->m_currentThreadId = currentThreadId;
|
||||
else
|
||||
m_pEngine->m_d->m_currentThreadId = 0;
|
||||
|
||||
m_pEngine->attemptBreakpointSynchronization();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CdbDebugEventCallback::ExitProcess(
|
||||
THIS_
|
||||
__in ULONG ExitCode
|
||||
)
|
||||
{
|
||||
if (debugCDB)
|
||||
qDebug() << Q_FUNC_INFO << ExitCode;
|
||||
|
||||
m_pEngine->m_d->m_hDebuggeeProcess = 0;
|
||||
m_pEngine->m_d->m_hDebuggeeThread = 0;
|
||||
m_pEngine->m_d->m_debuggerManagerAccess->notifyInferiorExited();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CdbDebugEventCallback::LoadModule(
|
||||
THIS_
|
||||
__in ULONG64 ImageFileHandle,
|
||||
__in ULONG64 BaseOffset,
|
||||
__in ULONG ModuleSize,
|
||||
__in_opt PCSTR ModuleName,
|
||||
__in_opt PCSTR ImageName,
|
||||
__in ULONG CheckSum,
|
||||
__in ULONG TimeDateStamp
|
||||
)
|
||||
{
|
||||
Q_UNUSED(ImageFileHandle)
|
||||
Q_UNUSED(BaseOffset)
|
||||
Q_UNUSED(ModuleSize)
|
||||
Q_UNUSED(ModuleName)
|
||||
Q_UNUSED(ImageName)
|
||||
Q_UNUSED(CheckSum)
|
||||
Q_UNUSED(TimeDateStamp)
|
||||
if (debugCDB)
|
||||
qDebug() << Q_FUNC_INFO << ModuleName;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CdbDebugEventCallback::UnloadModule(
|
||||
THIS_
|
||||
__in_opt PCSTR ImageBaseName,
|
||||
__in ULONG64 BaseOffset
|
||||
)
|
||||
{
|
||||
Q_UNUSED(ImageBaseName)
|
||||
Q_UNUSED(BaseOffset)
|
||||
if (debugCDB)
|
||||
qDebug() << Q_FUNC_INFO << ImageBaseName;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CdbDebugEventCallback::SystemError(
|
||||
THIS_
|
||||
__in ULONG Error,
|
||||
__in ULONG Level
|
||||
)
|
||||
{
|
||||
if (debugCDB)
|
||||
qDebug() << Q_FUNC_INFO << Error << Level;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CdbDebugEventCallback::SessionStatus(
|
||||
THIS_
|
||||
__in ULONG Status
|
||||
)
|
||||
{
|
||||
Q_UNUSED(Status)
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CdbDebugEventCallback::ChangeDebuggeeState(
|
||||
THIS_
|
||||
__in ULONG Flags,
|
||||
__in ULONG64 Argument
|
||||
)
|
||||
{
|
||||
Q_UNUSED(Flags)
|
||||
Q_UNUSED(Argument)
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CdbDebugEventCallback::ChangeEngineState(
|
||||
THIS_
|
||||
__in ULONG Flags,
|
||||
__in ULONG64 Argument
|
||||
)
|
||||
{
|
||||
Q_UNUSED(Flags)
|
||||
Q_UNUSED(Argument)
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CdbDebugEventCallback::ChangeSymbolState(
|
||||
THIS_
|
||||
__in ULONG Flags,
|
||||
__in ULONG64 Argument
|
||||
)
|
||||
{
|
||||
Q_UNUSED(Flags)
|
||||
Q_UNUSED(Argument)
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
} // namespace Internal
|
||||
} // namespace Debugger
|
@@ -1,8 +1,41 @@
|
||||
/***************************************************************************
|
||||
**
|
||||
** This file is part of Qt Creator
|
||||
**
|
||||
** Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
|
||||
**
|
||||
** Contact: Qt Software Information (qt-info@nokia.com)
|
||||
**
|
||||
**
|
||||
** Non-Open Source Usage
|
||||
**
|
||||
** Licensees may use this file in accordance with the Qt Beta Version
|
||||
** License Agreement, Agreement version 2.2 provided with the Software or,
|
||||
** alternatively, in accordance with the terms contained in a written
|
||||
** agreement between you and Nokia.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
**
|
||||
** Alternatively, this file may be used under the terms of the GNU General
|
||||
** Public License versions 2.0 or 3.0 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL included in the packaging
|
||||
** of this file. Please review the following information to ensure GNU
|
||||
** General Public Licensing requirements will be met:
|
||||
**
|
||||
** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
|
||||
** http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** In addition, as a special exception, Nokia gives you certain additional
|
||||
** rights. These rights are described in the Nokia Qt GPL Exception
|
||||
** version 1.3, included in the file GPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef DEBUGGER_CDBDEBUGEVENTCALLBACK_H
|
||||
#define DEBUGGER_CDBDEBUGEVENTCALLBACK_H
|
||||
|
||||
#include <windows.h>
|
||||
#include <dbgeng.h>
|
||||
#include <inc/dbgeng.h>
|
||||
|
||||
namespace Debugger {
|
||||
namespace Internal {
|
||||
@@ -12,9 +45,7 @@ class CdbDebugEngine;
|
||||
class CdbDebugEventCallback : public IDebugEventCallbacks
|
||||
{
|
||||
public:
|
||||
CdbDebugEventCallback(CdbDebugEngine* dbg)
|
||||
: m_pEngine(dbg)
|
||||
{}
|
||||
explicit CdbDebugEventCallback(CdbDebugEngine* dbg);
|
||||
|
||||
// IUnknown.
|
||||
STDMETHOD(QueryInterface)(
|
95
src/plugins/debugger/cdb/cdbdebugoutput.cpp
Normal file
95
src/plugins/debugger/cdb/cdbdebugoutput.cpp
Normal file
@@ -0,0 +1,95 @@
|
||||
/***************************************************************************
|
||||
**
|
||||
** This file is part of Qt Creator
|
||||
**
|
||||
** Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
|
||||
**
|
||||
** Contact: Qt Software Information (qt-info@nokia.com)
|
||||
**
|
||||
**
|
||||
** Non-Open Source Usage
|
||||
**
|
||||
** Licensees may use this file in accordance with the Qt Beta Version
|
||||
** License Agreement, Agreement version 2.2 provided with the Software or,
|
||||
** alternatively, in accordance with the terms contained in a written
|
||||
** agreement between you and Nokia.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
**
|
||||
** Alternatively, this file may be used under the terms of the GNU General
|
||||
** Public License versions 2.0 or 3.0 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL included in the packaging
|
||||
** of this file. Please review the following information to ensure GNU
|
||||
** General Public Licensing requirements will be met:
|
||||
**
|
||||
** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
|
||||
** http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** In addition, as a special exception, Nokia gives you certain additional
|
||||
** rights. These rights are described in the Nokia Qt GPL Exception
|
||||
** version 1.3, included in the file GPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
***************************************************************************/
|
||||
|
||||
|
||||
#include "cdbdebugoutput.h"
|
||||
#include "cdbdebugengine.h"
|
||||
#include "cdbdebugengine_p.h"
|
||||
|
||||
#include <windows.h>
|
||||
#include <inc/dbgeng.h>
|
||||
|
||||
namespace Debugger {
|
||||
namespace Internal {
|
||||
|
||||
CdbDebugOutput::CdbDebugOutput(CdbDebugEngine* engine) :
|
||||
m_pEngine(engine)
|
||||
{
|
||||
}
|
||||
|
||||
STDMETHODIMP CdbDebugOutput::QueryInterface(
|
||||
THIS_
|
||||
IN REFIID InterfaceId,
|
||||
OUT PVOID* Interface
|
||||
)
|
||||
{
|
||||
*Interface = NULL;
|
||||
|
||||
if (IsEqualIID(InterfaceId, __uuidof(IUnknown)) ||
|
||||
IsEqualIID(InterfaceId, __uuidof(IDebugOutputCallbacks)))
|
||||
{
|
||||
*Interface = (IDebugOutputCallbacks *)this;
|
||||
AddRef();
|
||||
return S_OK;
|
||||
} else {
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
}
|
||||
|
||||
STDMETHODIMP_(ULONG) CdbDebugOutput::AddRef(THIS)
|
||||
{
|
||||
// This class is designed to be static so
|
||||
// there's no true refcount.
|
||||
return 1;
|
||||
}
|
||||
|
||||
STDMETHODIMP_(ULONG) CdbDebugOutput::Release(THIS)
|
||||
{
|
||||
// This class is designed to be static so
|
||||
// there's no true refcount.
|
||||
return 0;
|
||||
}
|
||||
|
||||
STDMETHODIMP CdbDebugOutput::Output(
|
||||
THIS_
|
||||
IN ULONG mask,
|
||||
IN PCSTR text
|
||||
)
|
||||
{
|
||||
UNREFERENCED_PARAMETER(mask);
|
||||
m_pEngine->m_d->handleDebugOutput(text);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
} // namespace Internal
|
||||
} // namespace Debugger
|
77
src/plugins/debugger/cdb/cdbdebugoutput.h
Normal file
77
src/plugins/debugger/cdb/cdbdebugoutput.h
Normal file
@@ -0,0 +1,77 @@
|
||||
/***************************************************************************
|
||||
**
|
||||
** This file is part of Qt Creator
|
||||
**
|
||||
** Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
|
||||
**
|
||||
** Contact: Qt Software Information (qt-info@nokia.com)
|
||||
**
|
||||
**
|
||||
** Non-Open Source Usage
|
||||
**
|
||||
** Licensees may use this file in accordance with the Qt Beta Version
|
||||
** License Agreement, Agreement version 2.2 provided with the Software or,
|
||||
** alternatively, in accordance with the terms contained in a written
|
||||
** agreement between you and Nokia.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
**
|
||||
** Alternatively, this file may be used under the terms of the GNU General
|
||||
** Public License versions 2.0 or 3.0 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL included in the packaging
|
||||
** of this file. Please review the following information to ensure GNU
|
||||
** General Public Licensing requirements will be met:
|
||||
**
|
||||
** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
|
||||
** http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** In addition, as a special exception, Nokia gives you certain additional
|
||||
** rights. These rights are described in the Nokia Qt GPL Exception
|
||||
** version 1.3, included in the file GPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef DEBUGGER_CDBOUTPUT_H
|
||||
#define DEBUGGER_CDBOUTPUT_H
|
||||
|
||||
#include <windows.h>
|
||||
#include <inc/dbgeng.h>
|
||||
|
||||
namespace Debugger {
|
||||
namespace Internal {
|
||||
|
||||
class CdbDebugEngine;
|
||||
|
||||
class CdbDebugOutput : public IDebugOutputCallbacks
|
||||
{
|
||||
public:
|
||||
explicit CdbDebugOutput(CdbDebugEngine* engine);
|
||||
|
||||
// IUnknown.
|
||||
STDMETHOD(QueryInterface)(
|
||||
THIS_
|
||||
IN REFIID InterfaceId,
|
||||
OUT PVOID* Interface
|
||||
);
|
||||
STDMETHOD_(ULONG, AddRef)(
|
||||
THIS
|
||||
);
|
||||
STDMETHOD_(ULONG, Release)(
|
||||
THIS
|
||||
);
|
||||
|
||||
// IDebugOutputCallbacks.
|
||||
STDMETHOD(Output)(
|
||||
THIS_
|
||||
IN ULONG mask,
|
||||
IN PCSTR text
|
||||
);
|
||||
|
||||
private:
|
||||
CdbDebugEngine* m_pEngine;
|
||||
};
|
||||
|
||||
} // namespace Internal
|
||||
} // namespace Debugger
|
||||
|
||||
#endif // DEBUGGER_CDBOUTPUT_H
|
@@ -1,203 +0,0 @@
|
||||
#include "cdbdebugeventcallback.h"
|
||||
#include "cdbcdebugengine.h"
|
||||
#include "debuggermanager.h"
|
||||
|
||||
#include <QtCore/QDebug>
|
||||
|
||||
namespace Debugger {
|
||||
namespace Internal {
|
||||
|
||||
STDMETHODIMP MSVCDebugEventCallback::QueryInterface(
|
||||
THIS_
|
||||
IN REFIID InterfaceId,
|
||||
OUT PVOID* Interface)
|
||||
{
|
||||
*Interface = NULL;
|
||||
|
||||
if (IsEqualIID(InterfaceId, __uuidof(IUnknown)) ||
|
||||
IsEqualIID(InterfaceId, __uuidof(IDebugOutputCallbacks)))
|
||||
{
|
||||
*Interface = (IDebugOutputCallbacks *)this;
|
||||
AddRef();
|
||||
return S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
}
|
||||
|
||||
STDMETHODIMP_(ULONG) MSVCDebugEventCallback::AddRef(THIS)
|
||||
{
|
||||
// This class is designed to be static so
|
||||
// there's no true refcount.
|
||||
return 1;
|
||||
}
|
||||
|
||||
STDMETHODIMP_(ULONG) MSVCDebugEventCallback::Release(THIS)
|
||||
{
|
||||
// This class is designed to be static so
|
||||
// there's no true refcount.
|
||||
return 0;
|
||||
}
|
||||
|
||||
STDMETHODIMP MSVCDebugEventCallback::GetInterestMask(THIS_ __out PULONG mask)
|
||||
{
|
||||
*mask = DEBUG_EVENT_CREATE_PROCESS | DEBUG_EVENT_EXIT_PROCESS
|
||||
//| DEBUG_EVENT_CREATE_THREAD | DEBUG_EVENT_EXIT_THREAD
|
||||
| DEBUG_EVENT_BREAKPOINT
|
||||
| DEBUG_EVENT_EXCEPTION
|
||||
;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP MSVCDebugEventCallback::Breakpoint(THIS_ __in PDEBUG_BREAKPOINT Bp)
|
||||
{
|
||||
qDebug() << "MSVCDebugEventCallback::Breakpoint";
|
||||
m_pEngine->handleBreakpointEvent(Bp);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP MSVCDebugEventCallback::Exception(
|
||||
THIS_
|
||||
__in PEXCEPTION_RECORD64 Exception,
|
||||
__in ULONG FirstChance
|
||||
)
|
||||
{
|
||||
qDebug() << "MSVCDebugEventCallback::Exception";
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP MSVCDebugEventCallback::CreateThread(
|
||||
THIS_
|
||||
__in ULONG64 Handle,
|
||||
__in ULONG64 DataOffset,
|
||||
__in ULONG64 StartOffset
|
||||
)
|
||||
{
|
||||
//Debugger::ThreadInfo ti;
|
||||
//ti.handle = Handle;
|
||||
//ti.dataOffset = DataOffset;
|
||||
//ti.startOffset = StartOffset;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP MSVCDebugEventCallback::ExitThread(
|
||||
THIS_
|
||||
__in ULONG ExitCode
|
||||
)
|
||||
{
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP MSVCDebugEventCallback::CreateProcess(
|
||||
THIS_
|
||||
__in ULONG64 ImageFileHandle,
|
||||
__in ULONG64 Handle,
|
||||
__in ULONG64 BaseOffset,
|
||||
__in ULONG ModuleSize,
|
||||
__in_opt PCSTR ModuleName,
|
||||
__in_opt PCSTR ImageName,
|
||||
__in ULONG CheckSum,
|
||||
__in ULONG TimeDateStamp,
|
||||
__in ULONG64 InitialThreadHandle,
|
||||
__in ULONG64 ThreadDataOffset,
|
||||
__in ULONG64 StartOffset
|
||||
)
|
||||
{
|
||||
m_pEngine->m_hDebuggeeProcess = (HANDLE)Handle;
|
||||
m_pEngine->m_hDebuggeeThread = (HANDLE)InitialThreadHandle;
|
||||
//m_pEngine->qq->notifyStartupFinished();
|
||||
m_pEngine->qq->notifyInferiorRunning();
|
||||
|
||||
ULONG currentThreadId;
|
||||
if (SUCCEEDED(m_pEngine->m_pDebugSystemObjects->GetThreadIdByHandle(InitialThreadHandle, ¤tThreadId)))
|
||||
m_pEngine->m_currentThreadId = currentThreadId;
|
||||
else
|
||||
m_pEngine->m_currentThreadId = 0;
|
||||
|
||||
m_pEngine->attemptBreakpointSynchronization();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP MSVCDebugEventCallback::ExitProcess(
|
||||
THIS_
|
||||
__in ULONG ExitCode
|
||||
)
|
||||
{
|
||||
UNREFERENCED_PARAMETER(ExitCode);
|
||||
m_pEngine->m_hDebuggeeProcess = 0;
|
||||
m_pEngine->m_hDebuggeeThread = 0;
|
||||
m_pEngine->qq->notifyInferiorExited();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP MSVCDebugEventCallback::LoadModule(
|
||||
THIS_
|
||||
__in ULONG64 ImageFileHandle,
|
||||
__in ULONG64 BaseOffset,
|
||||
__in ULONG ModuleSize,
|
||||
__in_opt PCSTR ModuleName,
|
||||
__in_opt PCSTR ImageName,
|
||||
__in ULONG CheckSum,
|
||||
__in ULONG TimeDateStamp
|
||||
)
|
||||
{
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP MSVCDebugEventCallback::UnloadModule(
|
||||
THIS_
|
||||
__in_opt PCSTR ImageBaseName,
|
||||
__in ULONG64 BaseOffset
|
||||
)
|
||||
{
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP MSVCDebugEventCallback::SystemError(
|
||||
THIS_
|
||||
__in ULONG Error,
|
||||
__in ULONG Level
|
||||
)
|
||||
{
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP MSVCDebugEventCallback::SessionStatus(
|
||||
THIS_
|
||||
__in ULONG Status
|
||||
)
|
||||
{
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP MSVCDebugEventCallback::ChangeDebuggeeState(
|
||||
THIS_
|
||||
__in ULONG Flags,
|
||||
__in ULONG64 Argument
|
||||
)
|
||||
{
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP MSVCDebugEventCallback::ChangeEngineState(
|
||||
THIS_
|
||||
__in ULONG Flags,
|
||||
__in ULONG64 Argument
|
||||
)
|
||||
{
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP MSVCDebugEventCallback::ChangeSymbolState(
|
||||
THIS_
|
||||
__in ULONG Flags,
|
||||
__in ULONG64 Argument
|
||||
)
|
||||
{
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
} // namespace Internal
|
||||
} // namespace Debugger
|
@@ -1,57 +0,0 @@
|
||||
#include <windows.h>
|
||||
#include <dbgeng.h>
|
||||
|
||||
#include "cdbdebugoutput.h"
|
||||
#include "cdbdebugengine.h"
|
||||
|
||||
namespace Debugger {
|
||||
namespace Internal {
|
||||
|
||||
STDMETHODIMP MSVCDebugOutput::QueryInterface(
|
||||
THIS_
|
||||
IN REFIID InterfaceId,
|
||||
OUT PVOID* Interface
|
||||
)
|
||||
{
|
||||
*Interface = NULL;
|
||||
|
||||
if (IsEqualIID(InterfaceId, __uuidof(IUnknown)) ||
|
||||
IsEqualIID(InterfaceId, __uuidof(IDebugOutputCallbacks)))
|
||||
{
|
||||
*Interface = (IDebugOutputCallbacks *)this;
|
||||
AddRef();
|
||||
return S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
}
|
||||
|
||||
STDMETHODIMP_(ULONG) MSVCDebugOutput::AddRef(THIS)
|
||||
{
|
||||
// This class is designed to be static so
|
||||
// there's no true refcount.
|
||||
return 1;
|
||||
}
|
||||
|
||||
STDMETHODIMP_(ULONG) MSVCDebugOutput::Release(THIS)
|
||||
{
|
||||
// This class is designed to be static so
|
||||
// there's no true refcount.
|
||||
return 0;
|
||||
}
|
||||
|
||||
STDMETHODIMP MSVCDebugOutput::Output(
|
||||
THIS_
|
||||
IN ULONG mask,
|
||||
IN PCSTR text
|
||||
)
|
||||
{
|
||||
UNREFERENCED_PARAMETER(mask);
|
||||
m_pEngine->handleDebugOutput(text);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
} // namespace Internal
|
||||
} // namespace Debugger
|
@@ -1,43 +0,0 @@
|
||||
#ifndef DEBUGGER_CDBOUTPUT_H
|
||||
#define DEBUGGER_CDBOUTPUT_H
|
||||
|
||||
namespace Debugger {
|
||||
namespace Internal {
|
||||
|
||||
class CdbDebugEngine;
|
||||
|
||||
class CdbDebugOutput : public IDebugOutputCallbacks
|
||||
{
|
||||
public:
|
||||
CdbDebugOutput(CdbDebugEngine* engine)
|
||||
: m_pEngine(engine)
|
||||
{}
|
||||
|
||||
// IUnknown.
|
||||
STDMETHOD(QueryInterface)(
|
||||
THIS_
|
||||
IN REFIID InterfaceId,
|
||||
OUT PVOID* Interface
|
||||
);
|
||||
STDMETHOD_(ULONG, AddRef)(
|
||||
THIS
|
||||
);
|
||||
STDMETHOD_(ULONG, Release)(
|
||||
THIS
|
||||
);
|
||||
|
||||
// IDebugOutputCallbacks.
|
||||
STDMETHOD(Output)(
|
||||
THIS_
|
||||
IN ULONG mask,
|
||||
IN PCSTR text
|
||||
);
|
||||
|
||||
private:
|
||||
CdbDebugEngine* m_pEngine;
|
||||
};
|
||||
|
||||
} // namespace Internal
|
||||
} // namespace Debugger
|
||||
|
||||
#endif // DEBUGGER_CDBOUTPUT_H
|
@@ -85,19 +85,4 @@ HEADERS += $$PWD/modeltest.h
|
||||
DEFINES += USE_MODEL_TEST=1
|
||||
}
|
||||
|
||||
false {
|
||||
|
||||
HEADERS += \
|
||||
cdbdebugengine.h \
|
||||
cdbdebugeventcallback.h \
|
||||
cdbdebugoutput.h
|
||||
|
||||
SOURCES += \
|
||||
cdbdebugengine.cpp \
|
||||
cdbdebugeventcallback.cpp \
|
||||
cdbdebugoutput.cpp
|
||||
|
||||
LIBS += dbgeng.lib
|
||||
|
||||
}
|
||||
|
||||
CONFIG(cdbdebugger):include(cdb\cdb.pri)
|
||||
|
@@ -132,7 +132,12 @@ static IDebuggerEngine *winEngine = 0;
|
||||
static IDebuggerEngine *scriptEngine = 0;
|
||||
|
||||
extern IDebuggerEngine *createGdbEngine(DebuggerManager *parent);
|
||||
extern IDebuggerEngine *createWinEngine(DebuggerManager *) { return 0; }
|
||||
extern IDebuggerEngine *createWinEngine(DebuggerManager *)
|
||||
#ifdef CDB_ENABLED
|
||||
;
|
||||
#else
|
||||
{ return 0; }
|
||||
#endif
|
||||
extern IDebuggerEngine *createScriptEngine(DebuggerManager *parent);
|
||||
|
||||
DebuggerManager::DebuggerManager()
|
||||
|
@@ -106,11 +106,11 @@ enum DebuggerStatus
|
||||
DebuggerInferiorStopped, // Debuggee stopped
|
||||
};
|
||||
|
||||
|
||||
class IDebuggerEngine;
|
||||
class GdbEngine;
|
||||
class ScriptEngine;
|
||||
class WinEngine;
|
||||
class CdbDebugEngine;
|
||||
struct CdbDebugEnginePrivate;
|
||||
|
||||
// The construct below is not nice but enforces a bit of order. The
|
||||
// DebuggerManager interfaces a lots of thing: The DebuggerPlugin,
|
||||
@@ -131,10 +131,12 @@ public:
|
||||
|
||||
private:
|
||||
// This is the part of the interface that's exclusively seen by the
|
||||
// debugger engines.
|
||||
// debugger engines
|
||||
friend class GdbEngine;
|
||||
friend class CdbDebugEngine;
|
||||
friend class CdbDebugEventCallback;
|
||||
friend class ScriptEngine;
|
||||
friend class WinEngine;
|
||||
friend struct CdbDebugEnginePrivate;
|
||||
|
||||
// called from the engines after successful startup
|
||||
virtual void notifyInferiorStopRequested() = 0;
|
||||
|
@@ -234,15 +234,6 @@ static bool isLeavableFunction(const QString &funcName, const QString &fileName)
|
||||
return false;
|
||||
}
|
||||
|
||||
static QString startSymbolName()
|
||||
{
|
||||
#ifdef Q_OS_WIN
|
||||
return "WinMainCRTStartup";
|
||||
#else
|
||||
return "_start";
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
@@ -1555,9 +1546,7 @@ bool GdbEngine::startDebugger()
|
||||
qDebug() << "ExeFile: " << q->m_executable;
|
||||
#endif
|
||||
|
||||
q->showStatusMessage(tr("Starting Debugger"));
|
||||
emit gdbInputAvailable(QString(), q->settings()->m_gdbCmd + ' ' + gdbArgs.join(" "));
|
||||
|
||||
q->showStatusMessage(tr("Starting Debugger: ") + q->settings()->m_gdbCmd + ' ' + gdbArgs.join(" "));
|
||||
m_gdbProc.start(q->settings()->m_gdbCmd, gdbArgs);
|
||||
m_gdbProc.waitForStarted();
|
||||
|
||||
@@ -1655,7 +1644,7 @@ bool GdbEngine::startDebugger()
|
||||
if (!q->m_processArgs.isEmpty())
|
||||
sendCommand("-exec-arguments " + q->m_processArgs.join(" "));
|
||||
sendCommand("set auto-solib-add off");
|
||||
sendCommand("x/2i " + startSymbolName(), GdbStart);
|
||||
sendCommand("info target", GdbStart);
|
||||
}
|
||||
|
||||
// set all to "pending"
|
||||
@@ -1678,14 +1667,14 @@ void GdbEngine::continueInferior()
|
||||
void GdbEngine::handleStart(const GdbResultRecord &response)
|
||||
{
|
||||
if (response.resultClass == GdbResultDone) {
|
||||
// stdout:&"x/2i _start\n"
|
||||
// stdout:~"0x404540 <_start>:\txor %ebp,%ebp\n"
|
||||
// stdout:~"0x404542 <_start+2>:\tmov %rdx,%r9\n"
|
||||
// [some leading stdout here]
|
||||
// stdout:&" Entry point: 0x80831f0 0x08048134 - 0x08048147 is .interp\n"
|
||||
// [some trailing stdout here]
|
||||
QString msg = response.data.findChild("consolestreamoutput").data();
|
||||
QRegExp needle("0x([0-9a-f]+) <" + startSymbolName() + "\\+.*>:");
|
||||
QRegExp needle("\\bEntry point: (0x[0-9a-f]+)\\b");
|
||||
if (needle.indexIn(msg) != -1) {
|
||||
//debugMessage("STREAM: " + msg + " " + needle.cap(1));
|
||||
sendCommand("tbreak *0x" + needle.cap(1));
|
||||
sendCommand("tbreak *" + needle.cap(1));
|
||||
m_waitingForFirstBreakpointToBeHit = true;
|
||||
qq->notifyInferiorRunningRequested();
|
||||
sendCommand("-exec-run");
|
||||
@@ -1693,7 +1682,7 @@ void GdbEngine::handleStart(const GdbResultRecord &response)
|
||||
debugMessage("PARSING START ADDRESS FAILED: " + msg);
|
||||
}
|
||||
} else if (response.resultClass == GdbResultError) {
|
||||
debugMessage("PARSING START ADDRESS FAILED: " + response.toString());
|
||||
debugMessage("FETCHING START ADDRESS FAILED: " + response.toString());
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -39,6 +39,8 @@
|
||||
#include <QtNetwork/QLocalSocket>
|
||||
#include <QtCore/QCoreApplication>
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#else
|
||||
|
||||
#include <QtCore/QFile>
|
||||
@@ -80,7 +82,9 @@ bool OutputCollector::listen()
|
||||
return m_server->isListening();
|
||||
m_server = new QLocalServer(this);
|
||||
connect(m_server, SIGNAL(newConnection()), SLOT(newConnectionAvailable()));
|
||||
return m_server->listen(QString::fromLatin1("creator-%1").arg(QCoreApplication::applicationPid())); // XXX how to make that secure?
|
||||
return m_server->listen(QString::fromLatin1("creator-%1-%2")
|
||||
.arg(QCoreApplication::applicationPid())
|
||||
.arg(rand()));
|
||||
#else
|
||||
if (!m_serverPath.isEmpty())
|
||||
return true;
|
||||
@@ -156,7 +160,7 @@ void OutputCollector::newConnectionAvailable()
|
||||
if (m_socket)
|
||||
return;
|
||||
m_socket = m_server->nextPendingConnection();
|
||||
connect(m_socket, SIGNAL(bytesAvailable()), SLOT(bytesAvailable()));
|
||||
connect(m_socket, SIGNAL(readyRead()), SLOT(bytesAvailable()));
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@@ -111,7 +111,7 @@ QWidget *ApplicationRunConfigurationRunner::configurationWidget(QSharedPointer<R
|
||||
// ApplicationRunControl
|
||||
|
||||
ApplicationRunControl::ApplicationRunControl(QSharedPointer<ApplicationRunConfiguration> runConfiguration)
|
||||
: RunControl(runConfiguration), m_applicationLauncher()
|
||||
: RunControl(runConfiguration)
|
||||
{
|
||||
connect(&m_applicationLauncher, SIGNAL(applicationError(QString)),
|
||||
this, SLOT(slotError(QString)));
|
||||
|
@@ -84,6 +84,9 @@ const char * const C_OPERATOR = "Operator";
|
||||
const char * const C_PREPROCESSOR = "Preprocessor";
|
||||
const char * const C_LABEL = "Label";
|
||||
const char * const C_COMMENT = "Comment";
|
||||
const char * const C_DOXYGEN_COMMENT = "Doxygen.Comment";
|
||||
const char * const C_DOXYGEN_TAG = "Doxygen.Tag";
|
||||
|
||||
const char * const C_DISABLED_CODE = "DisabledCode";
|
||||
|
||||
const char * const C_ADDED_LINE = "AddedLine";
|
||||
|
@@ -84,6 +84,8 @@ TextEditorSettings::TextEditorSettings(QObject *parent)
|
||||
formatDescriptions.push_back(FormatDescription(QLatin1String(C_PREPROCESSOR), tr("Preprocessor"), Qt::darkBlue));
|
||||
formatDescriptions.push_back(FormatDescription(QLatin1String(C_LABEL), tr("Label"), Qt::darkRed));
|
||||
formatDescriptions.push_back(FormatDescription(QLatin1String(C_COMMENT), tr("Comment"), Qt::darkGreen));
|
||||
formatDescriptions.push_back(FormatDescription(QLatin1String(C_DOXYGEN_COMMENT), tr("Doxygen Comment"), Qt::darkBlue));
|
||||
formatDescriptions.push_back(FormatDescription(QLatin1String(C_DOXYGEN_TAG), tr("Doxygen Tag"), Qt::blue));
|
||||
formatDescriptions.push_back(FormatDescription(QLatin1String(C_DISABLED_CODE), tr("Disabled Code"), Qt::gray));
|
||||
|
||||
// Diff categories
|
||||
|
@@ -60,7 +60,7 @@ CPLUSPLUS_BEGIN_NAMESPACE
|
||||
|
||||
Lexer::Lexer(TranslationUnit *unit)
|
||||
: _translationUnit(unit),
|
||||
_state(Lexer::DefaultState),
|
||||
_state(State_Default),
|
||||
_flags(0),
|
||||
_currentLine(1)
|
||||
{
|
||||
@@ -71,7 +71,7 @@ Lexer::Lexer(TranslationUnit *unit)
|
||||
|
||||
Lexer::Lexer(const char *firstChar, const char *lastChar)
|
||||
: _translationUnit(0),
|
||||
_state(Lexer::DefaultState),
|
||||
_state(State_Default),
|
||||
_flags(0),
|
||||
_currentLine(1)
|
||||
{
|
||||
@@ -196,7 +196,9 @@ void Lexer::scan_helper(Token *tok)
|
||||
_tokenStart = _currentChar;
|
||||
tok->offset = _currentChar - _firstChar;
|
||||
|
||||
if (_state == MultiLineCommentState) {
|
||||
if (_state == State_MultiLineComment || _state == State_MultiLineDoxyComment) {
|
||||
const int originalState = _state;
|
||||
|
||||
if (! _yychar) {
|
||||
tok->kind = T_EOF_SYMBOL;
|
||||
return;
|
||||
@@ -209,7 +211,7 @@ void Lexer::scan_helper(Token *tok)
|
||||
yyinp();
|
||||
if (_yychar == '/') {
|
||||
yyinp();
|
||||
_state = DefaultState;
|
||||
_state = State_Default;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -218,7 +220,10 @@ void Lexer::scan_helper(Token *tok)
|
||||
if (! _scanCommentTokens)
|
||||
goto _Lagain;
|
||||
|
||||
else if (originalState == State_MultiLineComment)
|
||||
tok->kind = T_COMMENT;
|
||||
else
|
||||
tok->kind = T_DOXY_COMMENT;
|
||||
return; // done
|
||||
}
|
||||
|
||||
@@ -402,14 +407,30 @@ void Lexer::scan_helper(Token *tok)
|
||||
|
||||
case '/':
|
||||
if (_yychar == '/') {
|
||||
do {
|
||||
yyinp();
|
||||
} while (_yychar && _yychar != '\n');
|
||||
|
||||
bool doxy = false;
|
||||
|
||||
if (_yychar == '/' || _yychar == '!') {
|
||||
yyinp();
|
||||
|
||||
if (_yychar != '\n' && std::isspace(_yychar))
|
||||
doxy = true;
|
||||
}
|
||||
|
||||
while (_yychar && _yychar != '\n')
|
||||
yyinp();
|
||||
|
||||
if (! _scanCommentTokens)
|
||||
goto _Lagain;
|
||||
tok->kind = T_COMMENT;
|
||||
|
||||
tok->kind = doxy ? T_DOXY_COMMENT : T_COMMENT;
|
||||
|
||||
} else if (_yychar == '*') {
|
||||
yyinp();
|
||||
|
||||
const bool doxy = _yychar == '*' || _yychar == '!';
|
||||
|
||||
while (_yychar) {
|
||||
if (_yychar != '*') {
|
||||
yyinp();
|
||||
@@ -423,11 +444,13 @@ void Lexer::scan_helper(Token *tok)
|
||||
if (_yychar)
|
||||
yyinp();
|
||||
else
|
||||
_state = MultiLineCommentState;
|
||||
_state = doxy ? State_MultiLineDoxyComment : State_MultiLineComment;
|
||||
|
||||
if (! _scanCommentTokens)
|
||||
goto _Lagain;
|
||||
tok->kind = T_COMMENT;
|
||||
|
||||
tok->kind = doxy ? T_DOXY_COMMENT : T_COMMENT;
|
||||
|
||||
} else if (_yychar == '=') {
|
||||
yyinp();
|
||||
tok->kind = T_SLASH_EQUAL;
|
||||
|
@@ -66,8 +66,9 @@ class CPLUSPLUS_EXPORT Lexer
|
||||
|
||||
public:
|
||||
enum State {
|
||||
DefaultState,
|
||||
MultiLineCommentState
|
||||
State_Default,
|
||||
State_MultiLineComment,
|
||||
State_MultiLineDoxyComment
|
||||
};
|
||||
|
||||
Lexer(TranslationUnit *unit);
|
||||
|
@@ -58,7 +58,7 @@ CPLUSPLUS_BEGIN_NAMESPACE
|
||||
static const char *token_names[] = {
|
||||
(""), ("<error>"),
|
||||
|
||||
("<comment>"),
|
||||
("<comment>"), ("<doxy comment>"),
|
||||
|
||||
("<identifier>"), ("<int literal>"), ("<float literal>"), ("<char literal>"),
|
||||
("<wide char literal>"), ("<string literal>"), ("<wide char literal>"),
|
||||
|
@@ -64,6 +64,7 @@ enum Kind {
|
||||
T_ERROR,
|
||||
|
||||
T_COMMENT,
|
||||
T_DOXY_COMMENT,
|
||||
T_IDENTIFIER,
|
||||
|
||||
T_FIRST_LITERAL,
|
||||
@@ -297,6 +298,9 @@ public:
|
||||
inline bool isKeyword() const
|
||||
{ return kind >= T_FIRST_KEYWORD && kind < T_FIRST_QT_KEYWORD; }
|
||||
|
||||
inline bool isComment() const
|
||||
{ return kind == T_COMMENT || kind == T_DOXY_COMMENT; }
|
||||
|
||||
inline bool isObjCAtKeyword() const
|
||||
{ return kind >= T_FIRST_OBJC_AT_KEYWORD && kind < T_LAST_OBJC_AT_KEYWORD; }
|
||||
|
||||
|
@@ -5,4 +5,3 @@ echo "Generating $t"
|
||||
${CPP-gcc} -xc++ -E -include $me/conf.c++ $* > $t
|
||||
echo "Parsing $t"
|
||||
$me/cplusplus0 $t
|
||||
|
||||
|
@@ -6,3 +6,6 @@
|
||||
#define restrict
|
||||
#define __restrict
|
||||
#define __weak
|
||||
#define __complex__
|
||||
#define __imag__
|
||||
#define __real__
|
||||
|
Reference in New Issue
Block a user