8 definitionToSourceLocationMap
= dict()
10 # exclude some stuff, mostly because they are some kind of definition of external file formats
11 excludedSourceFiles
= set([
12 "include/svx/msdffdef.hxx",
13 "sw/source/filter/ww8/fields.hxx",
14 "sw/source/filter/inc/wwstyles.hxx",
21 "SwVarFormat", "RES_FIELDS", "SwFillOrder", "SwIoDetect", "SwDocumentSettingsPropertyHandles",
22 "SalGenericDataType", "SwDateSubFormat", "XclFutureRecType", "ds_status", "MediaCommand",
26 # clang does not always use exactly the same numbers in the type-parameter vars it generates
27 # so I need to substitute them to ensure we can match correctly.
28 normalizeTypeParamsRegex
= re
.compile(r
"type-parameter-\d+-\d+")
29 def normalizeTypeParams( line
):
30 return normalizeTypeParamsRegex
.sub("type-parameter-?-?", line
)
32 # The parsing here is designed to avoid grabbing stuff which is mixed in from gbuild.
33 # I have not yet found a way of suppressing the gbuild output.
34 with io
.open("loplugin.unusedenumvalues.log", "rb", buffering
=1024*1024) as txt
:
36 tokens
= line
.strip().split("\t")
37 if tokens
[0] == "definition:":
38 funcInfo
= (normalizeTypeParams(tokens
[1]), tokens
[2])
39 definitionSet
.add(funcInfo
)
40 definitionToSourceLocationMap
[funcInfo
] = tokens
[3]
41 elif tokens
[0] == "touch:":
42 callInfo
= (normalizeTypeParams(tokens
[1]), tokens
[2])
43 touchSet
.add(callInfo
)
45 # Invert the definitionToSourceLocationMap
46 # If we see more than one method at the same sourceLocation, it's being autogenerated as part of a template
47 # and we should just ignore
48 sourceLocationToDefinitionMap
= {}
49 for k
, v
in definitionToSourceLocationMap
.iteritems():
50 sourceLocationToDefinitionMap
[v
] = sourceLocationToDefinitionMap
.get(v
, [])
51 sourceLocationToDefinitionMap
[v
].append(k
)
52 for k
, definitions
in sourceLocationToDefinitionMap
.iteritems():
53 if len(definitions
) > 1:
55 definitionSet
.remove(d
)
58 for d
in definitionSet
:
59 clazz
= d
[0] + " " + d
[1]
62 srcLoc
= definitionToSourceLocationMap
[d
]
63 srcLocWithoutLineNo
= srcLoc
.split(":")[0]
64 # ignore external source code
65 if (srcLoc
.startswith("external/")):
68 if (srcLoc
.startswith("workdir/")):
70 # ignore our stable/URE/UNO api
71 if (srcLoc
.startswith("include/com/")
72 or srcLoc
.startswith("include/cppu/")
73 or srcLoc
.startswith("include/cppuhelper/")
74 or srcLoc
.startswith("include/osl/")
75 or srcLoc
.startswith("include/rtl/")
76 or srcLoc
.startswith("include/sal/")
77 or srcLoc
.startswith("include/salhelper/")
78 or srcLoc
.startswith("include/systools/")
79 or srcLoc
.startswith("include/typelib/")
80 or srcLoc
.startswith("include/uno/")):
82 if srcLocWithoutLineNo
in excludedSourceFiles
or d
[0] in excludedTypes
:
84 # structure definitions
85 if srcLoc
.startswith("lotuswordpro/"):
88 # used in templates to find the last member of an enum
89 if d
[1] == "LAST" or d
[1].endswith("_END"):
91 # used to aid in alignment of enum values
92 if d
[1].endswith("FORCE_EQUAL_SIZE"):
95 untouchedSet
.add((clazz
, srcLoc
))
97 # sort the results using a "natural order" so sequences like [item1,item2,item10] sort nicely
98 def natural_sort_key(s
, _nsre
=re
.compile('([0-9]+)')):
99 return [int(text
) if text
.isdigit() else text
.lower()
100 for text
in re
.split(_nsre
, s
)]
102 # sort results by name and line number
103 tmp1list
= sorted(untouchedSet
, key
=lambda v
: natural_sort_key(v
[1]))
105 # print out the results
106 with
open("loplugin.unusedenumvalues.report-untouched", "wt") as f
:
108 f
.write( t
[1] + "\n" )
109 f
.write( " " + t
[0] + "\n" )