@@ -42,14 +42,46 @@ class TT(Enum):
42
42
Token = namedtuple ("Token" , "kind code" )
43
43
44
44
45
- def report_unexpected (s , pos ):
46
- lines = (s [:pos ] + "X" ).split ("\n " )
47
- lineno , col = (len (lines ), len (lines [- 1 ]))
48
- print (
49
- "unexpected character %r in AnalyzerOptions.def at line %d column %d"
50
- % (s [pos ], lineno , col ),
51
- file = sys .stderr ,
52
- )
45
+ class ErrorHandler :
46
+ def __init__ (self ):
47
+ self .seen_errors = False
48
+
49
+ # This script uses some heuristical tweaks to modify the documentation
50
+ # of some analyzer options. As this code is fragile, we record the use
51
+ # of these tweaks and report them if they become obsolete:
52
+ self .unused_tweaks = [
53
+ "ctu-max-nodes-*" ,
54
+ "accepted values" ,
55
+ "example file content" ,
56
+ ]
57
+
58
+ def record_use_of_tweak (self , tweak_name ):
59
+ try :
60
+ self .unused_tweaks .remove (tweak_name )
61
+ except ValueError :
62
+ pass
63
+
64
+ def report_error (self , msg ):
65
+ print ("Error:" , msg , file = sys .stderr )
66
+ self .seen_errors = True
67
+
68
+ def report_unexpected_char (self , s , pos ):
69
+ lines = (s [:pos ] + "X" ).split ("\n " )
70
+ lineno , col = (len (lines ), len (lines [- 1 ]))
71
+ self .report_error (
72
+ "unexpected character %r in AnalyzerOptions.def at line %d column %d"
73
+ % (s [pos ], lineno , col ),
74
+ )
75
+
76
+ def report_unused_tweaks (self ):
77
+ if not self .unused_tweaks :
78
+ return
79
+ _is = " is" if len (self .unused_tweaks ) == 1 else "s are"
80
+ names = ", " .join (self .unused_tweaks )
81
+ self .report_error (f"textual tweak{ _is } unused in script: { names } " )
82
+
83
+
84
+ err_handler = ErrorHandler ()
53
85
54
86
55
87
def tokenize (s ):
@@ -63,7 +95,7 @@ def tokenize(s):
63
95
pos = m .end ()
64
96
break
65
97
else :
66
- report_unexpected (s , pos )
98
+ err_handler . report_unexpected_char (s , pos )
67
99
pos += 1
68
100
return result
69
101
@@ -149,10 +181,12 @@ def cmdflag_to_rst_title(cmdflag_tok):
149
181
150
182
151
183
def desc_to_rst_paragraphs (tok ):
152
- desc = string_value (tok )
184
+ base_desc = string_value (tok )
153
185
154
186
# Escape a star that would act as inline emphasis within RST.
155
- desc = desc .replace ("ctu-max-nodes-*" , r"ctu-max-nodes-\*" )
187
+ desc = base_desc .replace ("ctu-max-nodes-*" , r"ctu-max-nodes-\*" )
188
+ if desc != base_desc :
189
+ err_handler .record_use_of_tweak ("ctu-max-nodes-*" )
156
190
157
191
# Many descriptions end with "Value: <list of accepted values>", which is
158
192
# OK for a terse command line printout, but should be prettified for web
@@ -162,8 +196,10 @@ def desc_to_rst_paragraphs(tok):
162
196
paragraphs = [desc ]
163
197
extra = ""
164
198
if m := re .search (r"(^|\s)Value:" , desc ):
199
+ err_handler .record_use_of_tweak ("accepted values" )
165
200
paragraphs = [desc [: m .start ()], "Accepted values:" + desc [m .end () :]]
166
201
elif m := re .search (r"\s*Example file.content:" , desc ):
202
+ err_handler .record_use_of_tweak ("example file content" )
167
203
paragraphs = [desc [: m .start ()]]
168
204
extra = "Example file content::\n \n " + desc [m .end () :] + "\n \n "
169
205
@@ -209,7 +245,7 @@ def macro_call_to_rst_paragraphs(macro_call):
209
245
+ defaults_to_rst_paragraph (defaults )
210
246
)
211
247
except ValueError as ve :
212
- print (ve .args [0 ], file = sys . stderr )
248
+ err_handler . report_error (ve .args [0 ])
213
249
return ""
214
250
215
251
@@ -227,8 +263,11 @@ def get_option_list(input_file):
227
263
228
264
p = argparse .ArgumentParser ()
229
265
p .add_argument ("--options-def" , help = "path to AnalyzerOptions.def" )
230
- p .add_argument ("--template" , help = "path of template file" )
231
- p .add_argument ("--out" , help = "path of output file" )
266
+ p .add_argument ("--template" , help = "template file" )
267
+ p .add_argument ("--out" , help = "output file" )
268
+ p .add_argument (
269
+ "--validate" , action = "store_true" , help = "exit with failure on parsing error"
270
+ )
232
271
opts = p .parse_args ()
233
272
234
273
with open (opts .template , encoding = "utf-8" ) as f :
@@ -238,5 +277,10 @@ def get_option_list(input_file):
238
277
239
278
rst_output = doc_template .replace (PLACEHOLDER , get_option_list (opts .options_def ))
240
279
280
+ err_handler .report_unused_tweaks ()
281
+
241
282
with open (opts .out , "w" , newline = "" , encoding = "utf-8" ) as f :
242
283
f .write (rst_output )
284
+
285
+ if opts .validate and err_handler .seen_errors :
286
+ sys .exit (1 )
0 commit comments