1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
|
(:
This query opens a C++ GCC-XML output file, and outputs a report describing the use
of globals variables.
Run it, by invoking, for instance:
patternist reportGlobal.xq fileToOpen=globals.gccxml > globals.html
"fileToOpen=globals.gccxml" binds the string "globals.gccxml" to the variable
"fileToOpen." It identifies the GCC-XML file to open.
:)
declare variable $inDoc as document-node() := doc($fileToOpen);
(: Determines whether the type by ID @p typeId is a complex type such as QString. :)
declare function local:isComplexType($typeID as xs:string) as xs:boolean
{
(: We're being a bit crude here and only checks whether it's a class. We
actually should check whether it has non-synthesized,
constructors, I believe. :)
exists($inDoc/GCC_XML/Class[@id = $typeID])
or
(: We also want const-qualified variables. :)
exists($inDoc/GCC_XML/Class[@id = $inDoc/GCC_XML/CvQualifiedType[@id = $typeID]/@type])
};
declare function local:isPrimitive($typeId as xs:string) as xs:boolean
{
exists($inDoc/GCC_XML/FundamentalType[@id = $typeId])
};
(: Returns a string for human consumption that describes
the location of @p block. :)
declare function local:location($block as element()) as xs:string
{
concat($inDoc/GCC_XML/File[@id = $block/@file]/@name, " at line ", $block/@line)
};
declare function local:report() as element()+
{
let $complexVariables as element(Variable)* := $inDoc/GCC_XML/Variable[local:isComplexType(@type)]
return if(exists($complexVariables)) (: Is the length larger than zero? :)
then (<p xmlns="http://www.w3.org/1999/xhtml/">The following global, complex variables were found:</p>,
<ol xmlns="http://www.w3.org/1999/xhtml/">
{
(: For each Variable in $complexVariables... :)
$complexVariables/<li><span class="variableName">{string(@name)}</span> in {local:location(.)}</li>
}
</ol>)
else <p xmlns="http://www.w3.org/1999/xhtml/">No global variables that are of complex types were found.</p>
,
(: List primitive, mutable types. :)
let $primitiveVariables as element(Variable)+ := $inDoc/GCC_XML/Variable[local:isPrimitive(@type)]
return if(exists($primitiveVariables))
then (<p xmlns="http://www.w3.org/1999/xhtml/">The following mutable primitives were found:</p>,
<ol xmlns="http://www.w3.org/1999/xhtml/">
{
(: For each Variable in $complexVariables... :)
$primitiveVariables/<li><span class="variableName">{string(@name)}</span> in {local:location(.)}</li>
}
</ol>)
else <p xmlns="http://www.w3.org/1999/xhtml/">No global variables that are of complex types were found.</p>
};
<html xmlns="http://www.w3.org/1999/xhtml/" xml:lang="en" lang="en">
<head>
<title>Global variables report for {$fileToOpen}</title>
</head>
<style type="text/css">
.details
{{
text-align: center;
font-size: 80%;
color: gray
}}
.variableName
{{
font-family: courier
}}
</style>
<body>
{
(: We don't want simple types that are const, but all other types.
One could frown upon const integers and say enums should be used instead, but
let's be gentle. :)
local:report()
}
<p class="details">This report was generated on</p>
</body>
</html>
|