tdf#124341: special-case applying autoformat to whole rows
[LibreOffice.git] / bin / find-unused-defines.py
blobda28459d74704e32658448061ba8e4e13ab14d58
1 #!/usr/bin/python3
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
12 import re
13 import codecs
15 exclusionSet = set([
16 # List of RID constants where we compute a value using a base before calling one of the RESSTR methods
17 # Found with: git grep -P 'RID_\w+\s*\+' -- :/ ':!*.hrc' ':!*.src' ':!*.java' ':!*.py' ':!*.xba'
18 "RID_SVXSTR_KEY_",
19 "RID_UPDATE_BUBBLE_TEXT_",
20 "RID_UPDATE_BUBBLE_T_TEXT_",
21 "RID_SVXSTR_TBLAFMT_",
22 "RID_BMP_CONTENT_",
23 "RID_DROPMODE_",
24 "RID_BMP_LEVEL",
25 "RID_SVXSTR_BULLET_DESCRIPTION",
26 "RID_SVXSTR_SINGLENUM_DESCRIPTION",
27 "RID_SVXSTR_OUTLINENUM_DESCRIPTION",
28 "RID_SVXSTR_RULER_",
29 "RID_GALLERYSTR_THEME_",
30 "RID_SVXSTR_BULLET_DESCRIPTION",
31 "RID_SVXSTR_SINGLENUM_DESCRIPTION",
32 "RID_SVXSTR_OUTLINENUM_DESCRIPTION",
33 # doing some weird stuff in svx/source/unodraw/unoprov.cxx involving mapping of UNO api names to translated names and back again
34 "RID_SVXSTR_GRDT",
35 "RID_SVXSTR_HATCH",
36 "RID_SVXSTR_BMP",
37 "RID_SVXSTR_DASH",
38 "RID_SVXSTR_LEND",
39 "RID_SVXSTR_TRASNGR",
40 # other places doing calculations
41 "RID_SVXSTR_DEPTH",
42 "RID_SUBSETSTR_",
43 "ANALYSIS_",
44 "FLD_DOCINFO_CHANGE",
45 "FLD_EU_",
46 "FLD_INPUT_",
47 "FLD_PAGEREF_",
48 "FLD_STAT_",
49 "FMT_AUTHOR_",
50 "FMT_CHAPTER_",
51 "FMT_DBFLD_",
52 "FMT_FF_",
53 "FMT_GETVAR_",
54 "FMT_MARK_",
55 "FMT_REF_",
56 "FMT_SETVAR_",
57 "STR_AUTH_FIELD_ADDRESS_",
58 "STR_AUTH_TYPE_",
59 "STR_AUTOFMTREDL_",
60 "STR_CONTENT_TYPE_",
61 "STR_UPDATE_ALL",
62 "STR_UPDATE_INDEX",
63 "STR_UPDATE_LINK",
64 "BMP_PLACEHOLDER_",
65 "STR_RPT_HELP_",
66 "STR_TEMPLATE_NAME",
67 "UID_BRWEVT_",
68 "HID_EVT_",
69 "HID_PROP_",
70 "STR_VOBJ_MODE_",
71 "STR_COND_",
72 "SCSTR_CONTENT_",
73 "DATE_FUNCDESC_",
74 "DATE_FUNCNAME_",
75 "DATE_DEFFUNCNAME_",
76 "PRICING_DEFFUNCNAME_",
77 "PRICING_FUNCDESC_",
78 "PRICING_FUNCNAME_",
79 "STR_ItemValCAPTION",
80 "STR_ItemValCIRC",
81 "STR_ItemValEDGE",
82 "STR_ItemValFITTOSIZE",
83 "STR_ItemValMEASURE_",
84 "STR_ItemValMEASURETEXT_",
85 "STR_ItemValTEXTANI_",
86 "STR_ItemValTEXTHADJ",
87 "STR_ItemValTEXTVADJ",
88 "RID_SVXITEMS_VERJUST",
89 "RID_SVXITEMS_ORI",
90 "RID_SVXITEMS_JUSTMETHOD",
91 "RID_SVXITEMS_HORJUST",
92 "MM_PART",
96 def in_exclusion_set( a ):
97 for f in exclusionSet:
98 if a.startswith(f):
99 return True
100 return False
103 # Hack to turn off unicode decoding errors, which sometimes happens in the output and I really don't
104 # care
105 def strict_handler(exception):
106 return u"", exception.end
107 codecs.register_error("strict", strict_handler)
109 # find defines, excluding the externals folder
110 a = subprocess.Popen("git grep -hP '^#define\\s+\\w\\w\\w\\w+\\s*' -- \"[!e][!x][!t]*\" | sort -u", stdout=subprocess.PIPE, shell=True, encoding='UTF-8')
112 name_re = re.compile(r"#define\s+(\w+)")
113 with a.stdout as txt:
114 for line in txt:
115 idName = name_re.match(str(line)).group(1)
116 if idName.startswith("INCLUDED_"):
117 continue
118 # the various _START and _END constants are normally unused outside of the .hrc and .src files, and that's fine
119 if idName.endswith("_START"):
120 continue
121 if idName.endswith("_BEGIN"):
122 continue
123 if idName.endswith("_END"):
124 continue
125 if idName == "RID_SVX_FIRSTFREE":
126 continue
127 if idName == "":
128 continue
129 if idName.startswith("__com"):
130 continue # these are the include/header macros for the UNO stuff
131 if in_exclusion_set(idName):
132 continue
133 # search for the constant
134 b = subprocess.Popen(["git", "grep", "-w", idName], stdout=subprocess.PIPE, encoding='UTF-8')
135 found_reason_to_exclude = False
136 with b.stdout as txt2:
137 cnt = 0
138 for line2 in txt2:
139 line2 = line2.strip() # otherwise the comparisons below will not work
140 # ignore if/undef magic, does not indicate an actual use (most of the time)
141 if "ifdef" in line2:
142 continue
143 if "undef" in line2:
144 continue
145 # ignore commented out code
146 if line2.startswith("//"):
147 continue
148 if line2.startswith("/*"):
149 continue
150 # check if we found one in actual code
151 if idName.startswith("SID_"):
152 if ".hrc:" not in line2 and ".src:" not in line2 and ".sdi:" not in line2:
153 found_reason_to_exclude = True
154 else:
155 if ".hrc:" not in line2 and ".src:" not in line2:
156 found_reason_to_exclude = True
157 if idName.startswith("RID_"):
158 # is the constant being used as an identifier by entries in .src files?
159 if ".src:" in line2 and "Identifier = " in line2:
160 found_reason_to_exclude = True
161 # is the constant being used by the property controller extension or reportdesigner inspection,
162 # which use macros to declare constants, hiding them from a search
163 if "extensions/source/propctrlr" in line2:
164 found_reason_to_exclude = True
165 if "reportdesign/source/ui/inspection/inspection.src" in line2:
166 found_reason_to_exclude = True
167 if idName.startswith("HID_"):
168 # is the constant being used as an identifier by entries in .src files
169 if ".src:" in line2 and "HelpId = " in line2:
170 found_reason_to_exclude = True
171 # is it being used as a constant in an ItemList in .src files?
172 if ".src:" in line2 and (";> ;" in line2 or "; >;" in line2):
173 found_reason_to_exclude = True
174 # these are used in calculations in other .hrc files
175 if "sw/inc/rcid.hrc:" in line2:
176 found_reason_to_exclude = True
177 # calculations
178 if "sw/source/uibase/inc/ribbar.hrc:" in line2 and "ST_" in idName:
179 found_reason_to_exclude = True
180 if "sw/source/uibase/inc/ribbar.hrc:" in line2 and "STR_IMGBTN_" in idName:
181 found_reason_to_exclude = True
182 if "sw/source/core/undo/undo.hrc:" in line2:
183 found_reason_to_exclude = True
184 if "sw/inc/poolfmt.hrc:" in line2:
185 found_reason_to_exclude = True
186 # used via a macro that hides them from search
187 if "dbaccess/" in line2 and idName.startswith("PROPERTY_ID_"):
188 found_reason_to_exclude = True
189 if "reportdesign/" in line2 and idName.startswith("HID_RPT_PROP_"):
190 found_reason_to_exclude = True
191 if "reportdesign/" in line2 and idName.startswith("RID_STR_"):
192 found_reason_to_exclude = True
193 if "forms/" in line2 and idName.startswith("PROPERTY_"):
194 found_reason_to_exclude = True
195 if "svx/source/tbxctrls/extrusioncontrols.hrc:" in line2 and idName.startswith("DIRECTION_"):
196 found_reason_to_exclude = True
197 if "svx/source/tbxctrls/extrusioncontrols.hrc:" in line2 and idName.startswith("FROM_"):
198 found_reason_to_exclude = True
199 # if we see more than a few lines then it's probably one of the BASE/START/BEGIN things
200 cnt = cnt + 1
201 if cnt > 2:
202 found_reason_to_exclude = True
203 if not found_reason_to_exclude:
204 print(idName)
205 # otherwise the previous line of output will be incorrectly mixed into the below git output, because of buffering
206 sys.stdout.flush()
207 # search again, so we log the location and filename of stuff we want to remove
208 subprocess.call(["git", "grep", "-wn", idName])