Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Tobias Hunger
qt-creator
Commits
f3f95c69
Commit
f3f95c69
authored
Nov 29, 2010
by
Friedemann Kleint
Browse files
Debugger[new CDB]: Add support for more core types.
Structures with accessible members.
parent
847e5dfb
Changes
3
Hide whitespace changes
Inline
Side-by-side
src/libs/qtcreatorcdbext/stringutils.h
View file @
f3f95c69
...
...
@@ -63,6 +63,15 @@ std::string toString(const Streamable s)
return
str
.
str
();
}
// Format numbers, etc, as a wstring.
template
<
class
Streamable
>
std
::
wstring
toWString
(
const
Streamable
s
)
{
std
::
wostringstream
str
;
str
<<
s
;
return
str
.
str
();
}
bool
endsWith
(
const
std
::
string
&
haystack
,
const
char
*
needle
);
// Read an integer from a string as '10' or '0xA'
...
...
src/libs/qtcreatorcdbext/symbolgroup.cpp
View file @
f3f95c69
...
...
@@ -413,11 +413,17 @@ SymbolGroupNode *SymbolGroupNode::create(SymbolGroup *sg, const std::string &nam
}
// Fix some oddities in CDB values
static
inline
bool
isHexDigit
(
wchar_t
c
)
{
return
(
c
>=
L'0'
&&
c
<=
L'9'
)
||
(
c
>=
L'a'
&&
c
<=
L'f'
)
||
(
c
>=
L'A'
&&
c
<=
L'F'
);
}
static
void
fixValue
(
const
std
::
string
&
type
,
std
::
wstring
*
value
)
{
// Pointers: fix '0x00000000`00000AD
class
bla' ... to "0xAD
", but leave
// '
const
char *' values as is.
if
(
!
type
.
empty
()
&&
type
.
at
(
type
.
size
()
-
1
)
==
L'*'
&&
value
->
compare
(
0
,
2
,
L"0x"
)
==
0
)
{
// Pointers
/Unsigned integers
: fix '0x00000000`00000AD bla' ... to "0xAD
bla"
const
bool
isHexNumber
=
value
->
size
()
>
3
&&
value
->
compare
(
0
,
2
,
L"0x"
)
==
0
&&
isHexDigit
(
value
->
at
(
2
));
if
(
isHexNumber
)
{
// Remove dumb 64bit separator
if
(
value
->
size
()
>
10
&&
value
->
at
(
10
)
==
L'`'
)
value
->
erase
(
10
,
1
);
...
...
@@ -425,11 +431,16 @@ static void fixValue(const std::string &type, std::wstring *value)
// No on-null digits: plain null ptr.
if
(
firstNonNullDigit
==
std
::
string
::
npos
||
value
->
at
(
firstNonNullDigit
)
==
' '
)
{
*
value
=
L"0x0"
;
return
;
}
}
else
{
// Strip
if
(
firstNonNullDigit
>
2
)
value
->
erase
(
2
,
firstNonNullDigit
-
2
);
if
(
firstNonNullDigit
>
2
)
value
->
erase
(
2
,
firstNonNullDigit
-
2
);
}
}
// Pointers: fix '0x00000000`00000AD class bla' ... to "0xAD", but leave
// 'const char *' values as is ('0x00000000`00000AD "hallo").
if
(
!
type
.
empty
()
&&
type
.
at
(
type
.
size
()
-
1
)
==
L'*'
)
{
// Strip ' Class bla"
std
::
wstring
::
size_type
classPos
=
value
->
find
(
L" struct"
,
2
);
if
(
classPos
==
std
::
string
::
npos
)
...
...
@@ -438,6 +449,18 @@ static void fixValue(const std::string &type, std::wstring *value)
value
->
erase
(
classPos
,
value
->
size
()
-
classPos
);
return
;
}
// unsigned hex ints that are not pointers: Convert to decimal as not to confuse watch model:
if
(
isHexNumber
)
{
ULONG64
uv
;
std
::
wistringstream
str
(
*
value
);
str
>>
std
::
hex
>>
uv
;
if
(
!
str
.
fail
())
{
*
value
=
toWString
(
uv
);
return
;
}
}
// Integers: fix '0n10' -> '10'
if
(
value
->
size
()
>=
3
&&
value
->
compare
(
0
,
2
,
L"0n"
)
==
0
&&
(
isdigit
(
value
->
at
(
2
))
||
value
->
at
(
2
)
==
L'-'
))
{
...
...
src/libs/qtcreatorcdbext/symbolgroupvalue.cpp
View file @
f3f95c69
...
...
@@ -31,6 +31,8 @@
#include
"symbolgroup.h"
#include
"stringutils.h"
#include
<iomanip>
SymbolGroupValue
::
SymbolGroupValue
(
SymbolGroupNode
*
node
,
const
SymbolGroupValueContext
&
ctx
)
:
m_node
(
node
),
m_context
(
ctx
)
...
...
@@ -106,7 +108,12 @@ int SymbolGroupValue::intValue(int defaultValue) const
{
if
(
isValid
())
{
int
rc
=
0
;
if
(
integerFromString
(
wStringToString
(
value
()),
&
rc
))
// Is this an enumeration "EnumValue (0n12)", -> convert to integer
std
::
wstring
v
=
value
();
const
std
::
wstring
::
size_type
enPos
=
v
.
find
(
L"(0n"
);
if
(
enPos
!=
std
::
wstring
::
npos
&&
v
.
at
(
v
.
size
()
-
1
)
==
L')'
)
v
=
v
.
substr
(
enPos
+
3
,
v
.
size
()
-
4
);
if
(
integerFromString
(
wStringToString
(
v
),
&
rc
))
return
rc
;
}
return
defaultValue
;
...
...
@@ -164,6 +171,75 @@ std::string SymbolGroupValue::error() const
return
m_errorMessage
;
}
// -------------------- Simple dumping helpers
// Courtesy of qdatetime.cpp
static
inline
void
getDateFromJulianDay
(
unsigned
julianDay
,
int
*
year
,
int
*
month
,
int
*
day
)
{
int
y
,
m
,
d
;
if
(
julianDay
>=
2299161
)
{
typedef
unsigned
long
long
qulonglong
;
// Gregorian calendar starting from October 15, 1582
// This algorithm is from Henry F. Fliegel and Thomas C. Van Flandern
qulonglong
ell
,
n
,
i
,
j
;
ell
=
qulonglong
(
julianDay
)
+
68569
;
n
=
(
4
*
ell
)
/
146097
;
ell
=
ell
-
(
146097
*
n
+
3
)
/
4
;
i
=
(
4000
*
(
ell
+
1
))
/
1461001
;
ell
=
ell
-
(
1461
*
i
)
/
4
+
31
;
j
=
(
80
*
ell
)
/
2447
;
d
=
int
(
ell
-
(
2447
*
j
)
/
80
);
ell
=
j
/
11
;
m
=
int
(
j
+
2
-
(
12
*
ell
));
y
=
int
(
100
*
(
n
-
49
)
+
i
+
ell
);
}
else
{
// Julian calendar until October 4, 1582
// Algorithm from Frequently Asked Questions about Calendars by Claus Toendering
julianDay
+=
32082
;
int
dd
=
(
4
*
julianDay
+
3
)
/
1461
;
int
ee
=
julianDay
-
(
1461
*
dd
)
/
4
;
int
mm
=
((
5
*
ee
)
+
2
)
/
153
;
d
=
ee
-
(
153
*
mm
+
2
)
/
5
+
1
;
m
=
mm
+
3
-
12
*
(
mm
/
10
);
y
=
dd
-
4800
+
(
mm
/
10
);
if
(
y
<=
0
)
--
y
;
}
if
(
year
)
*
year
=
y
;
if
(
month
)
*
month
=
m
;
if
(
day
)
*
day
=
d
;
}
// Convert and format Julian Date as used in QDate
static
inline
void
formatJulianDate
(
std
::
wostringstream
&
str
,
unsigned
julianDate
)
{
int
y
,
m
,
d
;
getDateFromJulianDay
(
julianDate
,
&
y
,
&
m
,
&
d
);
str
<<
d
<<
'.'
<<
m
<<
'.'
<<
y
;
}
// Format time in milliseconds as "hh:dd:ss:mmm"
static
inline
void
formatMilliSeconds
(
std
::
wostringstream
&
str
,
int
milliSecs
)
{
const
int
hourFactor
=
1000
*
3600
;
const
int
hours
=
milliSecs
/
hourFactor
;
milliSecs
=
milliSecs
%
hourFactor
;
const
int
minFactor
=
1000
*
60
;
const
int
minutes
=
milliSecs
/
minFactor
;
milliSecs
=
milliSecs
%
minFactor
;
const
int
secs
=
milliSecs
/
1000
;
milliSecs
=
milliSecs
%
1000
;
str
.
fill
(
'0'
);
str
<<
std
::
setw
(
2
)
<<
hours
<<
':'
<<
std
::
setw
(
2
)
<<
minutes
<<
':'
<<
std
::
setw
(
2
)
<<
secs
<<
'.'
<<
std
::
setw
(
3
)
<<
milliSecs
;
}
static
const
char
stdStringTypeC
[]
=
"class std::basic_string<char,std::char_traits<char>,std::allocator<char> >"
;
static
const
char
stdWStringTypeC
[]
=
"class std::basic_string<unsigned short,std::char_traits<unsigned short>,std::allocator<unsigned short> >"
;
...
...
@@ -185,6 +261,123 @@ static unsigned dumpQString(const std::string &type, const SymbolGroupValue &v,
return
SymbolGroupNode
::
DumperFailed
;
}
// Dump QColor
static
unsigned
dumpQColor
(
const
std
::
string
&
type
,
const
SymbolGroupValue
&
v
,
std
::
wstring
*
s
)
{
if
(
!
endsWith
(
type
,
"QColor"
))
// namespaced Qt?
return
SymbolGroupNode
::
DumperNotApplicable
;
const
SymbolGroupValue
specV
=
v
[
"cspec"
];
if
(
!
specV
)
return
SymbolGroupNode
::
DumperFailed
;
const
int
spec
=
specV
.
intValue
();
if
(
spec
==
0
)
{
*
s
=
L"<Invalid color>"
;
return
SymbolGroupNode
::
DumperOk
;
}
if
(
spec
<
1
||
spec
>
4
)
return
SymbolGroupNode
::
DumperFailed
;
const
SymbolGroupValue
arrayV
=
v
[
"ct"
][
"array"
];
if
(
!
arrayV
)
return
SymbolGroupNode
::
DumperFailed
;
const
int
a0
=
arrayV
[
"0"
].
intValue
();
const
int
a1
=
arrayV
[
"1"
].
intValue
();
const
int
a2
=
arrayV
[
"2"
].
intValue
();
const
int
a3
=
arrayV
[
"3"
].
intValue
();
const
int
a4
=
arrayV
[
"4"
].
intValue
();
if
(
a0
<
0
||
a1
<
0
||
a2
<
0
||
a3
<
0
||
a4
<
0
)
return
SymbolGroupNode
::
DumperFailed
;
std
::
wostringstream
str
;
switch
(
spec
)
{
case
1
:
// Rgb
str
<<
L"RGB alpha="
<<
(
a0
/
0x101
)
<<
L", red="
<<
(
a1
/
0x101
)
<<
L", green="
<<
(
a2
/
0x101
)
<<
", blue="
<<
(
a3
/
0x101
);
break
;
case
2
:
// Hsv
str
<<
L"HSV alpha="
<<
(
a0
/
0x101
)
<<
L", hue="
<<
(
a1
/
100
)
<<
L", sat="
<<
(
a2
/
0x101
)
<<
", value="
<<
(
a3
/
0x101
);
break
;
case
3
:
// Cmyk
str
<<
L"CMYK alpha="
<<
(
a0
/
0x101
)
<<
L", cyan="
<<
(
a1
/
100
)
<<
L", magenta="
<<
(
a2
/
0x101
)
<<
", yellow="
<<
(
a3
/
0x101
)
<<
", black="
<<
(
a4
/
0x101
);
break
;
case
4
:
// Hsl
str
<<
L"HSL alpha="
<<
(
a0
/
0x101
)
<<
L", hue="
<<
(
a1
/
100
)
<<
L", sat="
<<
(
a2
/
0x101
)
<<
", lightness="
<<
(
a3
/
0x101
);
break
;
}
*
s
=
str
.
str
();
return
SymbolGroupNode
::
DumperOk
;
}
// Dump Qt's core types
static
unsigned
dumpQtCoreTypes
(
const
std
::
string
&
type
,
const
SymbolGroupValue
&
v
,
std
::
wstring
*
s
)
{
if
(
endsWith
(
type
,
"QAtomicInt"
))
{
// namespaced Qt?
if
(
SymbolGroupValue
iValue
=
v
[
unsigned
(
0
)][
"_q_value"
])
{
*
s
=
iValue
.
value
();
return
SymbolGroupNode
::
DumperOk
;
}
return
SymbolGroupNode
::
DumperFailed
;
}
if
(
endsWith
(
type
,
"QChar"
))
{
if
(
SymbolGroupValue
cValue
=
v
[
"ucs"
])
{
const
int
utf16
=
cValue
.
intValue
();
if
(
utf16
>=
0
)
{
// Print code = character,
// exclude control characters and Pair indicator
std
::
wostringstream
str
;
str
<<
utf16
;
if
(
utf16
>=
32
&&
(
utf16
<
0xD800
||
utf16
>
0xDBFF
))
str
<<
" '"
<<
wchar_t
(
utf16
)
<<
'\''
;
*
s
=
str
.
str
();
}
return
SymbolGroupNode
::
DumperOk
;
}
return
SymbolGroupNode
::
DumperFailed
;
}
if
(
type
.
find
(
"QFlags"
)
!=
std
::
wstring
::
npos
)
{
if
(
SymbolGroupValue
iV
=
v
[
"i"
])
{
const
int
i
=
iV
.
intValue
();
if
(
i
>=
0
)
{
*
s
=
toWString
(
i
);
return
SymbolGroupNode
::
DumperOk
;
}
}
return
SymbolGroupNode
::
DumperFailed
;
}
if
(
endsWith
(
type
,
"QDate"
))
{
if
(
SymbolGroupValue
julianDayV
=
v
[
"jd"
])
{
const
int
julianDay
=
julianDayV
.
intValue
();
if
(
julianDay
>
0
)
{
std
::
wostringstream
str
;
formatJulianDate
(
str
,
julianDay
);
*
s
=
str
.
str
();
return
SymbolGroupNode
::
DumperOk
;
}
return
SymbolGroupNode
::
DumperFailed
;
}
}
if
(
endsWith
(
type
,
"QTime"
))
{
if
(
SymbolGroupValue
milliSecsV
=
v
[
"mds"
])
{
int
milliSecs
=
milliSecsV
.
intValue
();
if
(
milliSecs
>=
0
)
{
std
::
wostringstream
str
;
formatMilliSeconds
(
str
,
milliSecs
);
*
s
=
str
.
str
();
return
SymbolGroupNode
::
DumperOk
;
}
return
SymbolGroupNode
::
DumperFailed
;
}
}
return
SymbolGroupNode
::
DumperNotApplicable
;
}
// Dump a QByteArray
static
unsigned
dumpQByteArray
(
const
std
::
string
&
type
,
const
SymbolGroupValue
&
v
,
std
::
wstring
*
s
)
{
...
...
@@ -289,12 +482,18 @@ unsigned dumpSimpleType(SymbolGroupNode *n, const SymbolGroupValueContext &ctx,
if
(
rc
!=
SymbolGroupNode
::
DumperNotApplicable
)
return
rc
;
rc
=
dumpQByteArray
(
type
,
v
,
s
);
if
(
rc
!=
SymbolGroupNode
::
DumperNotApplicable
)
return
rc
;
rc
=
dumpQtCoreTypes
(
type
,
v
,
s
);
if
(
rc
!=
SymbolGroupNode
::
DumperNotApplicable
)
return
rc
;
rc
=
dumpStdString
(
type
,
v
,
s
);
if
(
rc
!=
SymbolGroupNode
::
DumperNotApplicable
)
return
rc
;
rc
=
dumpQtGeometryTypes
(
type
,
v
,
s
);
if
(
rc
!=
SymbolGroupNode
::
DumperNotApplicable
)
return
rc
;
rc
=
dumpQColor
(
type
,
v
,
s
);
if
(
rc
!=
SymbolGroupNode
::
DumperNotApplicable
)
return
rc
;
return
rc
;
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment