cURL: follow redirects
[LibreOffice.git] / compilerplugins / clang / unusedenumvalues.py
blob76c9fe619eb3fa9f4f4c2279ddc7cc506a648100
1 #!/usr/bin/python
3 import sys
4 import re
5 import io
7 definitionSet = set()
8 definitionToSourceLocationMap = dict()
9 touchSet = set()
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",
15 "sw/inc/toxe.hxx",
16 "sw/inc/poolfmt.hxx",
17 "sw/inc/hintids.hxx",
18 "vcl/inc/unx/XIM.h",
20 excludedTypes = set([
21 "SwVarFormat", "RES_FIELDS", "SwFillOrder", "SwIoDetect", "SwDocumentSettingsPropertyHandles",
22 "SalGenericDataType", "SwDateSubFormat", "XclFutureRecType", "ds_status", "MediaCommand",
23 "EmfPlusHatchStyle"
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:
35 for line in 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:
54 for d in definitions:
55 definitionSet.remove(d)
57 untouchedSet = set()
58 for d in definitionSet:
59 clazz = d[0] + " " + d[1]
60 if d in touchSet:
61 continue
62 srcLoc = definitionToSourceLocationMap[d]
63 srcLocWithoutLineNo = srcLoc.split(":")[0]
64 # ignore external source code
65 if (srcLoc.startswith("external/")):
66 continue
67 # ignore build folder
68 if (srcLoc.startswith("workdir/")):
69 continue
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/")):
81 continue
82 if srcLocWithoutLineNo in excludedSourceFiles or d[0] in excludedTypes:
83 continue
84 # structure definitions
85 if srcLoc.startswith("lotuswordpro/"):
86 continue
88 # used in templates to find the last member of an enum
89 if d[1] == "LAST" or d[1].endswith("_END"):
90 continue
91 # used to aid in alignment of enum values
92 if d[1].endswith("FORCE_EQUAL_SIZE"):
93 continue
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:
107 for t in tmp1list:
108 f.write( t[1] + "\n" )
109 f.write( " " + t[0] + "\n" )