lok: avoid ILibreOfficeKitNotifier null ptr de-reference on shutdown.
[LibreOffice.git] / bin / find-unused-defines.py
blobad96c0c24118deda1e79add54cabd64a9c45ad15
1 #!/usr/bin/python
3 # Search for unused constants in header files.
5 # Note that sometimes these constants are calculated, so some careful checking of the output is necessary.
7 # Takes about 4 hours to run this on a fast machine with an SSD
10 import subprocess
11 import sys
13 exclusionSet = set([
14 # List of RID constants where we compute a value using a base before calling one of the RESSTR methods
15 # Found with: git grep -P 'RID_\w+\s*\+' -- :/ ':!*.hrc' ':!*.src' ':!*.java' ':!*.py' ':!*.xba'
16 "RID_SVXSTR_KEY_",
17 "RID_UPDATE_BUBBLE_TEXT_",
18 "RID_UPDATE_BUBBLE_T_TEXT_",
19 "RID_SVXSTR_TBLAFMT_",
20 "RID_BMP_CONTENT_",
21 "RID_DROPMODE_",
22 "RID_BMP_LEVEL",
23 "RID_SVXSTR_BULLET_DESCRIPTION",
24 "RID_SVXSTR_SINGLENUM_DESCRIPTION",
25 "RID_SVXSTR_OUTLINENUM_DESCRIPTION",
26 "RID_SVXSTR_RULER_",
27 "RID_GALLERYSTR_THEME_",
28 "RID_SVXSTR_BULLET_DESCRIPTION",
29 "RID_SVXSTR_SINGLENUM_DESCRIPTION",
30 "RID_SVXSTR_OUTLINENUM_DESCRIPTION",
31 # doing some weird stuff in svx/source/unodraw/unoprov.cxx involving mapping of UNO api names to translated names and back again
32 "RID_SVXSTR_GRDT",
33 "RID_SVXSTR_HATCH",
34 "RID_SVXSTR_BMP",
35 "RID_SVXSTR_DASH",
36 "RID_SVXSTR_LEND",
37 "RID_SVXSTR_TRASNGR",
38 # other places doing calculations
39 "RID_SVXSTR_DEPTH",
40 "RID_SUBSETSTR_",
41 "ANALYSIS_",
42 "FLD_DOCINFO_CHANGE",
43 "FLD_EU_",
44 "FLD_INPUT_",
45 "FLD_PAGEREF_",
46 "FLD_STAT_",
47 "FMT_AUTHOR_",
48 "FMT_CHAPTER_",
49 "FMT_DBFLD_",
50 "FMT_FF_",
51 "FMT_GETVAR_",
52 "FMT_MARK_",
53 "FMT_REF_",
54 "FMT_SETVAR_",
55 "STR_AUTH_FIELD_ADDRESS_",
56 "STR_AUTH_TYPE_",
57 "STR_AUTOFMTREDL_",
58 "STR_CONTENT_TYPE_",
59 "STR_UPDATE_ALL",
60 "STR_UPDATE_INDEX",
61 "STR_UPDATE_LINK",
62 "BMP_PLACEHOLDER_",
63 "STR_RPT_HELP_",
64 "STR_TEMPLATE_NAME",
65 "UID_BRWEVT_",
66 "HID_EVT_",
67 "HID_PROP_",
68 "STR_VOBJ_MODE_",
69 "STR_COND_",
70 "SCSTR_CONTENT_",
71 "DATE_FUNCDESC_",
72 "DATE_FUNCNAME_",
73 "DATE_DEFFUNCNAME_",
74 "PRICING_DEFFUNCNAME_",
75 "PRICING_FUNCDESC_",
76 "PRICING_FUNCNAME_",
77 "STR_ItemValCAPTION",
78 "STR_ItemValCIRC",
79 "STR_ItemValEDGE",
80 "STR_ItemValFITTOSIZE",
81 "STR_ItemValMEASURE_",
82 "STR_ItemValMEASURETEXT_",
83 "STR_ItemValTEXTANI_",
84 "STR_ItemValTEXTHADJ",
85 "STR_ItemValTEXTVADJ",
86 "RID_SVXITEMS_VERJUST",
87 "RID_SVXITEMS_ORI",
88 "RID_SVXITEMS_JUSTMETHOD",
89 "RID_SVXITEMS_HORJUST",
90 "MM_PART",
94 def in_exclusion_set( a ):
95 for f in exclusionSet:
96 if a.startswith(f):
97 return True;
98 return False;
100 # find defines, excluding the externals folder
101 a = subprocess.Popen("git grep -hP '^#define\s+\w+\s+' -- \"[!e][!x][!t]*\" | sort -u", stdout=subprocess.PIPE, shell=True)
103 with a.stdout as txt:
104 for line in txt:
105 idx1 = line.find("#define ")
106 idx2 = line.find(" ", idx1 + 9)
107 idName = line[idx1+8 : idx2].strip()
108 if idName.startswith("INCLUDED_"): continue
109 # the various _START and _END constants are normally unused outside of the .hrc and .src files, and that's fine
110 if idName.endswith("_START"): continue
111 if idName.endswith("_BEGIN"): continue
112 if idName.endswith("_END"): continue
113 if idName == "RID_SVX_FIRSTFREE": continue
114 if in_exclusion_set(idName): continue
115 # search for the constant
116 b = subprocess.Popen(["git", "grep", "-w", idName], stdout=subprocess.PIPE)
117 found_reason_to_exclude = False
118 with b.stdout as txt2:
119 cnt = 0
120 for line2 in txt2:
121 line2 = line2.strip() # otherwise the comparisons below will not work
122 # ignore if/undef magic, does not indicate an actual use (most of the time)
123 if "ifdef" in line2: continue
124 if "undef" in line2: continue
125 # ignore commented out code
126 if line2.startswith("//"): continue
127 if line2.startswith("/*"): continue
128 # check if we found one in actual code
129 if idName.startswith("SID_"):
130 if not ".hrc:" in line2 and not ".src:" in line2 and not ".sdi:" in line2: found_reason_to_exclude = True
131 else:
132 if not ".hrc:" in line2 and not ".src:" in line2: found_reason_to_exclude = True
133 if idName.startswith("RID_"):
134 # is the constant being used as an identifier by entries in .src files?
135 if ".src:" in line2 and "Identifier = " in line2: found_reason_to_exclude = True
136 # is the constant being used by the property controller extension or reportdesigner inspection,
137 # which use macros to declare constants, hiding them from a search
138 if "extensions/source/propctrlr" in line2: found_reason_to_exclude = True
139 if "reportdesign/source/ui/inspection/inspection.src" in line2: found_reason_to_exclude = True
140 if idName.startswith("HID_"):
141 # is the constant being used as an identifier by entries in .src files
142 if ".src:" in line2 and "HelpId = " in line2: found_reason_to_exclude = True
143 # is it being used as a constant in an ItemList in .src files?
144 if ".src:" in line2 and (";> ;" in line2 or "; >;" in line2): found_reason_to_exclude = True
145 # these are used in calculations in other .hrc files
146 if "sw/inc/rcid.hrc:" in line2: found_reason_to_exclude = True
147 # calculations
148 if "sw/source/uibase/inc/ribbar.hrc:" in line2 and "ST_" in idName: found_reason_to_exclude = True
149 if "sw/source/uibase/inc/ribbar.hrc:" in line2 and "STR_IMGBTN_" in idName: found_reason_to_exclude = True
150 if "sw/source/core/undo/undo.hrc:" in line2: found_reason_to_exclude = True
151 if "sw/inc/poolfmt.hrc:" in line2: found_reason_to_exclude = True
152 # used via a macro that hides them from search
153 if "dbaccess/" in line2 and idName.startswith("PROPERTY_ID_"): found_reason_to_exclude = True
154 if "reportdesign/" in line2 and idName.startswith("HID_RPT_PROP_"): found_reason_to_exclude = True
155 if "reportdesign/" in line2 and idName.startswith("RID_STR_"): found_reason_to_exclude = True
156 if "forms/" in line2 and idName.startswith("PROPERTY_"): found_reason_to_exclude = True
157 if "svx/source/tbxctrls/extrusioncontrols.hrc:" in line2 and idName.startswith("DIRECTION_"): found_reason_to_exclude = True
158 if "svx/source/tbxctrls/extrusioncontrols.hrc:" in line2 and idName.startswith("FROM_"): found_reason_to_exclude = True
159 # if we see more than a few lines then it's probably one of the BASE/START/BEGIN things
160 cnt = cnt + 1
161 if cnt > 4: found_reason_to_exclude = True
162 if not found_reason_to_exclude:
163 print(idName)
164 # otherwise the previous line of output will be incorrectly mixed into the below git output, because of buffering
165 sys.stdout.flush()
166 # search again, so we log the location and filename of stuff we want to remove
167 subprocess.call(["git", "grep", "-wn", idName])