1#!/usr/local/bin/python3.8 2 3import sys 4import re 5import io 6 7definitionToSourceLocationMap = dict() 8callDict = dict() 9 10# clang does not always use exactly the same numbers in the type-parameter vars it generates 11# so I need to substitute them to ensure we can match correctly. 12normalizeTypeParamsRegex1 = re.compile(r"type-parameter-\d+-\d+") 13normalizeTypeParamsRegex2 = re.compile(r"typename enable_if<.*") 14def normalizeTypeParams( line ): 15 line = normalizeTypeParamsRegex1.sub("type-parameter-?-?", line) 16 return normalizeTypeParamsRegex2.sub("type-parameter-?-?", line) 17 18with io.open("workdir/loplugin.countusersofdefaultparams.log", "rb", buffering=1024*1024) as txt: 19 for line in txt: 20 tokens = line.strip().split("\t") 21 if tokens[0] == "defn:": 22 access = tokens[1] 23 returnType = tokens[2] 24 nameAndParams = tokens[3] 25 sourceLocation = tokens[4] 26 funcInfo = normalizeTypeParams(returnType) + " " + normalizeTypeParams(nameAndParams) 27 definitionToSourceLocationMap[funcInfo] = sourceLocation 28 if not funcInfo in callDict: 29 callDict[funcInfo] = set() 30 elif tokens[0] == "call:": 31 returnType = tokens[1] 32 nameAndParams = tokens[2] 33 sourceLocationOfCall = tokens[3] 34 funcInfo = normalizeTypeParams(returnType) + " " + normalizeTypeParams(nameAndParams) 35 if not funcInfo in callDict: 36 callDict[funcInfo] = set() 37 callDict[funcInfo].add(sourceLocationOfCall) 38 else: 39 print( "unknown line: " + line) 40 41tmp1list = list() 42for k,v in callDict.iteritems(): 43 if len(v) >= 1: 44 continue 45 # created by macros 46 if k.endswith("::RegisterInterface(class SfxModule *)"): 47 continue 48 if k.endswith("::RegisterChildWindow(_Bool,class SfxModule *,enum SfxChildWindowFlags)"): 49 continue 50 if k.endswith("::RegisterControl(unsigned short,class SfxModule *)"): 51 continue 52 if k.endswith("::RegisterFactory(unsigned short)"): 53 continue 54 # windows-only stuff 55 if "ShutdownIcon::OpenURL" in k: 56 continue 57 # template magic 58 if k.startswith("void VclPtr::VclPtr(const VclPtr<type-parameter-?-?> &,typename UpCast<"): 59 continue 60 if k in definitionToSourceLocationMap: 61 tmp1list.append((k, definitionToSourceLocationMap[k])) 62 63# sort the results using a "natural order" so sequences like [item1,item2,item10] sort nicely 64def natural_sort_key(s, _nsre=re.compile('([0-9]+)')): 65 return [int(text) if text.isdigit() else text.lower() 66 for text in re.split(_nsre, s)] 67# sort by both the source-line and the datatype, so the output file ordering is stable 68# when we have multiple items on the same source line 69def v_sort_key(v): 70 return natural_sort_key(v[1]) + [v[0]] 71 72# sort results by name and line number 73tmp1list.sort(key=lambda v: v_sort_key(v)) 74 75# print out the results 76with open("loplugin.countusersofdefaultparams.report", "wt") as f: 77 for t in tmp1list: 78 f.write(t[1] + "\n") 79 f.write(" " + t[0] + "\n") 80 81 82